/* global React, Icon, UI, LessonHighData */
(function () {
const { useState, useEffect, useMemo, useRef } = React;

// ============================================================
// ProfileMenuItem (dropdown row)
// ============================================================
function ProfileMenuItem({ icon, label, hint, onClick, danger }) {
  return (
    <button onClick={onClick} style={{
      appearance: 'none', display: 'flex', alignItems: 'center', gap: 10,
      width: '100%', background: 'transparent', border: 'none',
      padding: '8px 10px', borderRadius: 'var(--radius-md)',
      cursor: 'pointer', textAlign: 'left', fontFamily: 'inherit',
      color: danger ? 'var(--status-danger)' : 'var(--text-primary)',
      transition: 'background var(--duration-fast) var(--ease-out)',
    }}
    onMouseEnter={(e) => e.currentTarget.style.background = danger ? 'var(--status-danger-bg)' : 'var(--bg-subtle)'}
    onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
      <span style={{
        width: 22, height: 22, display: 'grid', placeItems: 'center',
        color: danger ? 'var(--status-danger)' : 'var(--text-secondary)',
        flexShrink: 0,
      }}>{icon}</span>
      <span style={{ display: 'flex', flexDirection: 'column', gap: 1, minWidth: 0 }}>
        <span style={{ fontSize: 13, fontWeight: 500 }}>{label}</span>
        {hint && <span style={{ fontSize: 11, color: 'var(--text-tertiary)', fontWeight: 400 }}>{hint}</span>}
      </span>
    </button>
  );
}

// ============================================================
// TopBar
// ============================================================
function TopBar({ onOpenCmdK, onOpenMobile, onOpenNotif, spaceLabel, onCycleLabel, onOpenNav }) {
  const placeholders = [
    '회원, 화면, 액션 검색…',
    '"김민지" — 회원 찾기',
    '"오늘 결제 누락" — 액션',
    '"새 예약" — 새 일정 만들기',
    '"휴원 처리" — 회원 상태 변경',
  ];
  const [phIdx, setPhIdx] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setPhIdx(i => (i + 1) % placeholders.length), 3500);
    return () => clearInterval(id);
  }, []);

  // Profile dropdown
  const [profileOpen, setProfileOpen] = useState(false);
  const profileRef = useRef(null);
  useEffect(() => {
    if (!profileOpen) return;
    const onDoc = (e) => {
      if (profileRef.current && !profileRef.current.contains(e.target)) {
        setProfileOpen(false);
      }
    };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [profileOpen]);
  const flow = window.useFlow ? window.useFlow() : null;

  return (
    <header className="app__topbar">
      <button className="topbar__menu" onClick={onOpenNav} title="메뉴">
        <Icon.Layers size={18}/>
      </button>
      <div className="topbar__brand">
        <span className="topbar__brand-mark">L</span>
        <span>LessonHigh</span>
      </div>

      <div className="topbar__academy" title="학원 전환">
        <UI.Avatar name="송" tone="tone-a" size="sm"/>
        <div className="col" style={{ gap: 0 }}>
          <small>STUDIO</small>
          <strong>송유이보컬발성클래스</strong>
        </div>
        <Icon.ChevDown size={14}/>
      </div>

      <button className="topbar__search" onClick={onOpenCmdK} title="명령 팔레트 (⌘K)">
        <Icon.Search size={14}/>
        <span className="topbar__search-ph" style={{ flex: 1, textAlign: 'left', position: 'relative', overflow: 'hidden', height: 18 }}>
          {placeholders.map((p, i) => (
            <span key={i} className="topbar__search-ph-item" style={{
              position: 'absolute',
              left: 0, right: 0,
              top: i === phIdx ? 0 : (i === (phIdx - 1 + placeholders.length) % placeholders.length ? -18 : 18),
              opacity: i === phIdx ? 1 : 0,
              transition: 'top var(--duration-slow) var(--ease), opacity var(--duration-slow) var(--ease)',
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
            }}>{p}</span>
          ))}
        </span>
        <UI.Kbd>⌘K</UI.Kbd>
      </button>

      <div className="topbar__actions">
        <button className="icon-btn" title={`공간 라벨: ${spaceLabel}`} onClick={onCycleLabel}>
          <Icon.Tag size={16}/>
        </button>
        <button className="icon-btn" title="알림" onClick={onOpenNotif}>
          <Icon.Bell size={16}/>
          <span className="dot"></span>
        </button>
        <div className="profile-chip" ref={profileRef} style={{ position: 'relative', cursor: 'pointer' }} onClick={() => setProfileOpen(o => !o)}>
          <UI.Avatar name="송유이" tone="tone-d" size="sm"/>
          <span style={{ fontSize: 13, fontWeight: 600 }}>송유이</span>
          <Icon.ChevDown size={12}/>

          {profileOpen && (
            <div onClick={(e) => e.stopPropagation()} style={{
              position: 'absolute', top: 'calc(100% + 6px)', right: 0,
              width: 260,
              background: 'var(--bg-surface)',
              border: '1px solid var(--border-default)',
              borderRadius: 'var(--radius-lg)',
              boxShadow: 'var(--shadow-lg)',
              padding: 6,
              zIndex: 50,
              cursor: 'default',
              animation: 'fade-in var(--duration-fast) var(--ease-out)',
            }}>
              {/* Account header */}
              <div style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '10px 10px 12px',
                borderBottom: '1px solid var(--border-default)',
                marginBottom: 6,
              }}>
                <UI.Avatar name="송유이" tone="tone-d" size="md"/>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 1, minWidth: 0 }}>
                  <span style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--text-primary)' }}>송유이</span>
                  <span style={{ fontSize: 11.5, color: 'var(--text-tertiary)', fontFamily: 'var(--font-mono)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    songyui@studio.kr
                  </span>
                </div>
              </div>

              {/* Workspace row */}
              <div style={{
                display: 'flex', alignItems: 'center', gap: 8,
                padding: '6px 10px 10px',
              }}>
                <span style={{
                  fontFamily: 'var(--font-mono)', fontSize: 9.5, fontWeight: 600,
                  letterSpacing: '0.12em', textTransform: 'uppercase',
                  color: 'var(--text-tertiary)',
                }}>WORKSPACE</span>
                <span style={{
                  fontFamily: 'var(--font-mono)', fontSize: 11,
                  color: 'var(--accent-default)', fontWeight: 600,
                  marginLeft: 'auto',
                }}>songyui.lessonhigh.com</span>
              </div>

              {/* Items */}
              <ProfileMenuItem
                icon={<Icon.Settings size={14}/>}
                label="내 계정 설정"
                hint="이름·이메일·비밀번호"
                onClick={() => setProfileOpen(false)}
              />
              {flow && (
                <ProfileMenuItem
                  icon={<Icon.Layers size={14}/>}
                  label="워크스페이스 전환"
                  hint="다른 학원으로 이동"
                  onClick={() => { setProfileOpen(false); flow.go('switcher'); }}
                />
              )}

              <div style={{ height: 1, background: 'var(--border-default)', margin: '6px 4px' }}/>

              {flow && (
                <ProfileMenuItem
                  icon={<Icon.LogOut size={14}/>}
                  label="로그아웃"
                  hint="처음 화면으로 돌아갑니다"
                  danger
                  onClick={() => { setProfileOpen(false); flow.reset(); }}
                />
              )}
            </div>
          )}
        </div>
      </div>
    </header>
  );
}

