/* global React, ReactDOM */

const { useState: useS, useEffect: useE, useRef: useR } = React;

function useLang() {
  const [lang, setLang] = useS(() => localStorage.getItem("penumbra_lang") || "fr");
  useE(() => { localStorage.setItem("penumbra_lang", lang); document.documentElement.lang = lang; }, [lang]);
  return [lang, setLang];
}

function useHashRoute() {
  return "predict";
}

function todayStr() {
  return new Date().toISOString().slice(0, 10);
}

function App() {
  const [lang, setLang] = useLang();
  const route = useHashRoute();
  const t = (k) => (window.I18N[lang] && window.I18N[lang][k]) || k;

  return (
    <>
      <header className="topbar">
        <div className="inner">
          <a href="#" className="brand" onClick={(e) => { if (route === "predict") { e.preventDefault(); } window.location.hash = ""; }}>
            <span className="mark"></span>
            <span>Penumbra</span>
          </a>
          <nav className="nav">
            <div className="lang-switch" role="group" aria-label="Language">
              <button
                className={"ls-btn" + (lang === "fr" ? " active" : "")}
                onClick={() => setLang("fr")}
              >FR</button>
              <span className="ls-sep">/</span>
              <button
                className={"ls-btn" + (lang === "en" ? " active" : "")}
                onClick={() => setLang("en")}
              >EN</button>
            </div>
          </nav>
        </div>
      </header>

      <main className="container">
        <PredictPage t={t} lang={lang} />

        <footer className="footer">
          <div className="cols">
            <div>{t("foot_credit")}</div>
            <div>
              <a href="https://arxiv.org/abs/2602.07108" target="_blank" rel="noopener">
                {t("foot_dataset")}
              </a>
            </div>
          </div>
        </footer>
      </main>
    </>
  );
}

