/* global React */
const { useState } = React;

/* Part 1.5 (2026-04-23): independent collapse + sessionStorage + parent active highlight.
   §4.5 (sidebar 최종 설계) · §12.1 (Semantic Token 준수) 반영.
   hotfix17 TASK 2: rail-mode 토글 (240 ↔ 64).
   hotfix17.6 TASK 3: localStorage 영속화 제거 — viewport < 1280 자동 rail + 세션 단위 토글만. */
const SB_COLLAPSE_KEY = 'c200-admin.sidebar-sections';
/* hotfix17.6: 영속화 키 더이상 사용 안 함. 회귀 시 invariant 16 catch. */

function readSidebarState() {
  try {
    const raw = sessionStorage.getItem(SB_COLLAPSE_KEY);
    if (!raw) return {};
    return JSON.parse(raw);
  } catch (_) { return {}; }
}
function writeSidebarState(state) {
  try { sessionStorage.setItem(SB_COLLAPSE_KEY, JSON.stringify(state)); } catch (_) {}
}

function Sidebar({ current, onNavigate, mobileOpen, onMobileClose }) {
  /* hotfix17.6 TASK 3 + hotfix17.12: 세션 단위 토글.
     초기값 우선순위: sessionStorage > viewport-기반 (< 1280 → rail).
     sessionStorage = 같은 탭 내 navigation 시 상태 유지, 새 탭은 viewport 기반 재계산.
     localStorage 미사용 — 디바이스 공유 케이스에서 이전 사용자 의도 안 따라옴. */
  const SB_RAIL_SS_KEY = 'c200.sidebar.rail';
  const [isRail, setIsRail] = useState(() => {
    if (typeof window === 'undefined') return false;
    try {
      const saved = sessionStorage.getItem(SB_RAIL_SS_KEY);
      if (saved === 'true') return true;
      if (saved === 'false') return false;
    } catch (_) {}
    return window.innerWidth < 1280;
  });
  const toggleRail = () => setIsRail(v => {
    const next = !v;
    try { sessionStorage.setItem(SB_RAIL_SS_KEY, String(next)); } catch (_) {}
    return next;
  });

  /* hotfix17.7 TASK 1: 메인 사이드바 rail 상태를 body[data-sidebar-rail] 로 publish.
     Settings sub-nav 가 viewport 가 아닌 메인 상태에 동기화해 따라옴 (CSS attribute selector). */
  React.useEffect(() => {
    if (typeof document === 'undefined') return;
    document.body.dataset.sidebarRail = isRail ? 'true' : 'false';
    return () => { delete document.body.dataset.sidebarRail; };
  }, [isRail]);
  /* C-5a-fix2: 각 메뉴에 href 부여 → 실제 페이지 이동.
     Part 1.5:
      - "수강생 정보" → "수강생 목록" (§5.1)
      - 신규생 / 퇴원생 별도 페이지로 승격 (§5.2, §5.3)
      - "수강권 현황" 서브메뉴 제거 (§5.4)
      - "환불 관리" / "매출 리포트" / "급여" 예정 처리 (§7)
     children 은 { label, href, phase2 } 객체. phase2=true → 예정 뱃지 + 클릭 시 toast */

  /* hotfix12 TASK 3: 설정 메뉴는 원장(role_id=1, is_master) 전용. 마스터 잠금 권한.
   *  부원장·선생님·조교에게도 노출 안 됨 — 권한 UI 에서도 편집 불가능한 상수. */
  const cu = (window.RoleSim && window.RoleSim.getCurrentUser && window.RoleSim.getCurrentUser()) || null;
  const userRoleId = cu ? ((window.mockUsers || {})['u_' + cu.id]?.role_id) : null;
  const isOwner = userRoleId === 1;

  /* hotfix17.2 / Roadmap 7.5 Part F.1: usePermissions hook 으로 권한 기반 메뉴 분기.
   *  ITEM_PERMS 매핑된 메뉴는 hasPerm(permission_key) === true 시만 노출.
   *  로딩 중엔 낙관적 표시 (loaded 후 권한 없으면 hide).
   *  settings 는 isOwner 분기 그대로 유지 (master_only access_branch_settings 등가). */
  const userId = cu ? 'u_' + cu.id : null;
  const _permsHook = (typeof window.usePermissions === 'function')
    ? window.usePermissions(userId)
    : { has: function () { return false; }, loading: true };
  const hasPerm = _permsHook.has;
  const permsLoading = _permsHook.loading;
  const ITEM_PERMS = {
    finance: 'view_all_payments',
    payroll: 'view_payroll',
  };

  /* hotfix12 TASK 9: 학원명 동적 반영 (brandingMock 있을 때만) */
  const [brandTick, setBrandTick] = useState(0);
  React.useEffect(() => {
    const onChg = () => setBrandTick(t => t + 1);
    window.addEventListener('c200-branding-change', onChg);
    window.addEventListener('storage', (e) => { if (e && e.key === 'c200-admin.branding') onChg(); });
    return () => window.removeEventListener('c200-branding-change', onChg);
  }, []);
  const brandName = (typeof window.getBranding === 'function')
    ? (window.getBranding().academyName || '챌린지200')
    : '챌린지200';

  /* hotfix17.5 TASK 3: 운영 환경에서 "예정" 뱃지 + disabled 메뉴 숨김.
     dev 활성화: localStorage.setItem('c200.dev.showPhaseBadges', 'true') 후 새로고침. */
  const showPhaseBadges = (window.c200DevFlags && window.c200DevFlags.showPhaseBadges) || false;

  /* hotfix17.8 TASK 2: rail 모드 short label (3~4자) — section 시각 anchor 유지. */
  const sections = [
    { group: '운영', shortLabel: '운영', items: [
      { id: 'home', label: '홈', icon: 'layout-dashboard', href: 'Home.html' },
      // Phase 4 HQ 확장 분기점:
      // HQ 뷰에서는 "지점별 게시판" 목록 뷰 (지점 선택 → 해당 지점 board) 추가 고려.
      { id: 'board', label: '게시판', icon: 'clipboard-list', href: 'Board.html',
        children: [
          { label: '본사 공지',   href: 'Board.html?tab=notice' },
          { label: '지점 게시판', href: 'Board.html?tab=free' },
          { label: '자료실',      href: 'Board.html?tab=resources' },
        ] },
    ]},
    { group: '학생·수업', shortLabel: '학생', items: [
      /* Part 1.5: IA 옵션 B — 수강생 목록/신규생/퇴원생 별도 뷰 + 수강권 현황 제거 */
      { id: 'students', label: '수강생 관리', icon: 'users', href: 'Students.html',
        children: [
          { label: '수강생 목록',  href: 'Students.html' },
          { label: '신규생',       href: 'Students-new.html' },
          { label: '퇴원생',       href: 'Students-withdrawn.html' },
        ] },
      { id: 'qna', label: '문의 관리', icon: 'message-circle-question', href: 'admin-qna.html' },
      { id: 'pass', label: '수강권', icon: 'ticket', href: 'Courses.html' },
      { id: 'schedule', label: '시간표', icon: 'calendar-clock', href: 'Timetable.html' },
    ]},
    { group: '재무', shortLabel: '재무', items: [
      { id: 'finance', label: '결제·환불', icon: 'credit-card', href: 'PaymentsRefunds.html',
        children: [
          { label: '결제 현황',   href: 'PaymentsRefunds.html' },
          /* Part 1.5 §7: 환불 관리 / 매출 리포트 예정 */
          { label: '환불 관리',   phase2: true },
          { label: '매출 리포트', phase2: true },
        ] },
      /* Part 1.5 §7: 급여 예정 */
      { id: 'payroll', label: '급여', icon: 'wallet', disabled: true },
    ]},
    /* hotfix12 TASK 3: 설정 섹션 — 원장(role_id=1)만 */
    ...(isOwner ? [{ group: '운영 설정', shortLabel: '설정', items: [
      { id: 'settings', label: '설정', icon: 'settings', href: 'Settings.html' },
    ]}] : []),
    /* hotfix17.5 TASK 3: 추후 확장 섹션 — 운영 환경 숨김 (dev flag 활성 시만 노출) */
    ...(showPhaseBadges ? [{ group: '추후 확장', shortLabel: '확장', muted: true, items: [
      { id: 'learning', label: '학습 관리', icon: 'book-open', disabled: true },
      { id: 'sms', label: '문자 관리', icon: 'message-square', disabled: true },
      { id: 'goods', label: '교재·물품 관리', icon: 'package', disabled: true },
      { id: 'stats', label: '통계', icon: 'bar-chart-3', disabled: true },
    ]}] : []),
  ]
  /* hotfix17.5 TASK 3: 각 섹션 안에서도 disabled / phase2 children 숨김 (flag 미활성 시).
     hotfix17.2: ITEM_PERMS 매핑된 메뉴는 권한 체크 — 로딩 중 낙관적 표시. */
  .map(sec => {
    let items = sec.items;
    if (!showPhaseBadges) items = items.filter(it => !it.disabled);
    items = items.filter(it => {
      const req = ITEM_PERMS[it.id];
      if (!req) return true;
      if (permsLoading) return true;
      return hasPerm(req);
    });
    if (!showPhaseBadges) {
      items = items.map(it => {
        if (!it.children) return it;
        return Object.assign({}, it, { children: it.children.filter(c => !(typeof c === 'object' && c.phase2)) });
      });
    }
    return Object.assign({}, sec, { items: items });
  })
  .filter(sec => sec.items.length > 0);

  const childLabel = (c) => typeof c === 'string' ? c : c.label;

  /* Part 1.5 §1: sessionStorage 기반 independent collapse.
     + 현재 경로의 부모 섹션은 진입 시 강제 펼침. */
  const currentParentId = (() => {
    if (!current) return null;
    const colon = current.indexOf(':');
    const baseId = colon >= 0 ? current.slice(0, colon) : current;
    /* find which parent has this id as itself or as child */
    for (const sec of sections) {
      for (const it of sec.items) {
        if (it.id === baseId && it.children) return it.id;
      }
    }
    return null;
  })();

  const [expandedMenus, setExpandedMenus] = useState(() => {
    const saved = readSidebarState();
    const initial = new Set();
    sections.forEach(sec => sec.items.forEach(it => {
      if (it.children && saved[it.id] === true) initial.add(it.id);
    }));
    /* 현재 경로 부모는 저장값과 무관하게 강제 펼침 */
    if (currentParentId) initial.add(currentParentId);
    return initial;
  });
  const isExpanded = (id) => expandedMenus.has(id);
  const toggleParent = (id) => {
    setExpandedMenus(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      /* persist */
      const snapshot = {};
      sections.forEach(sec => sec.items.forEach(it => {
        if (it.children) snapshot[it.id] = next.has(it.id);
      }));
      writeSidebarState(snapshot);
      return next;
    });
  };

  /* 부모가 "서브 active 를 하나라도 포함" 여부. Part 1.5 §2 배경 강조 판단용. */
  const parentHasActiveSub = (it) => {
    if (!it.children) return false;
    const colon = current?.indexOf(':') ?? -1;
    if (colon < 0) return false;
    const baseId = current.slice(0, colon);
    return baseId === it.id;
  };

  /* hotfix17.13: rail 모드 tooltip — 기존 ::after 가 .sb-scroll overflow-y: auto 의 자동
     overflow-x clip 에 의해 사이드바 우측으로 못 나가서 잘못된 위치 (메뉴 라벨 길이만큼만 좁게)
     에 표시되는 버그. ReactDOM.createPortal 로 body 직계 자식으로 띄워 사이드바 클립 영향 회피.
     같은 sb-toggle-btn 도 일관된 처리 (이미 sb-foot 영역이라 안 잘렸지만 동일 패턴 유지). */
  const [tooltip, setTooltip] = useState(null);
  const showTooltip = (e, label) => {
    if (!isRail) return;
    const rect = e.currentTarget.getBoundingClientRect();
    setTooltip({ top: rect.top + rect.height / 2, left: rect.right + 8, label });
  };
  const hideTooltip = () => setTooltip(null);

  /* hotfix17.12: 같은 페이지로 navigate 시 reload 깜박임 방지. */
  const _navigateSafe = (href) => {
    if (!href) return;
    try {
      const cur = window.location.pathname.split('/').pop();
      const tgt = href.split('?')[0].split('#')[0];
      if (cur === tgt) {
        /* 같은 페이지 — query/hash 만 다른 경우만 변경, 전체 reload 회피 */
        const curSearch = window.location.search;
        const newSearch = href.indexOf('?') >= 0 ? '?' + href.split('?')[1].split('#')[0] : '';
        if (curSearch !== newSearch && newSearch) {
          window.history.replaceState(null, '', href);
          window.dispatchEvent(new PopStateEvent('popstate'));
        }
        return;  /* 같은 페이지 same query → no-op (reload 방지) */
      }
    } catch (_) {}
    window.location.href = href;
  };

  const handleClick = (it) => {
    if (it.disabled) return;
    if (it.children) {
      /* hotfix17.11: rail 모드에선 펼쳐도 자식 메뉴 안 보이므로 첫 번째 active child href 로 직접 이동.
         예: 게시판 ▶ 본사 공지 / 수강생 관리 ▶ 수강생 목록 / 결제·환불 ▶ 결제 현황. */
      if (isRail) {
        const firstChild = it.children.find(c => typeof c === 'object' && c.href && !c.phase2);
        if (firstChild && firstChild.href) {
          _navigateSafe(firstChild.href);
          return;
        }
        /* fallback: 부모 자체 href 가 있으면 그것 */
        if (it.href) { _navigateSafe(it.href); return; }
      }
      /* C-5a-fix3 (expand 모드): 부모 메뉴 = 펼침 토글만. 페이지 이동은 자식 클릭으로만. */
      toggleParent(it.id);
      return;
    }
    if (it.href) {
      _navigateSafe(it.href);
      return;
    }
    onNavigate(it.id);
    onMobileClose && onMobileClose();
  };

  const handleSubClick = (it, c) => {
    onMobileClose && onMobileClose();
    /* Part 1.5 §7: phase2 서브 → toast 로 안내 */
    if (typeof c === 'object' && c.phase2) {
      if (window.showToast) window.showToast('Phase 2-A 에서 구현 예정');
      return;
    }
    if (typeof c === 'object' && c.href) {
      window.location.href = c.href;
      return;
    }
    onNavigate(`${it.id}:${childLabel(c)}`);
  };

  /* C-4b: 문의 대기 3일 이상 카운트 */
  const qnaBadge = (() => {
    try {
      if (!Array.isArray(window.QNA_ADMIN_MOCK)) return 0;
      return window.QNA_ADMIN_MOCK.filter(t => {
        if (t.status !== 'pending') return false;
        const [d] = t.createdAt.split(' ');
        const [y, mo, da] = d.split('-').map(Number);
        const days = Math.floor((Date.now() - new Date(y, mo - 1, da).getTime()) / 86400000);
        return days >= 3;
      }).length;
    } catch (_) { return 0; }
  })();

  return (
    <aside className={`sb ${mobileOpen ? 'is-open' : ''} ${isRail ? 'is-rail' : ''}`}>
      <div
        className="sb-brand sb-brand-link"
        role="link"
        tabIndex={0}
        onClick={() => { window.location.href = 'Home.html'; }}
        onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); window.location.href = 'Home.html'; } }}
        title="홈으로"
      >
        <div className="sb-mark">
          <img src="../assets/logo3-full.png" alt="Challenge200" />
        </div>
        <div className="sb-brand-text">
          <div className="sb-brand-name">{brandName}</div>
          <div className="sb-brand-sub">CRM · 지점</div>
        </div>
      </div>

      <div className="sb-scroll">
        {/* Part 1.5 §3: "메뉴" 라벨 제거. 섹션 라벨만으로 충분. */}
        {sections.map((sec, i) => (
          <div key={i} className="sb-section">
            {/* hotfix17.8 TASK 2: rail 모드 short label / expand 모드 full label.
                CSS 가 .sb-section-label 의 long/short 자식을 토글. */}
            <div className="sb-section-label" style={sec.muted ? {opacity: 0.7} : null}>
              <span className="sb-section-label-long">{sec.group}</span>
              <span className="sb-section-label-short">{sec.shortLabel || sec.group}</span>
            </div>
            {sec.items.map((it) => {
              const isOpen = isExpanded(it.id);
              /* C-5a-fix3: 부모(children 있음)는 좌측 3px 인디케이터 없음. children 없는 메뉴만 자체 active */
              const isActive = !it.children && (current === it.id);
              /* Part 1.5 §2: 부모에 서브 active 있으면 배경 강조 (인디케이터 없음, 서브에만 유지) */
              const hasActiveChild = parentHasActiveSub(it);
              return (
                <div key={it.id}>
                  <button
                    className={`sb-item ${isActive ? 'is-active' : ''} ${hasActiveChild ? 'has-active-child' : ''}`}
                    data-label={it.label}
                    title={isRail ? it.label : null}
                    onClick={() => { hideTooltip(); handleClick(it); }}
                    onMouseEnter={(e) => showTooltip(e, it.label)}
                    onMouseLeave={hideTooltip}
                    disabled={it.disabled}
                    style={it.disabled ? { opacity: 0.4, cursor: 'not-allowed' } : null}
                  >
                    <i data-lucide={it.icon} className="sb-ic"></i>
                    <span>{it.label}</span>
                    {it.id === 'qna' && qnaBadge > 0 && <span className="sb-counter-dot">{qnaBadge}</span>}
                    {it.children && <i data-lucide={isOpen ? 'chevron-down' : 'chevron-right'} className="sb-chev"></i>}
                    {it.disabled && <span className="sb-phase-badge">예정</span>}
                  </button>
                  {it.children && isOpen && (
                    <div className="sb-sub">
                      {it.children.map((c, idx) => {
                        const lbl = childLabel(c);
                        const isSubActive = current === `${it.id}:${lbl}`;
                        const isPhase2 = typeof c === 'object' && c.phase2;
                        return (
                          <button
                            key={idx}
                            className={`sb-subitem ${isSubActive ? 'is-active' : ''} ${isPhase2 ? 'is-phase2' : ''}`}
                            onClick={() => handleSubClick(it, c)}
                          >
                            <span>{lbl}</span>
                            {isPhase2 && <span className="sb-phase-badge">예정</span>}
                          </button>
                        );
                      })}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        ))}
      </div>

      <div className="sb-foot">
        {/* hotfix17.7 TASK 3: 토글 버튼 컴팩트 — 위 divider만 유지 (아래 divider 제거).
            아이콘 차별화는 `panel-left-{open|close}` Lucide 아이콘으로 이미 적용됨. */}
        <div className="sb-toggle-divider"></div>
        <button
          type="button"
          className="sb-toggle-btn"
          data-label={isRail ? '펼치기' : '접기'}
          onClick={() => { hideTooltip(); toggleRail(); }}
          onMouseEnter={(e) => showTooltip(e, isRail ? '펼치기' : '접기')}
          onMouseLeave={hideTooltip}
          title={isRail ? '사이드바 펼치기' : '사이드바 접기'}
          aria-label={isRail ? '사이드바 펼치기' : '사이드바 접기'}
          aria-pressed={isRail}
        >
          {/* hotfix17.9 TASK 1+4: .sb-ic 클래스 추가 — Lucide replace 후 SVG 에 className 보존되어 16×16 적용. */}
          <i className="sb-ic" data-lucide={isRail ? 'panel-left-open' : 'panel-left-close'}></i>
          <span>{isRail ? '펼치기' : '접기'}</span>
        </button>
        <div className="sb-branch sb-branch-static" aria-label="현재 지점 (고정)">
          <div className="sb-branch-ic">광주</div>
          <div className="sb-branch-label">
            <div className="sb-branch-name">광주봉선지점</div>
            <div className="sb-branch-sub">지점 ID · KJ-BS</div>
          </div>
        </div>
        <button
          className="sb-logout"
          onMouseEnter={(e) => showTooltip(e, '로그아웃')}
          onMouseLeave={hideTooltip}
        >
          {/* hotfix17.9 TASK 4: .sb-ic 클래스 추가 — Lucide SVG 에 16×16 적용 */}
          <i className="sb-ic" data-lucide="log-out"></i>
          <span>로그아웃</span>
        </button>
      </div>
      {/* hotfix17.13: rail 모드 tooltip portal — body 직계 자식으로 띄워 사이드바 클립 영향 회피 */}
      {isRail && tooltip && ReactDOM.createPortal(
        <div className="sb-tooltip" style={{ top: tooltip.top, left: tooltip.left }}>
          {tooltip.label}
        </div>,
        document.body
      )}
    </aside>
  );
}
window.Sidebar = Sidebar;
