/* CargoNote — app shell, sidebar, top bar, routing.
   Data comes from the backend API (window.CN.api); the open case detail and the
   inbox list live in App state and are passed to the views as `data`. */

const App = () => {
  const [cases, setCases] = React.useState([]);
  const [detail, setDetail] = React.useState(null);   // the case open in review/final
  const [route, setRoute] = React.useState("loading"); // loading → inbox/review/...
  const [toast, setToast] = React.useState(null);

  const data = { cases, heroCase: detail };

  const showToast = (m) => { setToast(m); setTimeout(() => setToast(null), 2600); };

  const refreshCases = React.useCallback(async () => {
    const list = await window.CN.api.listCases();
    setCases(list);
    return list;
  }, []);

  const openCase = React.useCallback(async (ref) => {
    try {
      const d = await window.CN.api.getCase(ref);
      setDetail(d);
      setRoute("review");
    } catch (e) {
      showToast("Impossible d'ouvrir le dossier");
    }
  }, []);

  // Initial load: fetch the inbox, then open the hero (or first reviewable) case.
  React.useEffect(() => {
    (async () => {
      try {
        const list = await refreshCases();
        const hero = list.find((c) => c.hero) || list.find((c) => c.status === "review");
        if (hero) {
          const d = await window.CN.api.getCase(hero.id);
          setDetail(d);
          setRoute("review");
        } else {
          setRoute("inbox");
        }
      } catch (e) {
        setRoute("apierror");
      }
    })();
  }, [refreshCases]);

  // Tweaks
  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    "density": "comfortable",
    "confViz": "all",
    "accent": "indigo"
  }/*EDITMODE-END*/;
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  React.useEffect(() => {
    document.body.setAttribute("data-density", t.density);
    document.body.setAttribute("data-conf-viz", t.confViz);
    const accents = {
      indigo: "53% 0.14 256",
      teal: "55% 0.12 195",
      olive: "55% 0.11 130",
      terracotta: "58% 0.14 40",
    };
    const v = accents[t.accent] || accents.indigo;
    document.documentElement.style.setProperty("--accent", `oklch(${v})`);
    document.documentElement.style.setProperty("--accent-2", `oklch(${v.replace(/^[\d.]+%/, (m) => (parseFloat(m) - 8) + "%")})`);
  }, [t]);

  // Create a case: real files run the extraction pipeline; no files → demo email.
  const handleIngest = React.useCallback(async (files) => {
    const hasFiles = files && files.length > 0;
    try {
      const created = await window.CN.api.createCase(hasFiles ? files : null, !hasFiles);
      await refreshCases();
      if (created.status === "error") {
        setRoute("inbox");
        showToast(created.errorMsg || "Échec de l'extraction");
      } else {
        await openCase(created.id);
        showToast(`Brouillon ${created.ref} ouvert pour vérification`);
      }
    } catch (e) {
      setRoute("inbox");
      showToast("Échec de l'extraction");
    }
  }, [refreshCases, openCase]);

  const handleApprove = React.useCallback(async () => {
    if (!detail) return;
    try {
      await window.CN.api.approve(detail.ref);
      await refreshCases();
      setDetail((d) => ({ ...d, status: "approved" }));
      setRoute("final");
      showToast(`${detail.ref} validé`);
    } catch (e) {
      showToast("Échec de la validation");
    }
  }, [detail, refreshCases]);

  const counts = {
    review: cases.filter((c) => c.status === "review").length,
    approved: cases.filter((c) => c.status === "approved").length,
    error: cases.filter((c) => c.status === "error").length,
  };

  const nav = [
    { id: "inbox", icon: "inbox", label: "Boîte de réception", count: cases.length, screen: "inbox" },
    { id: "review", icon: "eye", label: "À vérifier", count: counts.review, screen: "review" },
    { id: "approved", icon: "check", label: "Validés", count: counts.approved, screen: "inbox" },
    { id: "error", icon: "alert", label: "Erreurs", count: counts.error, screen: "inbox" },
  ];
  const tools = [
    { id: "new", icon: "plus", label: "Nouveau dossier", screen: "ingest" },
    { id: "history", icon: "history", label: "Historique" },
    { id: "settings", icon: "settings", label: "Paramètres" },
  ];

  if (route === "loading") {
    return <div style={{ display: "grid", placeItems: "center", height: "100vh", color: "var(--muted)" }}>
      <div style={{ textAlign: "center" }}>
        <div className="brand-mark" style={{ margin: "0 auto 12px", width: 36, height: 36 }}>C</div>
        Chargement de CargoNote…
      </div>
    </div>;
  }
  if (route === "apierror") {
    return <div style={{ display: "grid", placeItems: "center", height: "100vh", color: "var(--lo-ink)" }}>
      <div style={{ textAlign: "center", maxWidth: 380 }}>
        <Icon name="alert" size={28} />
        <div style={{ marginTop: 10 }}>Backend injoignable. Lancez le serveur&nbsp;:</div>
        <div className="mono" style={{ marginTop: 8, fontSize: 12 }}>uvicorn cmr_from_file.api.app:app --reload</div>
      </div>
    </div>;
  }

  return (
    <div className="app" data-screen-label={`${route}`}>
      <aside className="sidebar">
        <div className="brand">
          <div className="brand-mark">C</div>
          <div>
            <div style={{ lineHeight: 1 }}>CargoNote</div>
            <div style={{ fontSize: 10.5, color: "var(--chrome-muted)", marginTop: 2, fontWeight: 400 }}>Atlas Maghreb · Casablanca</div>
          </div>
        </div>

        <div className="section-label">Dossiers</div>
        {nav.map((n) => (
          <div key={n.id} className={`nav-item ${route === n.screen && n.id !== "approved" && n.id !== "error" ? "active" : ""}`} onClick={() => setRoute(n.screen)}>
            <Icon name={n.icon} size={15} className="icon" />
            <span>{n.label}</span>
            <span className="count">{n.count}</span>
          </div>
        ))}

        <div className="section-label">Outils</div>
        {tools.map((n) => (
          <div key={n.id} className={`nav-item ${route === n.screen ? "active" : ""}`} onClick={() => n.screen && setRoute(n.screen)}>
            <Icon name={n.icon} size={15} className="icon" />
            <span>{n.label}</span>
          </div>
        ))}

        <div className="user">
          <div className="avatar">HB</div>
          <div>
            <div className="name">Hicham Bennani</div>
            <div className="org">Opérateur · Atlas Maghreb</div>
          </div>
        </div>
      </aside>

      <main className="main" data-screen-label={`screen-${route}`}>
        <Topbar route={route} setRoute={setRoute} detail={detail} />
        {route === "inbox" && (
          <InboxView data={data} onOpen={openCase} onNew={() => setRoute("ingest")} />
        )}
        {route === "ingest" && (
          <IngestView onProcessed={handleIngest} />
        )}
        {route === "review" && detail && (
          <ReviewView data={data} onApprove={handleApprove} onBack={() => setRoute("inbox")} />
        )}
        {route === "final" && detail && (
          <FinalView data={data} onBack={() => setRoute("review")} onPrint={() => showToast(`Export PDF — ${detail.ref}.pdf téléchargé`)} />
        )}
      </main>

      {toast && (
        <div className="toast">
          <Icon name="check" size={14} />
          <span>{toast}</span>
        </div>
      )}

      <TweaksPanel title="Tweaks · CargoNote">
        <TweakSection title="Densité">
          <TweakRadio value={t.density} onChange={(v) => setTweak("density", v)}
            options={[{ value: "comfortable", label: "Confort" }, { value: "compact", label: "Compact" }]} />
        </TweakSection>
        <TweakSection title="Visualisation de la confiance">
          <TweakRadio value={t.confViz} onChange={(v) => setTweak("confViz", v)}
            options={[{ value: "all", label: "Tous" }, { value: "border", label: "Bordure" }, { value: "dot", label: "Pastille" }, { value: "tint", label: "Teinte" }]} />
        </TweakSection>
        <TweakSection title="Couleur d'accent">
          <TweakColor value={t.accent} onChange={(v) => setTweak("accent", v)}
            options={[{ value: "indigo", color: "oklch(53% 0.14 256)" }, { value: "teal", color: "oklch(55% 0.12 195)" }, { value: "olive", color: "oklch(55% 0.11 130)" }, { value: "terracotta", color: "oklch(58% 0.14 40)" }]} />
        </TweakSection>
        <TweakSection title="Aller à un écran">
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 6 }}>
            <TweakButton onClick={() => setRoute("inbox")}>Boîte de réception</TweakButton>
            <TweakButton onClick={() => setRoute("ingest")}>Nouveau dossier</TweakButton>
            <TweakButton onClick={() => detail && setRoute("review")}>Workspace</TweakButton>
            <TweakButton onClick={() => detail && setRoute("final")}>CMR final</TweakButton>
          </div>
        </TweakSection>
      </TweaksPanel>
    </div>
  );
};

