// screens-main.jsx — Today, Logs, Flights, Profile, LogDetail. Exported to window.
const { useState: useStateM } = React;

function fuelLitres(f) { return Math.round(f.fuelUplift / f.fuelDensity); }

/* ============================== TODAY ============================== */
function TodayScreen({ logs, onOpenLog, onNew, openCB, openPhoto, onFuel, onAircraft, onSchematic, onTowing, onMel, onToolSearch, onWx, onConvert, onStatus, go, sync = {}, onRetry, shifts = {}, profile, assignedReg, onPickAssigned, watch = [], onRemoveWatch, t }) {
  const me = profile || {};
  const firstName = me.firstName || String(me.name || "").split(/\s+/)[0] || "there";
  const today = logs.filter((l) => l.tech === "You");
  const pending = today.filter((l) => l.status === "pending").length;
  const assigned = FLEET.find((a) => a.reg === assignedReg) || FLEET[0];
  const flt = assigned ? currentFlight(assigned.reg) : null;
  const now = new Date();
  const sh = effectiveShift(now, shifts);
  const eyebrow = `${now.toLocaleDateString("en-GB", { weekday: "long" })} · ${String(now.getDate()).padStart(2, "0")} ${now.toLocaleDateString("en-GB", { month: "short" })}`;
  const nx = sh.working ? null : shiftNext(now, shifts);
  return (
    <div className="screen-scroll">
      <div className="today-hero">
        <div className="today-hero-row">
          <div>
            <div className="eyebrow">{eyebrow}</div>
            <h1 className="today-h1">Hi, {firstName}</h1>
            <div className={"shift-chip shift-chip--" + sh.kind}>
              <i className="shift-dot" />
              {sh.working
                ? <span>{sh.label} · <b className="mono">{sh.hours}</b></span>
                : <span>Day off{nx ? <> · back {nx.kind === "night" ? "night" : "AM"} {nx.date.toLocaleDateString("en-GB", { weekday: "short", day: "2-digit" })}</> : ""}</span>}
              {sh.override && <span className={"shift-tag shift-tag--" + sh.override.reason}>{SHIFT_REASON[sh.override.reason] || "Edit"}</span>}
            </div>
          </div>
          <div className="avatar">{initials(me.name)}</div>
        </div>
        <div className="today-stats today-stats--2">
          <div className="tstat"><b>{today.length}</b><span>Jobs today</span></div>
          <div className="tstat"><b className={pending ? "warn" : ""}>{pending}</b><span>Pending</span></div>
        </div>
      </div>

      <button
        className={"offline-banner" + (sync.state === "offline" ? " offline-banner--warn" : "") + (sync.state === "loading" ? " offline-banner--sync" : "")}
        onClick={sync.state === "offline" && onRetry ? onRetry : undefined}>
        <Ic.sync width="16" height="16" />
        <span>
          {sync.state === "loading" && "Connecting to OPS API…"}
          {sync.state === "live" && `Connected to OPS API · updated ${sync.at}${pending ? ` · ${pending} pending` : ""}`}
          {sync.state === "offline" && `OPS API offline — tap to retry${pending ? ` · ${pending} pending` : ""}`}
          {!sync.state && `Offline — saved locally ${pending ? `· ${pending} to upload` : "· all synced"}`}
        </span>
      </button>

      <div className="block">
        <div className="block-head"><span>Assigned aircraft</span>{FLEET.length > 0 && <button className="link" onClick={onPickAssigned}><Ic.plus width="13" height="13" />Change</button>}</div>
        {assigned ? (
          <Card className="ac-card" onClick={() => onAircraft(assigned.reg)} role="button">
            <div className="ac-reg mono">{assigned.reg}</div>
            <div className="ac-meta">{assigned.type} · {assigned.eng} · <span className="ac-mr2">MR2 {(MR2[assigned.reg] || []).length} open</span></div>
            {flt && (
              <button className="ac-flight" onClick={(e) => { e.stopPropagation(); onStatus && onStatus(flt); }}>
                <span className="flt-pill mono">{flt.id}</span>
                <span className="flt-route">{flt.from}→{flt.to}</span>
                <span className="flt-stand"><Ic.pin width="13" height="13" />Gate {flt.gate}/Bay {flt.bay}</span>
                <span className={"flt-status flt-status--" + (flt.opStatus === "Boarding" ? "now" : "soft")}>{flt.opStatus}</span>
                <Ic.chevron className="ac-flight-go" width="15" height="15" />
              </button>
            )}
          </Card>
        ) : (
          <Card className="ac-card ac-card--empty">
            {sync.state === "offline"
              ? "OPS API ออฟไลน์ — ยังไม่มีข้อมูลฝูงบิน · แตะแบนเนอร์ด้านบนเพื่อลองใหม่"
              : "กำลังโหลดข้อมูลฝูงบินจาก OPS API…"}
          </Card>
        )}
      </div>

      {watch.length > 0 && (
        <div className="block">
          <div className="block-head"><span>Watching arrivals</span><span className="mono" style={{ color: "var(--ink-soft)", fontSize: 11 }}>เตือนก่อนถึง 15m</span></div>
          <div className="watch-list">
            {watch.map((w) => {
              const f = FLIGHTS.find((x) => x.id === w.id);
              const a = f ? flightArrival(f) : null;
              const state = !f ? "" : a.landed ? "landed" : (a.mins != null && a.mins <= w.lead ? "soon" : "");
              const eta = !f ? "—" : a.landed ? "Landed ✓" : a.mins == null ? "—" : a.mins <= 0 ? "Landing now" : "in " + a.mins + "m";
              return (
                <div key={w.id} className={"watch-row" + (state ? " watch-row--" + state : "")}>
                  <button className="watch-main" onClick={() => f && onStatus(f)}>
                    <span className="flt-pill mono">{w.id}</span>
                    <span className="watch-route">{f ? f.from + "→" + f.to : "—"} · <span className="mono">{w.reg}</span></span>
                    <span className="watch-eta">{eta}</span>
                  </button>
                  <button className="watch-x" onClick={() => onRemoveWatch && onRemoveWatch(w.id)} aria-label="remove"><Ic.close width="14" height="14" /></button>
                </div>
              );
            })}
          </div>
        </div>
      )}

      <div className="quick-grid">
        <button className="quick quick--accent" onClick={onNew}><Ic.plus width="22" height="22" /><span>New Work Log</span></button>
        <button className="quick quick--wide" onClick={onToolSearch}><Ic.search width="21" height="21" /><span>Search Tool Inventory</span></button>
        <button className="quick" onClick={openCB}><Ic.cb width="22" height="22" /><span>C/B Reset</span></button>
        <button className="quick" onClick={openPhoto}><Ic.camera width="22" height="22" /><span>On-site Photo</span></button>
        <button className="quick" onClick={onFuel}><Ic.fuel width="22" height="22" /><span>Fuel Calc</span></button>
        <button className="quick" onClick={onTowing}><Ic.tow width="22" height="22" /><span>Towing</span></button>
        <button className="quick" onClick={onMel}><Ic.clock width="22" height="22" /><span>MEL Calc</span></button>
        <button className="quick" onClick={onWx}><Ic.wx width="22" height="22" /><span>Weather</span></button>
        <button className="quick" onClick={onConvert}><Ic.swap width="22" height="22" /><span>Unit Converter</span></button>
        <button className="quick quick--wide" onClick={() => window.open(DNB_URL, "_blank", "noopener")}><Ic.dent width="21" height="21" /><span>Dent &amp; Buckle</span><span className="quick-ext"><Ic.ext width="13" height="13" />Drive</span></button>
      </div>

      <div className="block">
        <div className="block-head"><span>Today's timeline</span><button className="link" onClick={() => go("logs")}>History</button></div>
        <div className="timeline">
          {today.map((l) => (
            <button key={l.id} className="tl-item" onClick={() => onOpenLog(l)}>
              <div className="tl-time mono">{l.start}</div>
              <div className="tl-line"><i /></div>
              <div className="tl-body">
                <div className="tl-top"><AtaBadge code={l.ata} /><StatusDot status={l.status} /></div>
                <div className="tl-title">{l.title}</div>
                <div className="tl-sub">{l.th} · <span className="mono">{l.reg}</span> · {l.dur}</div>
              </div>
            </button>
          ))}
          {today.length === 0 && <div className="empty">ยังไม่มีงานวันนี้ · กดปุ่ม + เพื่อเริ่ม Work Log</div>}
        </div>
      </div>
      <div className="scroll-pad" />
    </div>
  );
}

