"use client";

import { useEffect, useState, type ReactNode } from "react";
import { readOpen, writeOpen } from "../lib/collapsible";

// 사이드바 패널의 공용 collapsible 래퍼.
//   - 헤더 row 가 button 으로 동작 → 클릭 시 본문 토글, aria-expanded 로 보조기술 알림.
//   - 사용자 선택은 localStorage 에 panel-open:<storageKey> 로 영속.
//   - 본문은 `hidden` 으로 숨겨 unmount 시키지 않음 → InvestmentNote 입력 텍스트,
//     AlertsPanel 폼 partial 입력, RelatedStocks fetch 결과 등이 토글 사이클 동안
//     보존. (조건부 렌더로 children 을 끄면 re-mount → 데이터 재요청/입력 손실.)
//
// SSR 안전:
//   초기 state 를 readOpen() 으로 lazy 초기화하면 서버는 window 가 없어 defaultOpen 을
//   반환하고, 클라이언트 hydration 첫 렌더에서 localStorage 값과 다르면 React 가
//   hydration mismatch 를 경고함. useState(defaultOpen) → useEffect 에서 sync 패턴으로
//   해결 — 1프레임 미세 jank 는 감수 (localStorage 값이 default 와 다를 때만, 사이드바
//   패널이라 시선 끄는 위치도 아님).

type Props = {
  title: ReactNode;
  subtitle?: ReactNode;
  storageKey: string;
  defaultOpen?: boolean;
  children: ReactNode;
  className?: string;
};

export function Collapsible({
  title,
  subtitle,
  storageKey,
  defaultOpen = true,
  children,
  className = "rounded-md border border-zinc-800 bg-zinc-900/40",
}: Props) {
  const [open, setOpen] = useState(defaultOpen);

  useEffect(() => {
    setOpen(readOpen(storageKey, defaultOpen));
  }, [storageKey, defaultOpen]);

  const toggle = () => {
    setOpen((cur) => {
      const next = !cur;
      writeOpen(storageKey, next);
      return next;
    });
  };

  return (
    <div className={className}>
      <button
        type="button"
        onClick={toggle}
        aria-expanded={open}
        className="flex w-full items-baseline justify-between gap-2 px-4 py-3 text-left transition hover:bg-zinc-900/60"
      >
        <span className="flex min-w-0 items-center gap-2 text-sm font-medium text-zinc-200">
          <span
            className={`inline-block text-[10px] text-zinc-500 transition-transform ${
              open ? "rotate-90" : ""
            }`}
            aria-hidden
          >
            ▶
          </span>
          {title}
        </span>
        {subtitle != null && (
          // min-w-0 + truncate: subtitle 이 길어지면(예: PriceTargets 의 "목표 1,234,567 ·
          // 손절 987,654") 사이드바 폭을 넘기는 대신 말줄임표로 끝나도록. shrink-0 였을 땐
          // title 을 밀어내며 헤더가 두 줄로 깨질 수 있었음. title 쪽도 min-w-0 을 줘 flex
          // shrink 계산이 올바르게 되도록.
          <span className="min-w-0 truncate text-[10px] text-zinc-500">
            {subtitle}
          </span>
        )}
      </button>
      <div className={open ? "border-t border-zinc-800 px-4 pb-4 pt-3" : "hidden"}>
        {children}
      </div>
    </div>
  );
}
