import type { ReactNode } from "react";

interface SidebarGroupProps {
  label: string;
  icon?: ReactNode;
  /** 펼침 상태 — 상태 소유는 소비처(feature)다. 이 컴포넌트는 비제어 프레젠테이션이다. */
  isExpanded: boolean;
  onToggle: () => void;
  /** 자식 SidebarLink들(isNested로 들여쓰기). */
  children: ReactNode;
}

/**
 * 사이드바 그룹 헤딩 — 자식 내비게이션 항목(SidebarLink)을 펼침/접힘으로 묶는다.
 * 상태를 갖지 않는 프레젠테이션 컴포넌트로, IconButton·SidebarLink와 동일한 관례로
 * 'use client'를 붙이지 않는다: onToggle을 받아 <button onClick>에 연결하지만,
 * 이 파일 자체는 훅을 쓰지 않는 순수 함수 컴포넌트다. Next.js App Router의 클라이언트
 * 경계는 "이 모듈을 어느 파일이 import하는가"로 정해지므로, 실제 펼침 상태(useState 등)를
 * 들고 있는 소비처(feature) 파일이 'use client'면 이 컴포넌트도 그 클라이언트 모듈
 * 그래프에 포함되어 정상 동작한다(node_modules/next/dist/docs/01-app/01-getting-started/
 * 05-server-and-client-components.md "module graph" 설명 참조).
 *
 * aria-controls는 의도적으로 생략했다 — 대상 id를 안전하게 만들 방법이 마땅치 않다
 * (useId는 위 이유로 이 컴포넌트에서 쓸 수 없고, label을 id로 슬러그화하면 공백 포함
 * 라벨이나 중복 라벨에서 깨질 수 있다). WAI-ARIA APG의 Disclosure 패턴에서 aria-controls는
 * 필수가 아니라 선택 사항이며(스크린리더 지원도 일관적이지 않음), aria-expanded + 버튼
 * 바로 다음에 내용이 오는 DOM 인접 구조만으로 충분하다고 판단했다.
 */
export function SidebarGroup({ label, icon, isExpanded, onToggle, children }: SidebarGroupProps) {
  return (
    <div>
      <button
        type="button"
        onClick={onToggle}
        aria-expanded={isExpanded}
        className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-label-lg text-foreground transition-colors duration-200 hover:bg-surface-muted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
      >
        {icon}
        {/* min-w-0: SidebarLink와 동일한 truncate 대응(flex 아이템 기본 min-width:auto가
            overflow-hidden을 무력화하는 문제). 접힘 폭(md:w-16)에서도 한 줄 유지 + 말줄임만
            적용한다 — 아이콘 전용 표시로 전환하는 정식 해법은 아이콘 자산이 없어 이번
            범위에서 다루지 않는다(SidebarLink와 동일 사유). */}
        <span className="min-w-0 flex-1 truncate">{label}</span>
        <ChevronIcon
          className={`shrink-0 transition-transform duration-200 ${isExpanded ? "rotate-90" : "rotate-0"}`}
        />
      </button>
      {isExpanded && <div className="flex flex-col">{children}</div>}
    </div>
  );
}

/**
 * 펼침/접힘 표시용 셰브론(오른쪽 화살표 — 펼치면 90도 회전해 아래를 향한다). 그룹 헤딩
 * 전용 장식 요소라 components/ui/icons/에 별도 파일로 승격하지 않고 이 파일 안에 둔다.
 * moon-icon.tsx/sun-icon.tsx와 동일한 인라인 SVG 관례(stroke=currentColor로 상위 text
 * 색 토큰 상속, 장식용이라 aria-hidden).
 */
function ChevronIcon({ className }: { className?: string }) {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="2"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
      className={`size-4 ${className ?? ""}`}
    >
      <path d="M9 6l6 6-6 6" />
    </svg>
  );
}