/* ============================== LOGS / HISTORY ============================== */
function LogsScreen({ logs, onOpenLog, t }) {
  const [q, setQ] = useStateM("");
  const [fAta, setFAta] = useStateM(null);
  const list = logs.filter((l) => {
    if (fAta && l.ata !== fAta) return false;
    if (!q) return true;
    const s = (l.title + l.th + l.reg + l.ata + l.defect).toLowerCase();
    return s.includes(q.toLowerCase());
  });
  const ataChips = [...new Set(logs.map((l) => l.ata))];
  return (
    <div className="screen-scroll">
      <div className="logs-search">
        <div className="searchbar">
          <Ic.search width="18" height="18" />
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search: reg, ATA, defect, P/N…" />
          {q && <button className="iconbtn" onClick={() => setQ("")}><Ic.close width="16" height="16" /></button>}
        </div>
        <div className="chiprow">
          <Chip on={!fAta} onClick={() => setFAta(null)}>All</Chip>
          {ataChips.map((c) => <Chip key={c} mono on={fAta === c} onClick={() => setFAta(fAta === c ? null : c)}>ATA {c}</Chip>)}
        </div>
      </div>
      <div className="block">
        <div className="block-head"><span>{list.length} logs</span><button className="link"><Ic.filter width="15" height="15" />Filter</button></div>
        <div className="loglist">
          {list.map((l) => (
            <button key={l.id} className="logrow" onClick={() => onOpenLog(l)}>
              <div className="logrow-l">
                <div className="logrow-top"><AtaBadge code={l.ata} /><span className="logrow-id mono">{l.id}</span></div>
                <div className="logrow-title">{l.title}</div>
                <div className="logrow-sub"><span className="mono">{l.reg}</span> · {l.start}–{l.stop}{photoCount(l.photos) > 0 && <span> · <Ic.camera width="12" height="12" /> {photoCount(l.photos)}</span>}</div>
              </div>
              <div className="logrow-r"><StatusDot status={l.status} /><Ic.chevron width="18" height="18" /></div>
            </button>
          ))}
          {list.length === 0 && <div className="empty">No logs match your search</div>}
        </div>
      </div>
      <div className="scroll-pad" />
    </div>
  );
}