function PredictPage({ t, lang }) {
  const [depIata, setDepIata] = useS("CDG");
  const [arrIata, setArrIata] = useS("JFK");
  const [date, setDate] = useS(todayStr());
  const [departureTime, setDepartureTime] = useS("10:00");
  const [error, setError] = useS("");
  const [loading, setLoading] = useS(false);
  const [trajectory, setTrajectory] = useS(null);
  const [meta, setMeta] = useS(null);
  const [solarEvent, setSolarEvent] = useS(null);

  const onCalculate = async () => {
    setError("");
    setTrajectory(null);
    setSolarEvent(null);

    const dep = depIata.trim().toUpperCase();
    const arr = arrIata.trim().toUpperCase();
    if (!dep || !arr || dep.length < 3 || arr.length < 3) {
      setError(t("err_iata_required"));
      return;
    }

    setLoading(true);
    try {
      const { trajectory: traj, meta: m, solarEvent: se } = await window.buildTrajectory({
        depIata: dep,
        arrIata: arr,
        date,
        departureTime,
      });
      setTrajectory(traj);
      setMeta(m);
      setSolarEvent(se);
    } catch (e) {
      setError(e.message || t("err_unknown_flight"));
    } finally {
      setLoading(false);
    }
  };

  const onSubmit = (e) => { e.preventDefault(); onCalculate(); };

  return (
    <>
      <section className="hero">
        <h1>{t("hero_title")}</h1>
        <p className="lead">{t("hero_lead")}</p>
        <span className="badge">
          <span className="dot"></span>
          {t("hero_badge")}
        </span>
      </section>

      <section className="tool">
        <div className="col-left">
          {!trajectory && (
            <form className="form-block" onSubmit={onSubmit}>
              <div className="label-uc">{t("form_section_kicker")}</div>
              <h2>{t("form_section_title")}</h2>

              <AirportInput
                label={t("form_label_dep")}
                value={depIata}
                onChange={setDepIata}
                placeholder="CDG"
              />
              <AirportInput
                label={t("form_label_arr")}
                value={arrIata}
                onChange={setArrIata}
                placeholder="JFK"
              />

              <div className="field">
                <label>{t("form_label_date")}</label>
                <div className="row">
                  <input
                    type="date"
                    value={date}
                    onChange={(e) => setDate(e.target.value)}
                  />
                </div>
              </div>

              <div className="field">
                <label>{t("form_label_time")}</label>
                <div className="row">
                  <input
                    type="time"
                    value={departureTime}
                    onChange={(e) => setDepartureTime(e.target.value)}
                  />
                </div>
              </div>

              <button type="submit" className="btn-primary" disabled={loading}>
                {loading ? "…" : t("form_btn_calculate")}
              </button>

              {loading && (
                <div className="error-msg" style={{ color: "var(--ink-2)", background: "none", border: "none", padding: "8px 0" }}>
                  Calcul en cours via le modèle XGBoost…
                </div>
              )}

              {error && <div className="error-msg">{error}</div>}

              <p className="form-note">{t("form_note")}</p>
            </form>
          )}

          {trajectory && (
            <>
              {solarEvent && (
                <SolarEventAlert event={solarEvent} t={t} />
              )}
              <ResultPanel
                trajectory={trajectory}
                meta={meta}
                t={t}
                lang={lang}
                onReset={() => { setTrajectory(null); setMeta(null); setSolarEvent(null); }}
              />
            </>
          )}
        </div>

        <div className="col-right">
          <window.TrajectoryMap
            trajectory={trajectory}
            fromAirport={meta && meta.fromAp}
            toAirport={meta && meta.toAp}
            t={t}
          />
        </div>
      </section>

      <section className="explainer">
        <ExpCard
          icon={<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12h3l3-9 6 18 3-9h3"/></svg>}
          title={t("exp1_title")} text={t("exp1_text")}
        />
        <ExpCard
          icon={<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M2 12h2M20 12h2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>}
          title={t("exp2_title")} text={t("exp2_text")}
        />
        <ExpCard
          icon={<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M4 18l4-8 4 4 4-10 4 14"/></svg>}
          title={t("exp3_title")} text={t("exp3_text")}
        />
      </section>
    </>
  );
}

function AirportInput({ label, value, onChange, placeholder }) {
  const [query, setQuery] = useS(value || "");
  const [suggestions, setSuggestions] = useS([]);
  const [open, setOpen] = useS(false);
  const timer = useR(null);

  const fetch_ = (q) => {
    clearTimeout(timer.current);
    if (q.length < 2) { setSuggestions([]); return; }
    timer.current = setTimeout(async () => {
      try {
        const r = await fetch(`/airports/search?q=${encodeURIComponent(q)}`);
        if (r.ok) setSuggestions(await r.json());
      } catch (_) {}
    }, 180);
  };

  const onInput = (e) => {
    const v = e.target.value;
    setQuery(v);
    setOpen(true);
    fetch_(v);
  };

  const onSelect = (ap) => {
    const display = `${ap.iata} — ${ap.city}`;
    setQuery(display);
    onChange(ap.iata);
    setSuggestions([]);
    setOpen(false);
  };

  const onBlur = () => setTimeout(() => setOpen(false), 160);
  const onFocus = () => { if (query.length >= 2) setOpen(true); };

  return (
    <div className="field ap-field">
      <label>{label}</label>
      <div className="row">
        <input
          value={query}
          onChange={onInput}
          onFocus={onFocus}
          onBlur={onBlur}
          placeholder={placeholder}
          autoComplete="off"
          spellCheck="false"
          className="iata-input"
        />
      </div>
      {open && suggestions.length > 0 && (
        <ul className="ap-suggestions">
          {suggestions.map((ap) => (
            <li key={ap.iata} onMouseDown={() => onSelect(ap)}>
              <span className="ap-code">{ap.iata}</span>
              <span className="ap-city">{ap.city}</span>
              <span className="ap-name">{ap.name}</span>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

function SolarEventAlert({ event, t }) {
  const stormColor = { g1: "#e6b800", g2: "#e68600", g3: "#e65200", g4: "#c42b00", g5: "#8b0000" };
  const scale = event.scale || "";
  const badgeColor = stormColor[scale.toLowerCase()] || "#c42b00";

  return (
    <div className="solar-alert">
      <div className="alert-icon" aria-hidden="true">
        <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
          <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
          <line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
        </svg>
      </div>
      <div className="alert-body">
        <strong>{t("solar_alert_title")}</strong>
        {scale && (
          <div className="alert-row">
            {t("solar_alert_storm")}
            <span className="storm-badge" style={{ background: badgeColor }}>{scale}</span>
            — Kp max {event.kp_max}
          </div>
        )}
        {event.flare_class && (
          <div className="alert-row">{t("solar_alert_flare")} <strong>{event.flare_class}</strong></div>
        )}
        <div className="alert-note">{t("solar_alert_note")}</div>
      </div>
    </div>
  );
}

function ExpCard({ icon, title, text }) {
  return (
    <div className="card">
      <div className="icon" aria-hidden="true">{icon}</div>
      <h3>{title}</h3>
      <p>{text}</p>
    </div>
  );
}

function ResultPanel({ trajectory, meta, t, lang, onReset }) {
  const dose = trajectory.totalDose;
  const low  = trajectory.lowDose;
  const high = trajectory.highDose;
  const riskKey = { low: "risk_low", mod: "risk_mod", high: "risk_high" }[trajectory.totalRisk];

  const chestXrays = dose / 100;
  const annualPct  = (dose / 1000) * 100;
  const groundHours = dose / 0.27;
  const groundDays = groundHours / 24;

  const fmtDose = window.fmtNumber(dose, 0);
  const fmtLow  = window.fmtNumber(low, 0);
  const fmtHigh = window.fmtNumber(high, 0);

  const dateLocale = lang === "fr" ? "fr-FR" : "en-US";
  const dateFmt = new Date(meta.date).toLocaleDateString(dateLocale, { day: "numeric", month: "long", year: "numeric" });

  const durationStr = (() => {
    const h = Math.floor(trajectory.durationHours);
    const m = Math.round((trajectory.durationHours - h) * 60);
    return `${h} h ${String(m).padStart(2, "0")}`;
  })();

  const xrayValTxt = window.fmtNumber(chestXrays, chestXrays < 1 ? 2 : 1) + " " + (chestXrays >= 2 ? t("cmp_xray_v_many") : t("cmp_xray_v_one"));
  const groundValTxt = groundDays >= 1
    ? window.fmtNumber(groundDays, groundDays < 2 ? 1 : 0) + " " + (groundDays >= 2 ? t("ground_unit_d_many") : t("ground_unit_d_one"))
    : window.fmtNumber(groundHours, 0) + " " + t("ground_unit_h");

  return (
    <div className="result fade-in">
      <div className="result-head">
        <div><div className="label-uc">{t("res_label")}</div></div>
        <button onClick={onReset} className="link-btn">← {t("res_new")}</button>
      </div>

      <div className="dose-display">
        <span className="num">{fmtDose}</span>
        <span className="unit">µSv</span>
      </div>

      <div className="ci-line">
        {t("res_ci")} · <span className="tnum" style={{ color: "var(--ink-2)" }}>{fmtLow} – {fmtHigh} µSv</span>
      </div>

      <div className={"risk " + trajectory.totalRisk}>
        <span className="pip"></span>{t(riskKey)}
      </div>

      <div className="compare-grid">
        <div className="compare-card">
          <span className="k">{t("cmp_xray_k")}</span>
          <span className="v">{xrayValTxt}</span>
        </div>
        <div className="compare-card">
          <span className="k">{t("cmp_annual_k")}</span>
          <span className="v">{window.fmtNumber(annualPct, annualPct < 1 ? 2 : 1)} %</span>
        </div>
        <div className="compare-card">
          <span className="k">{t("cmp_ground_k")}</span>
          <span className="v">{groundValTxt}</span>
        </div>
      </div>

      <div className="flight-meta">
        <div className="meta-item">
          <span className="k">{t("meta_route")}</span>
          <span className="v">{meta.fromAp.city} ({meta.fromAp.iata}) → {meta.toAp.city} ({meta.toAp.iata})</span>
        </div>
        <div className="meta-item">
          <span className="k">{t("meta_date")}</span>
          <span className="v">{dateFmt}</span>
        </div>
        <div className="meta-item">
          <span className="k">{t("meta_duration")}</span>
          <span className="v">{durationStr}</span>
        </div>
        <div className="meta-item">
          <span className="k">{t("meta_distance")}</span>
          <span className="v">{window.fmtNumber(trajectory.distanceKm, 0)} km</span>
        </div>
        <div className="meta-item">
          <span className="k">{t("meta_alt")}</span>
          <span className="v">FL{Math.round(meta.cruiseFt / 100)}</span>
        </div>
        {meta.kpUsed !== undefined && (
          <div className="meta-item">
            <span className="k">Kp ({meta.dataSource})</span>
            <span className="v">{typeof meta.kpUsed === "number" ? meta.kpUsed.toFixed(1) : meta.kpUsed}</span>
          </div>
        )}
      </div>
    </div>
  );
}

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