/* =============================================================================
   PRISM SOC — 메인 App (레이아웃 · 라우팅)
   -----------------------------------------------------------------------------
   문서: "N2SF 비티소프트 역할 정리(26.04.20)"
   비티소프트 역할 = N2SF 정보서비스 모델2 구간의 "지능형 보안 관제 플랫폼"
     · 통합 수집·정규화 (§3)   · 파이프라인/저장 (§4)   · RAG 지식베이스 (§5)
     · LLM 상관분석 (§6)       · xAI 설명 (§7)          · 관제 화면 (§8)

   좌측 네비의 7개 뷰는 문서 §8의 화면 구성과 1:1 대응:
     dashboard  → §8.1 메인 대시보드
     timeline   → §8.2 이벤트 타임라인/상세
     scenarios  → §8.4 위협 시나리오 뷰 (+ §6.2 분석 결과 구조, §8.4 MITRE ATT&CK)
     analytics  → §8.3 사용자·세션·데이터 중심 뷰 (+ §6.1 상관분석 5개 축)
     xai        → §7  xAI 설명 기능 (무엇이/왜/어떤 정책/무엇 확인)
     kb         → §5  정책·규정 지식베이스 (§5.2 벡터+그래프DB, §5.3 RAG+Reranker)
     pipeline   → §3/§4 수집 대상·범위 + 파이프라인 아키텍처 (§3.2 OCSF 정규화)
============================================================================= */

const NAV = [
  { k: "dashboard", l: "대시보드", icon: "dashboard", count: null },
  { k: "timeline", l: "이벤트 타임라인", icon: "timeline", count: "4.2M" },
  { k: "scenarios", l: "위협 시나리오", icon: "scenario", count: "7" },
  { k: "analytics", l: "분석 뷰", icon: "analytics", count: null },
  { k: "xai", l: "xAI 분석", icon: "xai", count: null },
  { k: "kb", l: "정책·규정 지식베이스", icon: "kb", count: null },
  { k: "pipeline", l: "수집·파이프라인", icon: "pipe", count: null },
];

const CRUMBS = {
  dashboard: ["통합 관제", "대시보드"],
  timeline: ["통합 관제", "이벤트 타임라인"],
  scenarios: ["통합 관제", "위협 시나리오"],
  analytics: ["통합 관제", "분석 뷰"],
  xai: ["통합 관제", "xAI 분석"],
  kb: ["지식베이스", "정책·규정"],
  pipeline: ["운영", "수집·파이프라인"],
};