/* ============================== FLIGHT CARD (3 variants) ============================== */
function OpBadge({ s }) {
  const cls = s === "Boarding" ? "now" : s === "Departed" ? "off" : "soft";
  return <span className={"opstatus opstatus--" + cls}>{s}</span>;
}
function PaxBar({ f }) {
  const pct = f.paxCap ? Math.round((f.pax / f.paxCap) * 100) : 0;
  const lvl = pct >= 70 ? "hi" : "ok";
  return (
    <div className="pax">
      <div className="pax-top"><span>Passenger load</span><span className="mono">{f.pax}/{f.paxCap} ({pct}%)</span></div>
      <div className="pax-bar"><i className={"pax-fill pax-fill--" + lvl} style={{ width: pct + "%" }} /></div>
    </div>
  );
}

function FlightCard({ f, variant, onAttach, onFuel, onAircraft, onStatus }) {
  const fuelL = (f.fuelFinal || 0);                  // already in litres — no conversion
  const pct = Math.min(100, Math.round((fuelL / 19000) * 100));   // gauge fill vs ~A320 tank
  const acts = <FlightActions f={f} onAttach={onAttach} onFuel={onFuel} onAircraft={onAircraft} />;
  if (variant === "boarding") {
    return (
      <Card className="bp">
        <div className="bp-stub">
          <button className="bp-id mono" onClick={() => onStatus && onStatus(f)}>{f.id}</button>
          <div className="bp-stub-r"><OpBadge s={f.opStatus} /><button className="regbtn regbtn--inv mono" onClick={() => onAircraft(f.reg)}>{f.reg}</button></div>
        </div>
        <div className="bp-main">
          <div className="bp-route">
            <div className="bp-port"><b>{f.from}</b></div>
            <div className="bp-arrow"><span className="mono">{f.actualIn}</span><Ic.flight width="20" height="20" /></div>
            <div className="bp-port"><b>{f.to}</b></div>
          </div>
          <div className="bp-grid">
            <KV k="STD" v={f.std} mono /><KV k="STA" v={f.sta} mono />
            <KV k="GATE / BAY" v={`${f.gate} / ${f.bay}`} mono /><KV k="TSAT" v={f.tsat} mono />
          </div>
          <div className="bp-fuel"><Ic.fuel width="16" height="16" /><span>Fuel</span><b className="mono">{fuelL.toLocaleString()} L · {f.fuelStatus}</b></div>
          <PaxBar f={f} />
        </div>
        {acts}
      </Card>
    );
  }
  if (variant === "gauge") {
    return (
      <Card className="fg">
        <div className="fg-head"><button className="flt-pill flt-pill--tap mono" onClick={() => onStatus && onStatus(f)}>{f.id}</button><button className="regbtn mono" onClick={() => onAircraft(f.reg)}>{f.reg}</button><OpBadge s={f.opStatus} /></div>
        <div className="fg-body">
          <div className="gauge" style={{ "--p": pct }}>
            <svg viewBox="0 0 120 120"><circle className="g-bg" cx="60" cy="60" r="50" /><circle className="g-fg" cx="60" cy="60" r="50" /></svg>
            <div className="gauge-c"><b className="mono">{fuelL.toLocaleString()}</b><span>L · {f.fuelStatus}</span></div>
          </div>
          <div className="fg-side">
            <KV k="Fuel" v={fuelL.toLocaleString() + " L"} mono />
            <KV k="Truck" v={f.refuelTruck} mono />
          </div>
        </div>
        <div className="fg-foot"><span><Ic.pin width="13" height="13" />Gate {f.gate} / Bay {f.bay}</span><span className="mono">STD {f.std} · STA {f.sta}</span></div>
        <PaxBar f={f} />
        {acts}
      </Card>
    );
  }
  // default: data row (ops-board style)
  return (
    <Card className="fr">
      <div className="fr-head">
        <div className="fr-id"><button className="flt-pill flt-pill--tap mono" onClick={() => onStatus && onStatus(f)}>{f.id}</button><button className="regbtn mono" onClick={() => onAircraft(f.reg)}>{f.reg}</button><span className="fr-type">{f.type}</span></div>
        <OpBadge s={f.opStatus} />
      </div>
      <div className="fr-route2"><b className="mono">{f.from}</b><Ic.flight width="18" height="18" /><b className="mono">{f.to}</b></div>
      <div className="fr-grid4">
        <KV k="STD" v={f.std} mono /><KV k="STA" v={f.sta} mono />
        <KV k="GATE / BAY" v={`${f.gate} / ${f.bay}`} mono /><KV k="TSAT" v={f.tsat} mono />
      </div>
      <div className="fr-fuelline"><Ic.fuel width="15" height="15" /><span>Fuel</span><b className="mono">{fuelL.toLocaleString()} L · {f.fuelStatus}</b></div>
      <PaxBar f={f} />
      {acts}
    </Card>
  );
}

