// app.jsx — root component, routes, layout

const { Sidebar, Topbar, Dashboard, TrackDetail, Kanban, Editor, CertPackage, Intake, Catalog, Audit, Capa, Share, Chat, Fill, AssistantPanel } = window.RAlly;

// 아직 구현되지 않은 화면을 정직하게 표시(무반응 대신 '준비 중')
const Soon = ({ title, note, go }) => (
  <div className="page" style={{ maxWidth: 720, margin: '0 auto' }}>
    <div className="card card--pad" style={{ textAlign: 'center', padding: 48 }}>
      <div style={{ fontSize: 40, marginBottom: 12 }}>🚧</div>
      <div style={{ fontSize: 20, fontWeight: 700, color: 'var(--navy)' }}>{title} · 준비 중</div>
      <div className="muted" style={{ marginTop: 8, fontSize: 13 }}>{note}</div>
      <div style={{ marginTop: 20 }}>
        <button className="btn btn--primary" onClick={() => go('dashboard')}>대시보드로 →</button>
      </div>
    </div>
  </div>
);

const SCREENS = {
  intake: {
    crumbs: ['홈', '시작하기'],
    render: (go) => <Intake go={go} />,
    fullBleed: false,
  },
  chat: {
    crumbs: ['홈', 'AI 어시스턴트'],
    render: (go) => <Chat go={go} />,
    fullBleed: false,
  },
  templates: {
    crumbs: ['홈', '템플릿'],
    render: (go) => <Catalog go={go} />,
    fullBleed: false,
  },
  risk: {
    crumbs: ['홈', '위험관리'],
    render: (go) => <Soon go={go} title="위험관리 보드" note="위험관리 문서(RMP·RMR·FMEA)를 한곳에서 보는 전용 보드입니다. 현재는 칸반의 '위험관리' 카테고리로 확인하세요." />,
    fullBleed: false,
  },
  audit: {
    crumbs: ['홈', '가상 심사'],
    render: (go) => <Audit go={go} />,
    fullBleed: false,
  },
  capa: {
    crumbs: ['홈', 'CAPA'],
    render: (go) => <Capa go={go} />,
    fullBleed: false,
  },
  share: {
    crumbs: ['홈', '외부 공유'],
    render: (go) => <Share go={go} />,
    fullBleed: false,
  },
  dashboard: {
    crumbs: ['홈', '대시보드'],
    render: (go) => <Dashboard go={go} />,
    fullBleed: false,
  },
  track: {
    crumbs: ['홈', '트랙', '하트리듬 AI v2.1'],
    render: (go) => <TrackDetail go={go} />,
    fullBleed: false,
  },
  kanban: {
    crumbs: ['홈', '트랙', '하트리듬 AI v2.1', 'STAGE 02'],
    render: (go) => <Kanban go={go} />,
    fullBleed: false,
  },
  editor: {
    crumbs: ['홈', '문서', 'R-018'],
    render: (go) => <Editor go={go} />,
    fullBleed: true,
  },
  fill: {
    crumbs: ['홈', '정보 입력'],
    render: (go) => <Fill go={go} />,
    fullBleed: false,
  },
  cert: {
    crumbs: ['홈', '트랙', '하트리듬 AI v2.1', '인증 패키지'],
    render: (go) => <CertPackage go={go} />,
    fullBleed: false,
  },
};

const SCREEN_LABELS = {
  intake:    '00 온보딩 · 시작하기',
  dashboard: '01 D-01 메인 대시보드',
  track:     '02 T-02 트랙 상세',
  kanban:    '03 T-04 STAGE 02 칸반',
  editor:    '04 DOC-03 문서 에디터',
  cert:      '05 C-01 인증 패키지',
  templates: '06 템플릿 카탈로그',
  audit:     '07 AI 가상 심사관',
  capa:      '08 CAPA · 시정예방',
  share:     '09 내보내기 · 공유',
  chat:      '10 AI 어시스턴트',
};