const App = () => {
  const [route, setRoute] = useState(() => localStorage.getItem("btisoc.route") || "dashboard");
  const [scenarioId, setScenarioId] = useState(() => localStorage.getItem("btisoc.scn") || window.TWEAK_DEFAULTS.scenario);
  const [navCollapsed, setNavCollapsed] = useState(() => localStorage.getItem("btisoc.navCollapsed") === "1");
  const [tweaks, setTweaks] = useState(() => {
    try { return { ...window.TWEAK_DEFAULTS, ...(JSON.parse(localStorage.getItem("btisoc.tweaks")||"{}")) }; }
    catch { return window.TWEAK_DEFAULTS; }
  });
  const [tweaksOpen, setTweaksOpen] = useState(false);
  const [editMode, setEditMode] = useState(false);

  useEffect(() => { localStorage.setItem("btisoc.route", route); }, [route]);
  useEffect(() => { localStorage.setItem("btisoc.scn", scenarioId); }, [scenarioId]);
  useEffect(() => { localStorage.setItem("btisoc.navCollapsed", navCollapsed ? "1" : "0"); }, [navCollapsed]);
  useEffect(() => { localStorage.setItem("btisoc.tweaks", JSON.stringify(tweaks)); }, [tweaks]);
  // Tweaks의 기본 시나리오를 바꾸면 현재 선택된 시나리오도 동기화
  useEffect(() => { if (tweaks.scenario) setScenarioId(tweaks.scenario); }, [tweaks.scenario]);

  // Apply accent + density
  useEffect(() => {
    const vars = window.ACCENTS[tweaks.accent] || window.ACCENTS.blue;
    Object.entries(vars).forEach(([k,v]) => document.documentElement.style.setProperty(k, v));
    document.documentElement.setAttribute("data-density", tweaks.density);
  }, [tweaks.accent, tweaks.density]);

  // Edit mode contract
  useEffect(() => {
    const onMsg = (e) => {
      const d = e.data || {};
      if (d.type === "__activate_edit_mode") { setEditMode(true); setTweaksOpen(true); }
      if (d.type === "__deactivate_edit_mode") { setEditMode(false); setTweaksOpen(false); }
    };
    window.addEventListener("message", onMsg);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const setTweaksAndPersist = (t) => {
    setTweaks(t);
    window.parent.postMessage({ type: "__edit_mode_set_keys", edits: t }, "*");
  };

  const openScenario = (id) => {
    setScenarioId(id);
    setRoute("scenarios");
  };

  return (
    <div className="app-shell" data-screen-label={`${NAV.find(n=>n.k===route)?.l}`} data-nav-collapsed={navCollapsed}>
      <div className="brand">
        <div className="brand-mark">PR</div>
        <div className="brand-text">
          <b>PRISM SOC</b>
          <span>Security Ops</span>
        </div>
        <button className="nav-toggle" onClick={()=>setNavCollapsed(v=>!v)} title={navCollapsed ? "사이드바 펼치기" : "사이드바 접기"}>
          <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
            {navCollapsed
              ? <path d="M6 4l4 4-4 4"/>
              : <path d="M10 4l-4 4 4 4"/>}
          </svg>
        </button>
      </div>

      <div className="topbar">
        <div className="crumbs">
          {CRUMBS[route]?.map((c,i,arr) => (
            <React.Fragment key={i}>
              {i===arr.length-1 ? <b>{c}</b> : c}
              {i<arr.length-1 && <span className="crumb-sep">/</span>}
            </React.Fragment>
          ))}
        </div>
        <div className="topbar-spacer"/>
        <button className="cmdk-btn" title="검색 (⌘K)">
          <Icon name="search" size={13}/>
          <span>검색</span>
          <kbd>⌘K</kbd>
        </button>
        <div className="status-group">
          <span className="live"><span className="dot"/>실시간 수집</span>
          <span className="time-pill">{window.MOCK.now}</span>
        </div>
        <div className="user-chip">
          <span className="ava">관</span>
          <span>관제팀 김보안</span>
        </div>
      </div>

      <nav className="nav">
        <div className="nav-group-label">통합 관제</div>
        {NAV.slice(0,5).map(n => (
          <button key={n.k} className={"nav-item "+(route===n.k?"active":"")} onClick={()=>setRoute(n.k)}>
            <Icon name={n.icon} size={16}/>
            <span>{n.l}</span>
            {n.count && <span className="count">{n.count}</span>}
          </button>
        ))}
        <div className="nav-group-label">지식 · 운영</div>
        {NAV.slice(5).map(n => (
          <button key={n.k} className={"nav-item "+(route===n.k?"active":"")} onClick={()=>setRoute(n.k)}>
            <Icon name={n.icon} size={16}/>
            <span>{n.l}</span>
          </button>
        ))}

        {/* 사이드바 푸터: 컨소시엄 포지셔닝(문서 §2)
            비티소프트는 각 솔루션 기능을 "대체"하는 것이 아니라 상위 분석·관제 레이어에 위치.
              NAC/SDP/AI-NDR → 엠엘소프트 (인증·Zero Trust·네트워크 이상행위)
              AI Gateway     → 모놀리    (생성형 AI 입출력 통제·C/S/O 정책)
              DB 보안        → 피앤피시큐어 (DBMS 쿼리·결과 분석, 데이터 등급 분류)
              WORM           → 나무소프트 (스토리지 무결성·랜섬웨어 대응)
              통합 관제·분석 → 비티소프트 (본 플랫폼) */}
      </nav>

      <main className="main" key={route}>
        {route === "dashboard" && <Dashboard onNav={setRoute} onOpenScenario={openScenario}/>}
        {route === "timeline" && <Timeline onOpenScenario={openScenario} onNav={setRoute}/>}
        {route === "scenarios" && <ScenarioView scenarioId={scenarioId} setScenarioId={setScenarioId}/>}
        {route === "analytics" && <AnalyticsView/>}
        {route === "xai" && <XaiPanel onOpenScenario={openScenario}/>}
        {route === "kb" && <KnowledgeBase/>}
        {route === "pipeline" && <PipelineStatus/>}
      </main>

      {!tweaksOpen && (
        <button className="tweaks-fab" onClick={()=>setTweaksOpen(true)} title="Tweaks">
          <Icon name="settings" size={18}/>
        </button>
      )}
      <TweaksPanel open={tweaksOpen} tweaks={tweaks} setTweaks={setTweaksAndPersist} close={()=>setTweaksOpen(false)}/>
    </div>
  );
};

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