function FlightActions({ f, onAttach, onFuel, onAircraft }) {
  return (
    <div className="flt-foot">
      <div className="flt-actions flt-actions--3">
        <button className="flt-act flt-act--ghost" onClick={() => onFuel(f)}><Ic.fuel width="15" height="15" />Fuel</button>
        <button className="flt-act flt-act--track" onClick={() => window.open(trackUrl(f.id), "_blank", "noopener")}><Ic.flight width="15" height="15" />Track</button>
        <button className="flt-act" onClick={() => onAttach(f)}>Work Log <Ic.arrowR width="15" height="15" /></button>
      </div>
      <button className="flt-acbtn" onClick={() => onAircraft(f.reg)}><Ic.doc width="15" height="15" />Aircraft Info · W&amp;B · MR2 <Ic.chevron width="16" height="16" /></button>
    </div>
  );
}

/* ============================== ASSIGN AIRCRAFT PICKER ============================== */
function AssignSheet({ open, onClose, onPick, current }) {
  const [q, setQ] = useStateM("");
  const lib = window.FLEET || [];
  const s = q.trim().toLowerCase();
  const list = (s ? lib.filter((a) => (a.reg + " " + (a.type || "")).toLowerCase().includes(s)) : lib).slice(0, 80);
  const choose = (reg) => { onPick(reg); onClose(); setQ(""); };
  return (
    <Sheet open={open} onClose={onClose} title="Assign aircraft" full>
      <p className="sheet-lead">เลือกเครื่องที่รับผิดชอบวันนี้ — จะแสดงบนหน้า Today (จำไว้ในเครื่อง)</p>
      <div className="searchbar searchbar--insheet">
        <Ic.search width="18" height="18" />
        <input autoFocus value={q} onChange={(e) => setQ(e.target.value)} placeholder="ค้น reg / type — เช่น ABA, A321" />
        {q && <button className="iconbtn" onClick={() => setQ("")}><Ic.close width="16" height="16" /></button>}
      </div>
      <div className="assign-list">
        {list.map((a) => {
          const on = a.reg === current;
          const mr2n = (MR2[a.reg] || []).length;
          return (
            <button key={a.reg} className={"assign-row" + (on ? " assign-row--on" : "")} onClick={() => choose(a.reg)}>
              <span className="assign-reg mono">{a.reg}</span>
              <span className="assign-meta">{a.type || "—"}{mr2n ? <i className="assign-mr2"> · MR2 {mr2n}</i> : null}</span>
              {on ? <Ic.check width="17" height="17" /> : <Ic.chevron width="16" height="16" />}
            </button>
          );
        })}
        {!lib.length && <div className="empty">ยังไม่มีข้อมูลฝูงบิน (รอ OPS API)</div>}
        {s && !list.length && lib.length > 0 && <div className="empty">ไม่พบ “{q}”</div>}
      </div>
    </Sheet>
  );
}

/* ============================== FLIGHT STATUS (Google-style) ============================== */
const hmMin = (s) => { const m = /(\d{1,2}):(\d{2})/.exec(s || ""); return m ? (+m[1]) * 60 + (+m[2]) : null; };
function fStat(f) {
  const depSched = f.depSched || f.std || "", depAct = f.depAct || "", depEst = f.depEst || "";
  const arrSched = f.arrSched || f.sta || "", arrAct = f.arrAct || "", arrEst = f.arrEst || "";
  const departed = !!depAct || /Depart|Land|Airborne|Boarding closed/i.test(f.opStatus || "");
  const landed = !!arrAct || /Land/i.test(f.opStatus || "");
  const depShow = depAct || depEst || depSched || "—", arrShow = arrAct || arrEst || arrSched || "—";
  const depDelayed = (depAct || depEst) && depSched && (depAct || depEst) !== depSched;
  const arrDelayed = (arrAct || arrEst) && arrSched && (arrAct || arrEst) !== arrSched;
  const dM = hmMin(depAct || depEst || depSched), aM = hmMin(arrAct || arrEst || arrSched);
  const now = new Date(), nM = now.getHours() * 60 + now.getMinutes();
  let frac = 0;
  if (landed) frac = 1;
  else if (departed && dM != null && aM != null && aM > dM) frac = Math.min(1, Math.max(0.03, (nM - dM) / (aM - dM)));
  else if (departed) frac = 0.5;
  return { depShow, depSched, depDelayed, departed, arrShow, arrSched, arrDelayed, landed, frac,
    depLabel: departed ? "Departed" : "Departs",
    arrLabel: landed ? "Arrived" : (arrEst && arrEst !== arrSched ? "Estimated arrival" : "Scheduled arrival") };
}

// The aircraft's "current" flight for the Today card: the leg in progress (airborne),
// else the next upcoming leg, else the most recent — NOT just the first of the day.
function currentFlight(reg) {
  const fl = FLIGHTS.filter((f) => f.reg === reg);
  if (!fl.length) return null;
  const byStd = fl.slice().sort((a, b) => String(a.std || "").localeCompare(String(b.std || ""), undefined, { numeric: true }));
  const active = byStd.filter((f) => { const s = fStat(f); return s.departed && !s.landed; });
  if (active.length) return active[active.length - 1];        // in the air now → latest active
  const upcoming = byStd.filter((f) => !fStat(f).departed);
  if (upcoming.length) return upcoming[0];                     // next leg to depart
  return byStd[byStd.length - 1];                              // all done → last leg
}