const Topbar = ({ route, setRoute, detail }) => {
  const ref = detail ? detail.ref : "—";
  const crumbs = {
    inbox: [{ label: "Boîte de réception" }],
    ingest: [{ label: "Boîte de réception", to: "inbox" }, { label: "Nouveau dossier" }],
    review: [{ label: "Boîte de réception", to: "inbox" }, { label: ref }, { label: "Vérification" }],
    final: [{ label: "Boîte de réception", to: "inbox" }, { label: ref }, { label: "CMR final" }],
  }[route] || [];
  return (
    <div className="topbar">
      <div className="breadcrumb">
        {crumbs.map((c, i) => (
          <React.Fragment key={i}>
            {i > 0 && <Icon name="chev" size={12} style={{ color: "var(--muted-2)" }} />}
            {c.to ? <span onClick={() => setRoute(c.to)} style={{ cursor: "pointer" }}>{c.label}</span> : <b>{c.label}</b>}
          </React.Fragment>
        ))}
      </div>
      <div className="right">
        <button className="icon-btn" title="Notifications"><Icon name="bell" size={15} /><span style={{ position: "absolute", width: 6, height: 6, background: "var(--lo)", borderRadius: "50%", marginTop: -10, marginLeft: 6 }}></span></button>
        <button className="icon-btn" title="Raccourcis clavier" style={{ fontSize: 11, fontFamily: "var(--font-mono)" }}>?</button>
        <button className="icon-btn" title="Paramètres"><Icon name="settings" size={15} /></button>
      </div>
    </div>
  );
};

window.App = App;
