'use client';

import Link from 'next/link';
import { FoxIconButton } from '@fox/core/components/fox-icon-button';
import { FoxInput } from '@fox/core/components/fox-input';
import {
  FoxCaretDownIcon,
  FoxCaretUpIcon,
  FoxMagnifyingGlassIcon,
  FoxSidebarSimpleIcon,
  FoxStarIcon,
} from '@fox/core/icons';
import type {
  SidebarMenu,
  SidebarMenuChild,
  SidebarMenuItem,
} from '@/lib/domain/sidebar-menu';
import { useSidebarNav, type SidebarNavState } from '../_hooks/use-sidebar-nav';
import styles from './admin-sidebar.module.scss';
import { SidebarMenuIcon } from './sidebar-menu-icon';

interface AdminSidebarProps {
  /** 서버가 계정 권한에 맞춰 구성해 준 메뉴. 이 컴포넌트는 라우트 목록을 알지 못한다. */
  menu: SidebarMenu;
}

/**
 * Basic 레이아웃 사이드바 — 시안 snb-area(3041:11860)를 옮겼다. 검색·즐겨찾기·섹션별 GNB로
 * 이루어지고, GNB는 1depth > 2depth > 3depth 중첩이다.
 *
 * **메뉴 데이터를 소유하지 않는다.** 권한마다 항목이 달라 매 요청 서버가 조회해 넘겨주며
 * (`fetchSidebarMenu`), 여기서는 받은 트리를 그리고 펼침·활성 상태만 판정한다. 그래서 새 화면이
 * 생겨도 이 파일은 손대지 않는다.
 *
 * 시안에 없어 넣지 않은 것: 검색 입력의 실제 동작(제출 대상이 정해지지 않음)과 즐겨찾기
 * 추가/해제. 별 아이콘은 시안대로 표시만 한다.
 */
export function AdminSidebar({ menu }: AdminSidebarProps) {
  const nav = useSidebarNav(menu);

  return (
    <nav className={styles.sidebar} aria-label="주요 메뉴">
      <div className={styles.top}>
        <div className={styles.search}>
          <FoxInput
            size="md"
            placeholder="검색어를 입력하세요."
            icon={<FoxMagnifyingGlassIcon />}
            aria-label="메뉴 검색"
          />
        </div>
        <FoxIconButton
          size="xsm"
          type="ghost"
          icon={<FoxSidebarSimpleIcon />}
          label="사이드바 접기"
        />
      </div>

      {menu.favorites.length > 0 && (
        <section className={`${styles.section} ${styles.sectionFavorites}`}>
          <h2 className={styles.sectionTitle}>즐겨찾기</h2>
          <ul className={styles.list}>
            {menu.favorites.map((favorite) => (
              <li key={favorite.id} className={styles.item}>
                <Link href={favorite.href} className={styles.favorite}>
                  <span className={styles.childMark}>
                    <FoxStarIcon weight="fill" />
                  </span>
                  {favorite.label}
                </Link>
              </li>
            ))}
          </ul>
        </section>
      )}

      {menu.sections.map((section) => (
        <section
          key={section.id}
          className={`${styles.section} ${styles.sectionNav}`}
        >
          <h2 className={styles.sectionTitle}>{section.label}</h2>
          <ul className={styles.list}>
            {section.items.map((item) => (
              <SidebarItem key={item.id} item={item} nav={nav} />
            ))}
          </ul>
        </section>
      ))}
    </nav>
  );
}

/** 1depth — 자식이 있으면 펼침 버튼, 없으면 링크다. */
function SidebarItem({
  item,
  nav,
}: {
  item: SidebarMenuItem;
  nav: SidebarNavState;
}) {
  const hasChildren = (item.children?.length ?? 0) > 0;
  const isActive = nav.containsActive(item);
  const isOpen = nav.isItemOpen(item);
  const rowClass = `${styles.itemButton} ${isActive ? styles.itemButtonActive : ''}`;

  const inner = (
    <>
      <span className={styles.itemIcon}>
        <SidebarMenuIcon name={item.icon} />
      </span>
      <span className={styles.itemLabel}>{item.label}</span>
    </>
  );

  return (
    <li className={styles.item}>
      {hasChildren ? (
        <button
          type="button"
          className={rowClass}
          aria-expanded={isOpen}
          onClick={() => nav.toggleItem(item.id)}
        >
          {inner}
        </button>
      ) : (
        <Link href={item.href ?? '#'} className={rowClass}>
          {inner}
        </Link>
      )}

      {hasChildren && isOpen && (
        <ul className={styles.childGroup}>
          {item.children?.map((child) => (
            <SidebarChild key={child.id} child={child} nav={nav} />
          ))}
        </ul>
      )}
    </li>
  );
}

/** 2depth — 자식이 있으면 펼침 버튼(별·캐럿 표시), 없으면 링크다. */
function SidebarChild({
  child,
  nav,
}: {
  child: SidebarMenuChild;
  nav: SidebarNavState;
}) {
  const hasChildren = (child.children?.length ?? 0) > 0;
  const isOpen = nav.isChildOpen(child);
  const isActive = nav.isActive(child.href);
  const rowClass = `${styles.childRow} ${
    isActive || (hasChildren && isOpen) ? styles.childRowActive : ''
  }`;

  // 시안은 자식이 없는 항목도 별·캐럿 자리를 비워 두고 투명하게만 만든다 — 라벨 시작
  // 위치를 줄마다 맞추기 위해서다.
  const mark = (
    <span
      className={`${styles.childMark} ${hasChildren ? '' : styles.childMarkHidden}`}
    >
      <FoxStarIcon />
    </span>
  );
  const caret = (
    <span
      className={`${styles.childMark} ${hasChildren ? '' : styles.childMarkHidden}`}
    >
      {isOpen ? <FoxCaretUpIcon /> : <FoxCaretDownIcon />}
    </span>
  );

  return (
    <li className={styles.child}>
      {hasChildren ? (
        <button
          type="button"
          className={rowClass}
          aria-expanded={isOpen}
          onClick={() => nav.toggleChild(child.id)}
        >
          {mark}
          <span className={styles.childLabel}>{child.label}</span>
          {caret}
        </button>
      ) : (
        <Link href={child.href ?? '#'} className={rowClass}>
          {mark}
          <span className={styles.childLabel}>{child.label}</span>
          {caret}
        </Link>
      )}

      {hasChildren && isOpen && (
        <ul className={styles.leafGroup}>
          {child.children?.map((leaf) => (
            <li key={leaf.id}>
              <Link
                href={leaf.href}
                className={`${styles.leaf} ${
                  nav.isActive(leaf.href) ? styles.leafActive : ''
                }`}
              >
                <span className={styles.childMark}>
                  <FoxStarIcon />
                </span>
                {leaf.label}
              </Link>
            </li>
          ))}
        </ul>
      )}
    </li>
  );
}