function FlightStatus({ f }) {
  const s = fStat(f);
  return (
    <div className="fstat">
      <div className="fstat-head"><span className="flt-pill mono">{f.id}</span><span className="fstat-type">{f.type}</span><OpBadge s={f.opStatus} /></div>
      <div className="fstat-route">
        <div className="fstat-port"><b>{f.from}</b><span>{airportName(f.from)}</span></div>
        <div className="fstat-line" style={{ "--f": s.frac }}>
          <i className="fstat-base" /><i className="fstat-prog" />
          <Ic.flight className="fstat-plane" width="18" height="18" />
        </div>
        <div className="fstat-port fstat-port--r"><b>{f.to}</b><span>{airportName(f.to)}</span></div>
      </div>
      <div className="fstat-times">
        <div className="fstat-t">
          <span className="fstat-lbl">{s.depLabel}</span>
          <b className={"fstat-time" + (s.departed ? " fstat-time--on" : "")}>{s.depShow}</b>
          {s.depDelayed && <s className="fstat-sched mono">{s.depSched}</s>}
          {f.gate && f.gate !== "-" && <span className="fstat-gate mono">Gate {f.gate}{f.bay && f.bay !== "-" ? " · Bay " + f.bay : ""}</span>}
        </div>
        <div className="fstat-t fstat-t--r">
          <span className="fstat-lbl">{s.arrLabel}</span>
          <b className={"fstat-time" + (s.landed ? " fstat-time--on" : "")}>{s.arrShow}</b>
          {s.arrDelayed && <s className="fstat-sched mono">{s.arrSched}</s>}
        </div>
      </div>
    </div>
  );
}

function FlightStatusSheet({ flight, onClose, watching, onToggleWatch }) {
  return (
    <Sheet open={!!flight} onClose={onClose} title="Flight status">
      {flight && (
        <>
          <FlightStatus f={flight} />
          <button className={"fstat-watch" + (watching ? " fstat-watch--on" : "")} onClick={onToggleWatch}>
            <Ic.bell width="17" height="17" />
            {watching ? "กำลังเตือนก่อนถึง — แตะเพื่อปิด" : "เตือนฉันเมื่อใกล้ลง / ลงแล้ว (ไปรับเครื่อง)"}
          </button>
          <p className="fstat-src">Source: OPS API (taaplus) · เวลาถึง = ตามตาราง/ETA ของ OPS (เวลาลงจริงอาจช้ากว่า) · กด "แผนที่สด" ดูเวลาลงจริง real-time</p>
          <Btn full kind="ghost" onClick={() => window.open(trackUrl(flight.id), "_blank", "noopener")} icon={<Ic.ext width="16" height="16" />}>เปิดแผนที่สด (FlightStats)</Btn>
        </>
      )}
    </Sheet>
  );
}

function FlightsScreen({ variant, onAttach, onFuel, onAircraft, onStatus, sync = {}, onRetry, t }) {
  const [q, setQ] = useStateM("");
  const [sortBy, setSortBy] = useStateM("std");   // "std" | "flt"
  const [asc, setAsc] = useStateM(true);
  const subText = sync.state === "live" ? `From OPS API · updated ${sync.at}`
    : sync.state === "loading" ? "From OPS API · connecting…"
    : sync.state === "offline" ? "OPS API offline · cached data"
    : "From OPS API · updated 10:21";
  const pillLabel = sync.state === "loading" ? "SYNC" : sync.state === "offline" ? "OFFLINE" : "LIVE";
  const pillCls = "apipill" + (sync.state === "offline" ? " apipill--off" : sync.state === "loading" ? " apipill--sync" : "");
  const RENDER_CAP = 60;

  const total = FLIGHTS.length;
  const s = q.trim().toLowerCase();
  let list = s ? FLIGHTS.filter((f) => (f.id + " " + f.reg + " " + f.from + " " + f.to).toLowerCase().includes(s)) : FLIGHTS.slice();
  list.sort((a, b) => {
    const c = String(sortBy === "flt" ? a.id : (a.std || "")).localeCompare(String(sortBy === "flt" ? b.id : (b.std || "")), undefined, { numeric: true });
    return asc ? c : -c;
  });
  const matched = list.length;
  const shown = list.slice(0, RENDER_CAP);

  return (
    <div className="screen-scroll">
      <div className="flights-head">
        <div>
          <h2 className="scr-h2">Flights &amp; Fuel</h2>
          <div className="scr-sub">{subText} · {total} flights</div>
        </div>
        <button className={pillCls} onClick={onRetry} title="Refresh from OPS API"><i className="apipill-dot" />{pillLabel}</button>
      </div>

      <div className="flights-search">
        <div className="searchbar">
          <Ic.search width="18" height="18" />
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search: flight, reg, airport (FD3188, ABA, DMK…)" />
          {q && <button className="iconbtn" onClick={() => setQ("")}><Ic.close width="16" height="16" /></button>}
        </div>
        <div className="chiprow">
          <span className="sort-lbl">Sort</span>
          <Chip mono on={sortBy === "std"} onClick={() => setSortBy("std")}>STD</Chip>
          <Chip mono on={sortBy === "flt"} onClick={() => setSortBy("flt")}>Flight</Chip>
          <Chip mono on={asc} onClick={() => setAsc(true)}>▲ Asc</Chip>
          <Chip mono on={!asc} onClick={() => setAsc(false)}>▼ Desc</Chip>
        </div>
      </div>

      <div className="flights-list">
        {shown.map((f, i) => <FlightCard key={f.id + "_" + i} f={f} variant={variant} onAttach={onAttach} onFuel={onFuel} onAircraft={onAircraft} onStatus={onStatus} />)}
      </div>
      {matched === 0
        ? <div className="empty">No flights match “{q}”</div>
        : <div className="empty">{s ? `Found ${matched} flights · ` : "Sorted by " + (sortBy === "flt" ? "Flight" : "STD") + " · "}showing {shown.length}{matched > shown.length ? ` of ${matched}` : ""}</div>}
      <div className="scroll-pad" />
    </div>
  );
}