const App = () => {
  // 인증 게이트 — 신원의 근거는 서버 세션(GET /api/auth/me). localStorage는 첫 렌더용 캐시일 뿐.
  const [user, setUser] = React.useState(() => window.RAlly.getUser());
  const [authReady, setAuthReady] = React.useState(false);

  // Initial screen from hash, default dashboard
  const initial = (typeof location !== 'undefined' && location.hash.replace('#', '')) || 'dashboard';
  const [screen, setScreen] = React.useState(SCREENS[initial] ? initial : 'dashboard');

  // 부팅 시 세션 확인 + 401 전역 처리(어떤 API든 401이면 로그인 화면으로)
  React.useEffect(() => {
    window.RAlly.fetchMe().then((u) => { setUser(u); setAuthReady(true); });
    const onUnauth = () => setUser(null);
    window.addEventListener('rally:unauthorized', onUnauth);
    return () => window.removeEventListener('rally:unauthorized', onUnauth);
  }, []);

  const onLogin = (u) => { setUser(u); setScreen('dashboard'); try { history.replaceState(null, '', '#dashboard'); } catch (_) {} };
  const logout = () => { window.RAlly.logout().then(() => setUser(null)); };

  const go = (s) => {
    if (!SCREENS[s]) s = 'dashboard';  // 존재하지 않는 화면 방어(크래시 방지)
    if (s === screen) { window.scrollTo({ top: 0, behavior: 'instant' }); return; }
    setScreen(s);
    // pushState로 히스토리 항목을 남겨 브라우저/마우스 뒤로가기가 동작하게 함
    try { history.pushState({ screen: s }, '', '#' + s); } catch (_) {}
    window.scrollTo({ top: 0, behavior: 'instant' });
  };

  // 뒤로/앞으로(브라우저 버튼·마우스 4/5번 버튼)로 화면 이동 동기화
  React.useEffect(() => {
    const sync = () => {
      const s = location.hash.replace('#', '');
      if (SCREENS[s]) setScreen(s);
    };
    window.addEventListener('hashchange', sync);
    window.addEventListener('popstate', sync);
    return () => {
      window.removeEventListener('hashchange', sync);
      window.removeEventListener('popstate', sync);
    };
  }, []);

  // 활성 트랙명을 가져와 crumbs의 '하트리듬 AI v2.1'을 실제 트랙명으로 치환
  const [trackName, setTrackName] = React.useState('');
  React.useEffect(() => {
    if (!user) return;   // 미인증 상태에선 데이터 API를 부르지 않는다
    const loadName = (tid) => fetch('/api/track/' + tid + '/detail').then((r) => r.json())
      .then((d) => { if (d.track && d.track.name) setTrackName(d.track.name); }).catch(() => {});
    const sel = window.__RALLY_TRACK;
    if (sel) { loadName(sel); return; }
    // 선택 트랙 없으면 실제 생성 트랙(profile 보유·최신) 해석
    fetch('/api/tracks').then((r) => r.json()).then((d) => {
      const ts = d.tracks || [];
      const real = ts.filter((x) => x.profile);
      const pick = (real.length ? real : ts).slice(-1)[0];
      if (pick) { window.__RALLY_TRACK = pick.id; loadName(pick.id); }
    }).catch(() => {});
  }, [screen, user]);

  // 에디터 화면: 실제 문서번호를 가져와 크럼의 'R-018' 치환
  const [docNo, setDocNo] = React.useState('');
  React.useEffect(() => {
    if (screen !== 'editor') return;
    const did = window.__RALLY_DOC;
    if (!did) return;
    fetch('/api/doc/' + did + '/body').then((r) => r.json())
      .then((d) => { if (d.ok && d.doc_no) setDocNo(d.doc_no); }).catch(() => {});
  }, [screen]);

  // AI 어시스턴트 패널 — 모든 화면에 상주(우측). 접힘 상태는 localStorage 영속.
  const [panelOpen, setPanelOpen] = React.useState(() => window.RAlly.isPanelOpen());
  const togglePanel = (b) => { setPanelOpen(b); window.RAlly.setPanelOpen(b); };

  // 세션 확인 중(첫 렌더) — 캐시된 사용자도 없으면 잠깐 빈 화면
  if (!authReady && !user) {
    return <div style={{ minHeight: '100vh', background: 'linear-gradient(135deg, #0F2942 0%, #173856 100%)' }} />;
  }
  // 로그인 안 됐으면 로그인 화면만 표시(데모 모드 토글 포함 앱 UI는 일절 노출되지 않음)
  if (!user) {
    return <window.RAlly.Login onLogin={onLogin} />;
  }

  const cfg = SCREENS[screen];
  let crumbs = trackName ? cfg.crumbs.map((c) => c === '하트리듬 AI v2.1' ? trackName : c) : cfg.crumbs;
  if (screen === 'editor' && docNo) crumbs = crumbs.map((c) => c === 'R-018' ? docNo : c);

  return (
    <div className={'app' + (panelOpen ? ' app--ai' : ' app--ai-closed')}>
      <Sidebar screen={screen} go={go} user={user} logout={logout} />
      <div className="main" data-screen-label={SCREEN_LABELS[screen]}>
        <Topbar crumbs={crumbs} />
        {window.RAlly.isDemo() && (
          <div style={{ background: '#fbeee6', borderBottom: '1px solid #f0d9c8', color: '#9a4a1e',
            padding: '7px 20px', fontSize: 12.5, display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ fontWeight: 700 }}>● 데모 모드</span>
            예시(더미) 데이터로 화면을 채워 보여주는 중입니다. 실제 서비스 화면은 왼쪽 <b>데모 모드</b>를 꺼서 확인하세요.
          </div>
        )}
        {cfg.render(go)}
        <ScreenSwitcher screen={screen} go={go} panelOpen={panelOpen} />
      </div>
      <AssistantPanel screen={screen} go={go} open={panelOpen} onToggle={togglePanel} />
    </div>
  );
};