// ============================================================
// Sidebar
// ============================================================
function Sidebar({ active, onNav, spaceLabel, onClose }) {
  const activeCount = LessonHighData.members.filter(m => m.status === 'ACTIVE').length;
  const consultPendingCount = LessonHighData.consultations.filter(c => !c.joined).length;
  const groups = [
    {
      label: '오늘',
      items: [
        { id: 'dashboard',  label: '대시보드',   icon: Icon.Home,     kbd: 'G D' },
        { id: 'schedule',   label: '일정',       icon: Icon.Calendar, kbd: 'G S' },
        { id: 'attendance', label: '출결',       icon: Icon.Check,    kbd: 'G A' },
      ],
    },
    {
      label: '회원',
      items: [
        { id: 'members',       label: '회원',     icon: Icon.Users, kbd: 'G M', count: activeCount },
        { id: 'consults',      label: '상담',     icon: Icon.Chat,  kbd: 'G C', count: consultPendingCount },
        { id: 'notes',         label: '수업일지', icon: Icon.Note },
        { id: 'announcements', label: '공지',     icon: Icon.Bell,  kbd: 'G N', count: 2 },
      ],
    },
    {
      label: '운영',
      items: [
        { id: 'spaces',      label: spaceLabel,  icon: Icon.Door,  kbd: 'G R' },
        { id: 'payments',    label: '결제',       icon: Icon.Card,  kbd: 'G P', count: 2 },
        { id: 'instructors', label: '강사',       icon: Icon.User,  kbd: 'G I', count: LessonHighData.teachers.length },
        { id: 'analytics',   label: '분석',       icon: Icon.Trend, kbd: 'G L' },
      ],
    },
    {
      label: '시스템',
      items: [
        { id: 'settings', label: '설정', icon: Icon.Settings },
      ],
    },
  ];

  const item = (it) => (
    <button
      key={it.id}
      className={`side-item ${active === it.id ? 'is-active' : ''}`}
      onClick={() => { onNav(it.id); onClose && onClose(); }}
    >
      <it.icon size={16}/>
      <span>{it.label}</span>
      {it.count != null && <span className="side-item__count">{it.count}</span>}
    </button>
  );

  return (
    <nav className="app__sidebar">
      {groups.map((g, idx) => (
        <div className="side-group" key={g.label}>
          {idx > 0 && <div className="side-group__label">{g.label}</div>}
          {g.items.map(item)}
        </div>
      ))}

      <div style={{ flex: 1 }}></div>

      <div style={{ padding: '12px', borderRadius: 'var(--radius-md)', background: 'var(--bg-canvas)', border: '1px solid var(--border-default)', fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.5 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
          <UI.Kbd>⌘</UI.Kbd><UI.Kbd>K</UI.Kbd>
          <span style={{ color: 'var(--text-tertiary)', fontSize: 11 }}>를 눌러 빠르게</span>
        </div>
        <div style={{ color: 'var(--text-tertiary)', fontSize: 11 }}>회원 검색·이동·액션 한 곳에서</div>
      </div>
    </nav>
  );
}

// ============================================================
// Command Palette
// ============================================================
function CommandPalette({ open, onClose, onNav }) {
  const [q, setQ] = useState('');
  const [idx, setIdx] = useState(0);
  const inputRef = useRef(null);

  useEffect(() => {
    if (open) {
      setQ('');
      setIdx(0);
      setTimeout(() => inputRef.current?.focus(), 80);
    }
  }, [open]);

  const allItems = useMemo(() => {
    const data = LessonHighData;
    const nav = [
      { kind: 'nav', label: '대시보드로 이동',  hint: 'G D', action: () => onNav('dashboard') },
      { kind: 'nav', label: '회원 목록',         hint: 'G M', action: () => onNav('members') },
      { kind: 'nav', label: '상담',              hint: 'G C', action: () => onNav('consults') },
      { kind: 'nav', label: '일정 캘린더',       hint: 'G S', action: () => onNav('schedule') },
      { kind: 'nav', label: '출결 (오늘)',        hint: 'G A', action: () => onNav('attendance') },
      { kind: 'nav', label: '연습실 (공간 뷰)',  hint: 'G R', action: () => onNav('spaces') },
      { kind: 'nav', label: '결제 관리',         hint: 'G P', action: () => onNav('payments') },
      { kind: 'nav', label: '공지',             hint: 'G N', action: () => onNav('announcements') },
      { kind: 'nav', label: '분석 (매출·전환·LTV)', hint: 'G L', action: () => onNav('analytics') },
      { kind: 'nav', label: '강사 운영 (정산·KPI)', hint: 'G I', action: () => onNav('instructors') },
      { kind: 'nav', label: '설정',                  hint: '',    action: () => onNav('settings') },
    ];
    const actions = [
      { kind: 'action', label: '회원 등록',           hint: 'N M', action: () => onNav('members') },
      { kind: 'action', label: '상담일지 작성',       hint: 'N C', action: () => onNav('consults') },
      { kind: 'action', label: '결제 완료 처리',      hint: '',    action: () => onNav('payments') },
      { kind: 'action', label: '시간 변경 요청 검토', hint: '',    action: () => onNav('schedule') },
      { kind: 'action', label: '강사 정산서 보기',   hint: '',    action: () => onNav('instructors') },
      { kind: 'action', label: '월간 매출 리포트',   hint: '',    action: () => onNav('analytics') },
      { kind: 'action', label: '이탈 위험 회원 검토', hint: '',    action: () => onNav('dashboard') },
    ];
    const memberItems = data.members.map(m => ({
      kind: 'member',
      label: m.name,
      hint: data.getTeacher(m.teacherId)?.name + ' 담당',
      action: () => onNav({ view: 'members', memberId: m.id }),
    }));
    return [...nav, ...actions, ...memberItems];
  }, [onNav]);

  const filtered = useMemo(() => {
    if (!q.trim()) return allItems;
    const lower = q.toLowerCase();
    return allItems.filter(it => it.label.toLowerCase().includes(lower) || (it.hint || '').toLowerCase().includes(lower));
  }, [q, allItems]);

  useEffect(() => { setIdx(0); }, [q]);

  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'ArrowDown') { e.preventDefault(); setIdx(i => Math.min(filtered.length - 1, i + 1)); }
      else if (e.key === 'ArrowUp') { e.preventDefault(); setIdx(i => Math.max(0, i - 1)); }
      else if (e.key === 'Enter') {
        const it = filtered[idx];
        if (it) { it.action(); onClose(); }
      }
      else if (e.key === 'Escape') { onClose(); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, filtered, idx, onClose]);

  const groups = useMemo(() => {
    const g = { nav: [], action: [], member: [] };
    filtered.forEach(it => g[it.kind].push(it));
    return g;
  }, [filtered]);

  if (!open && !q) {/* still render to allow fade */}

  // Render with absolute indices for keyboard navigation
  let flatIdx = -1;
  const renderItem = (it) => {
    flatIdx += 1;
    const active = flatIdx === idx;
    const iconOf = it.kind === 'member' ? Icon.User : it.kind === 'action' ? Icon.Sparkle : Icon.ChevRight;
    const Ic = iconOf;
    return (
      <div
        key={it.kind + flatIdx}
        className={`cmdk__item ${active ? 'is-active' : ''}`}
        onClick={() => { it.action(); onClose(); }}
        onMouseEnter={() => setIdx(flatIdx)}
      >
        <Ic size={14} />
        <span>{it.label}</span>
        {it.hint && <small>{it.hint}</small>}
      </div>
    );
  };

  return (
    <div className={`cmdk-overlay ${open ? 'is-open' : ''}`} onClick={onClose}>
      <div className="cmdk" onClick={(e) => e.stopPropagation()}>
        <div className="cmdk__input">
          <Icon.Search size={16} />
          <input
            ref={inputRef}
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder="명령 또는 회원 이름 검색…"
          />
          <UI.Kbd>ESC</UI.Kbd>
        </div>
        <div className="cmdk__list">
          {groups.nav.length > 0 && (
            <React.Fragment>
              <div className="cmdk__group-label">이동</div>
              {groups.nav.map(renderItem)}
            </React.Fragment>
          )}
          {groups.action.length > 0 && (
            <React.Fragment>
              <div className="cmdk__group-label">액션</div>
              {groups.action.map(renderItem)}
            </React.Fragment>
          )}
          {groups.member.length > 0 && (
            <React.Fragment>
              <div className="cmdk__group-label">회원</div>
              {groups.member.map(renderItem)}
            </React.Fragment>
          )}
          {filtered.length === 0 && (
            <div style={{ padding: 24, textAlign: 'center', color: 'var(--text-tertiary)', fontSize: 13 }}>
              일치하는 항목이 없습니다.
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Notification Popover (simple inline)
// ============================================================
function NotificationPanel({ open, onClose }) {
  const data = LessonHighData;
  if (!open) return null;
  return (
    <div onClick={onClose}
      style={{
        position: 'fixed', top: 60, right: 16, width: 360, background: 'var(--bg-surface)',
        border: '1px solid var(--border-default)', borderRadius: 'var(--radius-lg)',
        boxShadow: 'var(--shadow-lg)', zIndex: 100, overflow: 'hidden',
      }}
      onClickCapture={(e) => e.stopPropagation()}
    >
      <header style={{ padding: '12px 16px', borderBottom: '1px solid var(--border-default)', display: 'flex', alignItems: 'center', gap: 8 }}>
        <span className="t-body-strong">알림</span>
        <span className="t-caption" style={{ marginLeft: 'auto' }}>최근 24시간</span>
      </header>
      <ul style={{ listStyle: 'none', margin: 0, padding: 4 }}>
        {data.notifications.map(n => (
          <li key={n.id} style={{ padding: '10px 12px', borderRadius: 'var(--radius-md)', display: 'flex', gap: 12 }}>
            <span style={{
              width: 26, height: 26, borderRadius: 99,
              background: n.kind === 'payment' ? 'var(--type-rental-bg)' : n.kind === 'change' ? 'var(--type-consultation-bg)' : 'var(--accent-subtle-bg)',
              color:      n.kind === 'payment' ? 'var(--type-rental)'    : n.kind === 'change' ? 'var(--type-consultation)'    : 'var(--accent-default)',
              display: 'grid', placeItems: 'center', flexShrink: 0,
            }}>
              {n.kind === 'payment' ? <Icon.Card size={12}/> : n.kind === 'change' ? <Icon.Refresh size={12}/> : <Icon.Chat size={12}/>}
            </span>
            <div style={{ flex: 1, fontSize: 13, lineHeight: 1.45 }}>
              <div>{n.text}</div>
              <div className="t-caption" style={{ fontSize: 11 }}>{data.fmt ? data.fmt.relative(n.at) : (n.at || n.when)}</div>
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}

window.Shell = { TopBar, Sidebar, CommandPalette, NotificationPanel };
})();