/* ============================== PROFILE ============================== */
// One day in the roster (base pattern + any override). Tap to add/edit, × to clear.
function RosterRow({ date, info, isToday, onPick, onRemove }) {
  const wd = date.toLocaleDateString("en-GB", { weekday: "short" });
  const dd = String(date.getDate()).padStart(2, "0");
  const o = info.override;
  return (
    <div className={"rost-row rost-row--" + info.kind + (isToday ? " rost-row--today" : "")} onClick={() => onPick && onPick()} role="button">
      <span className="rost-day"><b>{wd}</b><i className="mono">{dd}</i></span>
      <span className="rost-dot" />
      <span className="rost-main">
        <span className="rost-label">{info.working ? info.label : "Day off"}{isToday && <em className="rost-today-tag">today</em>}</span>
        {info.working && info.hours && <span className="rost-hours mono">{info.hours}</span>}
        {o && o.note && <span className="rost-note">{o.note}</span>}
      </span>
      {o && <span className={"shift-tag shift-tag--" + o.reason}>{SHIFT_REASON[o.reason] || "Edit"}</span>}
      {o && onRemove && <button className="rost-x" onClick={(e) => { e.stopPropagation(); onRemove(); }} aria-label="remove"><Ic.close width="14" height="14" /></button>}
    </div>
  );
}

// Add / change a shift for a date: call-in on an off day, OT, swap, or leave.
function ShiftSheet({ open, onClose, onSave, dateDefault }) {
  const [date, setDate] = useStateM(dateDefault || "");
  const [reason, setReason] = useStateM("callin");
  const [kind, setKind] = useStateM("morning");
  const [hours, setHours] = useStateM(SHIFT_HOURS.morning);
  const [note, setNote] = useStateM("");
  React.useEffect(() => { if (open) { setDate(dateDefault || ""); setReason("callin"); setKind("morning"); setHours(SHIFT_HOURS.morning); setNote(""); } }, [open, dateDefault]);
  const isLeave = reason === "leave";
  const pickKind = (k) => { setKind(k); setHours(SHIFT_HOURS[k] || ""); };
  const save = () => {
    if (!date) return;
    const effKind = isLeave ? "off" : kind;
    onSave && onSave({ date, kind: effKind, reason, hours: effKind === "off" ? "" : hours, note: note.trim() });
    onClose();
  };
  const REASONS = [["callin", "Call-in · วันหยุด"], ["ot", "OT"], ["swap", "Swap · แลกกะ"], ["leave", "Leave · ลา"]];
  return (
    <Sheet open={open} onClose={onClose} title="Add shift / change">
      <p className="sheet-lead">โดนเรียกทำวันหยุด · OT · แลกกะ · หรือวันลา — จะไปแทนกะปกติของวันนั้นในตาราง</p>
      <Field label="Date"><input type="date" className="inp inp--mono" value={date} onChange={(e) => setDate(e.target.value)} /></Field>
      <div className="field">
        <span className="field-label">Type</span>
        <div className="chiprow wrap">{REASONS.map(([k, l]) => <Chip key={k} on={reason === k} onClick={() => setReason(k)}>{l}</Chip>)}</div>
      </div>
      {!isLeave && (
        <>
          <div className="field">
            <span className="field-label">Shift</span>
            <div className="chiprow wrap">{["morning", "night"].map((k) => <Chip key={k} on={kind === k} onClick={() => pickKind(k)}>{SHIFT_LABEL[k]}</Chip>)}</div>
          </div>
          <Field label="Hours"><input className="inp inp--mono" value={hours} onChange={(e) => setHours(e.target.value)} placeholder="08:00–20:00" /></Field>
        </>
      )}
      <Field label="Note (optional)"><input className="inp" value={note} onChange={(e) => setNote(e.target.value)} placeholder="เช่น แลกกับพี่ A / เรียกด่วน" /></Field>
      <Btn full kind="primary" onClick={save} icon={<Ic.check width="18" height="18" />}>Save to roster</Btn>
    </Sheet>
  );
}