// Floating screen index — bottom right, lets reviewer jump between the 5 screens
const ScreenSwitcher = ({ screen, go, panelOpen }) => {
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{
      position: 'fixed', right: panelOpen ? 400 : 56, bottom: 20, zIndex: 50,
      fontFamily: 'var(--font)',
    }}>
      {open && (
        <div style={{
          background: 'var(--navy)',
          color: 'var(--on-navy)',
          border: '1px solid rgba(240,239,232,0.18)',
          borderRadius: 10,
          padding: 10,
          marginBottom: 8,
          minWidth: 240,
          boxShadow: 'var(--shadow-pop)',
        }}>
          <div style={{ fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'rgba(240,239,232,0.5)', padding: '6px 10px 8px' }}>
            P0 화면 · 클릭해서 이동
          </div>
          {Object.entries(SCREEN_LABELS).map(([k, label]) => (
            <div key={k}
              onClick={() => { go(k); setOpen(false); }}
              style={{
                padding: '8px 10px',
                fontSize: 12.5,
                color: k === screen ? '#FFE6DA' : 'rgba(240,239,232,0.78)',
                background: k === screen ? 'rgba(217,96,62,0.18)' : 'transparent',
                borderRadius: 6,
                cursor: 'pointer',
                fontWeight: k === screen ? 600 : 500,
              }}
            >{label}</div>
          ))}
        </div>
      )}
      <button
        onClick={() => setOpen((o) => !o)}
        style={{
          background: 'var(--navy)',
          color: 'var(--on-navy)',
          border: '1px solid rgba(240,239,232,0.18)',
          height: 40,
          padding: '0 16px',
          borderRadius: 999,
          fontSize: 12,
          fontWeight: 600,
          letterSpacing: '0.04em',
          display: 'flex', alignItems: 'center', gap: 8,
          boxShadow: 'var(--shadow-pop)',
          cursor: 'pointer',
          whiteSpace: 'nowrap',
        }}
      >
        <span style={{ width: 7, height: 7, borderRadius: 999, background: 'var(--coral)' }} />
        {SCREEN_LABELS[screen]}
        <span style={{ color: 'rgba(240,239,232,0.5)', marginLeft: 4 }}>{open ? '▾' : '▴'}</span>
      </button>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