// Month calendar of the shift roster (base 4-on/4-off pattern + overrides).
// Tap a day to select it; the detail bar below adds/edits/clears that day.
function ShiftCalendar({ shifts, onPick, onRemove }) {
  const today = new Date();
  const todayISO = shiftISO(today);
  const [ym, setYm] = useStateM({ y: today.getFullYear(), m: today.getMonth() });
  const [selISO, setSelISO] = useStateM(todayISO);
  const first = new Date(ym.y, ym.m, 1);
  const dim = new Date(ym.y, ym.m + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < first.getDay(); i++) cells.push(null);
  for (let d = 1; d <= dim; d++) cells.push(new Date(ym.y, ym.m, d));
  while (cells.length % 7) cells.push(null);
  const monthLbl = first.toLocaleDateString("en-GB", { month: "long", year: "numeric" });
  const step = (n) => setYm((s) => { let m = s.m + n, y = s.y; if (m < 0) { m = 11; y--; } if (m > 11) { m = 0; y++; } return { y, m }; });
  const goToday = () => { setYm({ y: today.getFullYear(), m: today.getMonth() }); setSelISO(todayISO); };
  const selDate = (() => { const [y, m, d] = selISO.split("-").map(Number); return new Date(y, m - 1, d); })();
  const selInfo = effectiveShift(selDate, shifts);
  const selOv = selInfo.override;
  return (
    <Card className="cal">
      <div className="cal-head">
        <button className="cal-nav" onClick={() => step(-1)} aria-label="previous month"><Ic.back width="18" height="18" /></button>
        <button className="cal-title" onClick={goToday}>{monthLbl}</button>
        <button className="cal-nav" onClick={() => step(1)} aria-label="next month"><Ic.chevron width="18" height="18" /></button>
      </div>
      <div className="cal-wd">{["S", "M", "T", "W", "T", "F", "S"].map((w, i) => <span key={i}>{w}</span>)}</div>
      <div className="cal-grid">
        {cells.map((d, i) => {
          if (!d) return <span key={i} className="cal-cell cal-cell--empty" />;
          const iso = shiftISO(d);
          const info = effectiveShift(d, shifts);
          return (
            <button key={i} className={"cal-cell cal-cell--" + info.kind + (iso === todayISO ? " cal-cell--today" : "") + (iso === selISO ? " cal-cell--sel" : "")} onClick={() => setSelISO(iso)}>
              <span className="cal-num">{d.getDate()}</span>
              {info.working && <span className="cal-bar" />}
              {info.override && <i className={"cal-ov cal-ov--" + info.override.reason} />}
            </button>
          );
        })}
      </div>
      <div className="cal-legend">
        <span><i className="lg lg--m" />Morning</span>
        <span><i className="lg lg--n" />Night</span>
        <span><i className="lg lg--o" />Off</span>
        <span className="cal-legend-hint">tap a day →</span>
      </div>
      <div className={"cal-sel cal-sel--" + selInfo.kind}>
        <div className="cal-sel-l">
          <span className="cal-sel-date">{selDate.toLocaleDateString("en-GB", { weekday: "long", day: "2-digit", month: "short" })}{selISO === todayISO ? " · today" : ""}</span>
          <span className="cal-sel-shift"><i className="cal-sel-dot" />{selInfo.working ? `${selInfo.label} · ${selInfo.hours}` : "Day off"}{selOv && <em className={"shift-tag shift-tag--" + selOv.reason}>{SHIFT_REASON[selOv.reason]}</em>}</span>
          {selOv && selOv.note && <span className="cal-sel-note">{selOv.note}</span>}
        </div>
        <div className="cal-sel-actions">
          <button className="cal-selbtn" onClick={() => onPick(selISO)}>{selOv ? "Edit" : "+ Add"}</button>
          {selOv && onRemove && <button className="cal-selbtn--clear" onClick={() => onRemove(selISO)}>Clear</button>}
        </div>
      </div>
    </Card>
  );
}

function ProfileScreen({ t, logCount = 0, onReset, shifts = {}, onAddShift, onRemoveShift, profile, onLock, onSignOut }) {
  const [shiftOpen, setShiftOpen] = useStateM(false);
  const today = new Date();
  const todayISO = shiftISO(today);
  const [sheetDate, setSheetDate] = useStateM(todayISO);
  const openAdd = (iso) => { setSheetDate(iso || todayISO); setShiftOpen(true); };
  const me = profile || {};
  return (
    <div className="screen-scroll">
      <div className="prof-hero">
        <div className="avatar avatar--lg">{initials(me.name)}</div>
        <div><div className="prof-name">{me.name || "Technician"}</div>{(me.authz || me.station) && <div className="prof-role">{me.authz || me.station}</div>}</div>
      </div>

      <div className="block">
        <div className="block-head"><span>My shift roster</span><button className="link" onClick={() => openAdd(todayISO)}><Ic.plus width="15" height="15" />Add</button></div>
        <div className="rost-sum">4-on / 4-off · 2 morning, 2 night · <span className="mono">{SHIFT_HOURS.morning}</span> / <span className="mono">{SHIFT_HOURS.night}</span></div>
        <ShiftCalendar shifts={shifts} onPick={openAdd} onRemove={onRemoveShift} />
        <p className="prof-note">แตะวันในปฏิทินเพื่อเลือก · ปุ่ม +Add / Edit เพื่อเพิ่มกะ (เรียกทำวันหยุด · OT · แลกกะ · ลา) · กะปกติคำนวณจากรอบ 4-on/4-off อัตโนมัติ</p>
      </div>
      <div className="block">
        <div className="block-head"><span>Technician info</span></div>
        <Card><KV k="License" v={me.license || "—"} mono /><KV k="Employee" v={me.emp || "—"} mono /><KV k="Station" v={me.station || "—"} /><KV k="Authorizations" v={me.authz || "—"} /></Card>
      </div>
      <div className="block">
        <div className="block-head"><span>Local data</span><span className="mono" style={{ color: "var(--ink-soft)", fontSize: 11 }}>{logCount} logs stored</span></div>
        <Card className="settings">
          <div className="set-row"><span>Logs saved on this device</span><span className="mono">{logCount}</span></div>
          <button className="set-row set-row--btn" onClick={onReset}><span>Clear local logs</span><span className="set-danger">Reset</span></button>
        </Card>
        <p className="prof-note">บันทึกทั้งหมดเก็บในเครื่อง (localStorage) — เปิดใหม่ยังอยู่ · ปุ่ม Reset จะลบ log ที่บันทึกไว้และกลับเป็นตัวอย่าง</p>
      </div>
      <div className="block">
        <div className="block-head"><span>Account</span><span className="mono" style={{ color: "var(--ink-soft)", fontSize: 11 }}>PIN lock · this device</span></div>
        <Card className="settings">
          <button className="set-row set-row--btn" onClick={onLock}><span>Lock app now</span><span className="acc-act">Lock</span></button>
          <button className="set-row set-row--btn" onClick={onSignOut}><span>Sign out (clear profile + PIN)</span><span className="set-danger">Sign out</span></button>
        </Card>
        <p className="prof-note">PIN เก็บแบบเข้ารหัส (hash) ในเครื่องนี้ · เป็นการล็อกเครื่อง ไม่ใช่บัญชี cloud — ภายหลังอัปเป็นบัญชีจริง + sync ได้</p>
      </div>
      <div className="scroll-pad" />
      <ShiftSheet open={shiftOpen} onClose={() => setShiftOpen(false)} onSave={onAddShift} dateDefault={sheetDate} />
    </div>
  );
}

/* ============================== LOG DETAIL ============================== */
function LogDetail({ log, onBack, onEdit }) {
  const parts = log.parts || [];
  return (
    <div className="screen-scroll detail">
      <TopBar title={log.id} sub={log.title} onBack={onBack} right={<>{onEdit && <button className="iconbtn" onClick={onEdit} aria-label="edit"><Ic.edit width="19" height="19" /></button>}<StatusDot status={log.status} /></>} />
      <div className="detail-body">
        <div className="detail-top">
          <AtaBadge code={log.ata} big />
          <div className="detail-title">{log.title}</div>
          <div className="detail-th">{log.th}</div>
          <div className="detail-meta mono">{log.reg} · {log.start}–{log.stop} ({log.dur}){log.flight && " · " + log.flight}</div>
        </div>
        <Section title="Defect"><p className="para">{log.defect}</p></Section>
        <Section title="Action taken"><p className="para">{log.action}</p>
          {(Array.isArray(log.amm) ? log.amm : (log.amm && log.amm !== "—" ? [log.amm] : [])).map((x, i) => (
            <div key={i} className="amm mono"><Ic.doc width="14" height="14" />AMM {x}</div>
          ))}
        </Section>
        {parts.length > 0 && <Section title="Parts">{parts.map((p, i) => (<div key={i} className="partrow"><Ic.part width="18" height="18" /><div><div className="mono partpn">{p.pn}</div><div className="partoff mono">OFF {p.off} → ON {p.on}</div></div></div>))}</Section>}
        {log.tools?.length > 0 && <Section title="Tools / Equipment"><div className="chiprow wrap">{log.tools.map((id) => { const tl = TOOL_LIB.find((x) => x.id === id); return <span key={id} className="chip chip--static chip--mono"><Ic.tool width="13" height="13" />{tl ? tl.name : id}</span>; })}</div></Section>}
        {log.consumables && <Section title="Consumables / Other"><p className="para">{log.consumables}</p></Section>}
        {log.cb?.length > 0 && <Section title="C/B"><div className="chiprow wrap">{log.cb.map((id) => <span key={id} className="chip chip--static chip--mono"><Ic.cb width="13" height="13" />{id}</span>)}</div></Section>}
        {photoCount(log.photos) > 0 && <Section title={`Photos (${photoCount(log.photos)})`}><div className="photogrid">{photoArr(log.photos).length ? photoArr(log.photos).map((src, i) => <a key={i} className="photo-thumb photo-thumb--img" href={src} target="_blank" rel="noreferrer"><img src={src} alt={"photo " + (i + 1)} /></a>) : Array.from({ length: photoCount(log.photos) }).map((_, i) => <div key={i} className="photo-thumb"><Ic.camera width="20" height="20" /></div>)}</div></Section>}
      </div>
      <div className="scroll-pad" />
    </div>
  );
}
function Section({ title, children }) {
  return <div className="dsec"><div className="dsec-h">{title}</div>{children}</div>;
}

Object.assign(window, { TodayScreen, LogsScreen, FlightsScreen, FlightActions, FlightCard, FlightStatus, FlightStatusSheet, AssignSheet, OpBadge, PaxBar, ProfileScreen, RosterRow, ShiftSheet, ShiftCalendar, LogDetail, fuelLitres });
