/* SkyOps — Field app (technician, mobile, offline-first).
   Task inbox = work orders assigned to the technician · execute with checklist, photos, parts swap, measurements, signature ·
   field observations (source FIELD_REPORT) · offline queue that syncs back into Work orders / Alerts / Warranty. */

const { useState: uSFA, useEffect: uEFA } = React;

const FA_TODAY = "2026-04-17";
const faQ = {
  v: (() => { try { return JSON.parse(localStorage.getItem("skyops_field_v1") || "null") || { queue: [], obs: [], online: true, lastSync: "2026-04-17 07:58" }; } catch { return { queue: [], obs: [], online: true, lastSync: "—" }; } })(),
  subs: new Set(),
  set(fn) { this.v = fn(this.v); try { localStorage.setItem("skyops_field_v1", JSON.stringify(this.v)); } catch {} this.subs.forEach(s => s(this.v)); },
};
function useFA() { const [v, setV] = uSFA(faQ.v); uEFA(() => { faQ.subs.add(setV); return () => faQ.subs.delete(setV); }, []); return v; }
const faNow = () => { const d = new Date(); return `${FA_TODAY} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`; };

function faApply(item) {
  if (item.kind === "wo") window.woStore.set(l => l.map(w => w.id === item.id ? { ...w, ...item.patch } : w));
  if (item.kind === "obs") faQ.set(v => ({ ...v, obs: [{ ...item.obs, synced: true }, ...v.obs.filter(o => o.id !== item.obs.id)] }));
}
function faPush(item) {
  if (faQ.v.online) { faApply(item); faQ.set(v => ({ ...v, lastSync: faNow() })); }
  else faQ.set(v => ({ ...v, queue: [...v.queue, { ...item, at: faNow() }], ...(item.kind === "obs" ? { obs: [{ ...item.obs, synced: false }, ...v.obs] } : {}) }));
}
function faSync() { const q = faQ.v.queue; q.forEach(faApply); faQ.set(v => ({ ...v, queue: [], lastSync: faNow() })); }

const FA_STEPS = {
  "Electrical": ["LOTO · isolate & lock out", "Verify zero voltage", "Test string fuses", "Re-energize", "IV curve trace"],
  "Module replace": ["LOTO · isolate string", "Remove faulty module", "Install spare & torque clamps", "Re-energize", "Thermal spot-check"],
  "Cleaning": ["Confirm wash window", "Wash sector", "Spot-check soiling index"],
  "Vegetation": ["Clear vegetation", "Remove cuttings"],
  "Tracker": ["Read TCU fault code", "Reset / replace actuator", "Verify tracking angle"],
};

function FieldPage({ go }) {
  const v = useFA();
  const wos = window.useWOs ? window.useWOs() : [];
  const crew = (window.resStore?.data.people || []).filter(p => !p.skills.every(s => s === "Pilot" || s === "Thermography" || s === "Review"));
  const [tech, setTech] = uSFA(() => localStorage.getItem("skyops_field_tech") || "");
  const [tab, setTab] = uSFA("tasks");
  const [open, setOpen] = uSFA(null);
  uEFA(() => { tech && localStorage.setItem("skyops_field_tech", tech); }, [tech]);
  const me = crew.find(p => p.name === tech);
  const mine = me ? wos.filter(w => (w.assignee || "").startsWith(me.name)) : [];
  const todo = mine.filter(w => !["done", "verified"].includes(w.status));
  const cur = open && wos.find(w => w.id === open);

  return (
    <div className="page fa-page">
      <div className="page-head">
        <div className="title"><div className="kicker">Operate · field technician · mobile</div><h1>Field app</h1>
          <div className="sub">What the technician sees on site. Works offline; everything syncs back into work orders, alerts and warranty claims.</div></div>
      </div>
      <div className="fa-wrap">
        <div className="fa-phone">
          <div className="fa-status"><span className="mono">09:41</span><span className="grow"/>
            <button className={`fa-net ${v.online ? "on" : ""}`} onClick={() => faQ.set(x => ({ ...x, online: !x.online }))}><i/>{v.online ? "Online" : "Offline"}</button></div>
          {!me ? <FaLogin crew={crew} setTech={setTech}/> : cur ? <FaTask w={cur} me={me} back={() => setOpen(null)} online={v.online}/> : <>
            <div className="fa-top"><div><span className="fa-hi">{me.name}</span><span className="fa-sub">{me.role} · {me.org}</span></div><button className="fa-ic" onClick={() => setTech("")} aria-label="Switch user"><Icon name="users" size={16}/></button></div>
            {!v.online && <div className="fa-off"><Icon name="alert" size={13}/>Offline · {v.queue.length} change{v.queue.length === 1 ? "" : "s"} waiting to sync</div>}
            <div className="fa-body">
              {tab === "tasks" && <FaTasks todo={todo} done={mine.filter(w => ["done", "verified"].includes(w.status))} setOpen={setOpen}/>}
              {tab === "report" && <FaReport me={me} done={() => setTab("sync")}/>}
              {tab === "sync" && <FaSyncTab v={v}/>}
            </div>
            <nav className="fa-tabs">{[["tasks", "Tasks", "flag", todo.length], ["report", "Report", "plus", null], ["sync", "Sync", "refresh", v.queue.length || null]].map(([k, l, ic, n]) => (
              <button key={k} className={tab === k ? "on" : ""} onClick={() => setTab(k)}><span className="fa-tab-ic"><Icon name={ic} size={18}/>{n ? <em>{n}</em> : null}</span>{l}</button>))}</nav>
          </>}
        </div>
        <aside className="fa-side card">
          <div className="card-hd">Back-office link<span className="sub">what each field action updates</span></div>
          <div className="fa-side-b">
            {[["Complete task", "Work order → Done · verified by the next inspection", "flag"], ["Parts swap", "Removed serial added to the warranty claim evidence", "shield"], ["Field report", "New observation · source FIELD_REPORT · raises an alert", "bell"], ["Offline", "Changes queue on the device and sync when back online", "refresh"]].map(([a, b, ic]) => (
              <div key={a} className="fa-side-it"><Icon name={ic} size={13}/><div><b>{a}</b><span>{b}</span></div></div>))}
            <div className="caps" style={{ marginTop: 6 }}>Sync status</div>
            <div className="ps-kv"><span>Device</span><b>{v.online ? "Online" : "Offline"}</b></div>
            <div className="ps-kv"><span>Pending changes</span><b className="mono">{v.queue.length}</b></div>
            <div className="ps-kv"><span>Last sync</span><b className="mono">{v.lastSync}</b></div>
            <div className="ps-kv"><span>Field reports</span><b className="mono">{v.obs.length}</b></div>
            <button className="btn btn-secondary btn-xs" onClick={() => go("workorders")}>Open work orders<Icon name="arrow_right" size={11}/></button>
          </div>
        </aside>
      </div>
    </div>
  );
}

function FaLogin({ crew, setTech }) {
  return (<div className="fa-body fa-login">
    <div className="fa-logo">SK</div><h3>Sign in</h3><p>Choose your profile. Your tasks are downloaded for offline use.</p>
    {crew.map(p => <button key={p.id} className="fa-user" onClick={() => setTech(p.name)}><span className="fa-av">{p.name.split(" ").map(x => x[0]).join("")}</span><span><b>{p.name}</b><em>{p.role} · {p.org}</em></span><Icon name="arrow_right" size={14}/></button>)}
  </div>);
}

function FaTasks({ todo, done, setOpen }) {
  const site = (id) => (window.SITES || []).find(s => s.id === id);
  const over = todo.filter(w => w.due && w.due < FA_TODAY), rest = todo.filter(w => !(w.due && w.due < FA_TODAY));
  const Card = ({ w }) => (
    <button className="fa-card" onClick={() => setOpen(w.id)}>
      <div className="fa-card-hd"><span className={`wo-prio wo-prio-${w.prio}`}>{w.prio}</span><span className="mono fa-muted">{w.id}</span><span className="grow"/><span className={`fa-chip fa-chip-${w.status}`}>{w.status.replace("_", " ")}</span></div>
      <b>{w.title}</b>
      <span className="fa-muted"><Icon name="map" size={11}/> {site(w.siteId)?.name} · {w.loc}</span>
      <span className={`fa-muted ${w.due < FA_TODAY ? "fa-late" : ""}`}><Icon name="calendar" size={11}/> due {w.due} · {(w.checklist || []).filter(c => c[1]).length}/{(w.checklist || []).length} steps</span>
    </button>);
  return (<>
    {over.length > 0 && <><div className="fa-sec fa-late">Overdue · {over.length}</div>{over.map(w => <Card key={w.id} w={w}/>)}</>}
    <div className="fa-sec">Assigned · {rest.length}</div>{rest.map(w => <Card key={w.id} w={w}/>)}
    {todo.length === 0 && <div className="fa-empty"><Icon name="check_circle" size={22}/>No open tasks. New work orders appear here when assigned to you.</div>}
    {done.length > 0 && <><div className="fa-sec">Completed · {done.length}</div>{done.map(w => <Card key={w.id} w={w}/>)}</>}
  </>);
}

function FaTask({ w, me, back, online }) {
  const site = (window.SITES || []).find(s => s.id === w.siteId);
  const det = (window.DETECTIONS || []).find(d => d.id === w.obs);
  const steps = (w.checklist && w.checklist.length ? w.checklist.map(c => c[0]) : null) || FA_STEPS[w.type] || ["Execute task", "Photo evidence"];
  const fr = w.fieldReport || {};
  const [chk, setChk] = uSFA(() => w.checklist && w.checklist.length ? w.checklist.map(c => c[1]) : steps.map(() => false));
  const [ph, setPh] = uSFA(fr.photos || { before: null, after: null });
  const [part, setPart] = uSFA(fr.part || { out: det ? det.module.replace("MOD", "LRP2311") : "", in: "" });
  const [ms, setMs] = uSFA(fr.measures || { voc: "", isc: "", ins: "" });
  const [note, setNote] = uSFA(fr.note || "");
  const [sig, setSig] = uSFA(!!fr.signedBy);
  const isSwap = w.type === "Module replace", isElec = w.type === "Electrical" || isSwap;
  const ready = chk.every(Boolean) && ph.before && ph.after && sig && (!isSwap || (part.out && part.in));
  const closed = ["done", "verified"].includes(w.status);
  const save = (status) => faPush({ kind: "wo", id: w.id, patch: { status, checklist: steps.map((s, i) => [s, chk[i]]), fieldReport: { photos: ph, part: isSwap ? part : null, measures: isElec ? ms : null, note, signedBy: sig ? me.name : null, completedAt: status === "done" ? faNow() : null } } });
  const shot = (k) => setPh(p => ({ ...p, [k]: faNow().slice(11) }));
  return (<>
    <div className="fa-top"><button className="fa-ic" onClick={back} aria-label="Back"><Icon name="chevron_left" size={18}/></button><div><span className="fa-hi">{w.id}</span><span className="fa-sub">{site?.name}</span></div><span className={`fa-chip fa-chip-${w.status}`}>{w.status.replace("_", " ")}</span></div>
    <div className="fa-body">
      <h3 className="fa-t">{w.title}</h3>
      <div className="fa-loc"><Icon name="map" size={13}/><span>{w.loc}</span><button className="fa-nav">Navigate</button></div>
      {det && <div className="fa-det"><span className="fa-th" style={{ background: `radial-gradient(circle at 60% 40%, #fde68a, #ef4444 25%, #7c2d12 45%, #1e3a5f 70%)` }}/><div><b>{det.label} · ΔT +{det.dT.toFixed(1)} °C</b><span className="fa-meta mono">{`${det.id} · ${det.module} · ${det.string}`}</span></div></div>}
      <div className="fa-core"><span className="core-mark sm"><i/>Argus</span><span>{w.type === "Electrical" ? "Most likely cause: blown string fuse (81% of similar cases). Check fuse F2 first." : w.type === "Module replace" ? "Spare in van 2 matches model. Record both serials — they feed the warranty claim." : w.type === "Tracker" ? "TCU-B fault E-114 → actuator limit switch. Bring spare LS-40." : "Follow steps; photos are checked for completeness on upload."}</span></div>
      <div className="fa-sec">Steps</div>
      {steps.map((s, i) => <label key={s} className={`fa-step ${chk[i] ? "on" : ""}`}><input type="checkbox" checked={chk[i]} disabled={closed} onChange={() => setChk(c => c.map((x, j) => j === i ? !x : x))}/><i>{chk[i] ? <Icon name="check" size={12}/> : i + 1}</i><span>{s}</span></label>)}
      <div className="fa-sec">Photos</div>
      <div className="fa-photos">{[["before", "Before"], ["after", "After"]].map(([k, l]) => (
        <button key={k} className={`fa-ph ${ph[k] ? "on" : ""}`} disabled={closed} onClick={() => shot(k)}>{ph[k] ? <><Icon name="check_circle" size={16}/><span>{l} · {ph[k]}</span><em>GPS tagged</em></> : <><Icon name="camera" size={18}/><span>{l} photo</span></>}</button>))}</div>
      {isSwap && <><div className="fa-sec">Module swap · warranty evidence</div>
        <label className="fa-f"><span>Removed serial</span><input className="inp mono" value={part.out} disabled={closed} onChange={e => setPart(p => ({ ...p, out: e.target.value }))}/></label>
        <label className="fa-f"><span>Installed serial</span><div className="fa-scan"><input className="inp mono" value={part.in} disabled={closed} onChange={e => setPart(p => ({ ...p, in: e.target.value }))} placeholder="Scan barcode"/><button className="fa-ic" disabled={closed} onClick={() => setPart(p => ({ ...p, in: "LRP2402-" + (4000 + Math.floor(Math.random() * 5000)) + "-0" + (100 + Math.floor(Math.random() * 800)) }))}><Icon name="crosshair" size={16}/></button></div></label></>}
      {isElec && <><div className="fa-sec">Measurements</div>
        <div className="fa-ms">{[["voc", "Voc", "V"], ["isc", "Isc", "A"], ["ins", "Insulation", "MΩ"]].map(([k, l, u]) => <label key={k} className="fa-f"><span>{l} ({u})</span><input className="inp mono" inputMode="decimal" value={ms[k]} disabled={closed} onChange={e => setMs(m => ({ ...m, [k]: e.target.value }))}/></label>)}</div></>}
      <div className="fa-sec">Notes</div>
      <textarea className="inp fa-note" rows={3} value={note} disabled={closed} onChange={e => setNote(e.target.value)} placeholder="What you found, what you did"/>
      <label className={`fa-sig ${sig ? "on" : ""}`}><input type="checkbox" checked={sig} disabled={closed} onChange={e => setSig(e.target.checked)}/><span>{sig ? `Signed · ${me.name}` : "Tap to sign off — I confirm the work is complete and the site is safe"}</span></label>
    </div>
    {!closed && <div className="fa-act">
      <button className="fa-btn ghost" onClick={() => { save("in_progress"); back(); }}>Save progress</button>
      <button className="fa-btn" disabled={!ready} onClick={() => { save("done"); back(); }}>{online ? "Complete task" : "Complete · sync later"}</button>
    </div>}
    {closed && <div className="fa-act"><div className="fa-done"><Icon name="check_circle" size={14}/>Completed{fr.completedAt ? " · " + fr.completedAt : ""} — verified by {w.verifyMic || "next inspection"}</div></div>}
  </>);
}

function FaReport({ me, done }) {
  const sites = window.SITES || [];
  const kinds = Object.entries(window.ANOMALY_CLASS || {});
  const [f, setF] = uSFA({ siteId: sites.find(s => s.id === "pt-ev-03") ? "pt-ev-03" : sites[0]?.id, kind: "soiling", sev: "medium", loc: "", note: "", photo: false });
  const submit = () => {
    const id = `FR-${String(Date.now()).slice(-6)}`;
    faPush({ kind: "obs", obs: { id, ...f, label: window.ANOMALY_CLASS[f.kind]?.label, by: me.name, at: faNow(), source: "FIELD_REPORT" } });
    done();
  };
  return (<>
    <h3 className="fa-t">New field report</h3>
    <p className="fa-muted" style={{ margin: "0 0 6px" }}>Something the drone can't see — or saw between flights. Becomes an observation with source FIELD_REPORT.</p>
    <label className="fa-f"><span>Site</span><select className="sel" value={f.siteId} onChange={e => setF(x => ({ ...x, siteId: e.target.value }))}>{sites.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}</select></label>
    <label className="fa-f"><span>Type</span><select className="sel" value={f.kind} onChange={e => setF(x => ({ ...x, kind: e.target.value }))}>{["MODULE", "STRING", "OBSTRUCTION", "MOUNTING"].map(g => <optgroup key={g} label={g}>{kinds.filter(([, c]) => c.group === g).map(([k, c]) => <option key={k} value={k}>{c.label}</option>)}</optgroup>)}</select></label>
    <div className="fa-f"><span>Severity</span><div className="fa-seg">{["critical", "high", "medium", "low"].map(s => <button key={s} className={f.sev === s ? `on s-${s}` : ""} onClick={() => setF(x => ({ ...x, sev: s }))}>{s}</button>)}</div></div>
    <label className="fa-f"><span>Location</span><div className="fa-scan"><input className="inp" value={f.loc} onChange={e => setF(x => ({ ...x, loc: e.target.value }))} placeholder="Row, table or module ID"/><button className="fa-ic" onClick={() => setF(x => ({ ...x, loc: "GPS 38.5734, −7.9121 · row 14" }))}><Icon name="crosshair" size={16}/></button></div></label>
    <button className={`fa-ph wide ${f.photo ? "on" : ""}`} onClick={() => setF(x => ({ ...x, photo: true }))}>{f.photo ? <><Icon name="check_circle" size={16}/><span>Photo attached</span></> : <><Icon name="camera" size={18}/><span>Take photo</span></>}</button>
    <label className="fa-f"><span>Note</span><textarea className="inp fa-note" rows={3} value={f.note} onChange={e => setF(x => ({ ...x, note: e.target.value }))}/></label>
    <button className="fa-btn" disabled={!f.loc || !f.photo} onClick={submit}>Submit report</button>
  </>);
}

function FaSyncTab({ v }) {
  return (<>
    <h3 className="fa-t">Sync</h3>
    <div className="fa-syncbox"><div><b>{v.online ? "Online" : "Offline"}</b><span className="fa-muted">Last sync {v.lastSync}</span></div><button className="fa-btn" disabled={!v.online || !v.queue.length} onClick={faSync}>Sync now</button></div>
    <div className="fa-sec">Waiting to upload · {v.queue.length}</div>
    {v.queue.map((q, i) => <div key={i} className="fa-qi"><Icon name={q.kind === "wo" ? "flag" : "plus"} size={13}/><span>{q.kind === "wo" ? `${q.id} → ${q.patch.status.replace("_", " ")}` : `Field report · ${q.obs.label}`}</span><em className="mono">{q.at.slice(11)}</em></div>)}
    {v.queue.length === 0 && <div className="fa-muted" style={{ fontSize: 12 }}>Everything is uploaded.</div>}
    <div className="fa-sec">My field reports · {v.obs.length}</div>
    {v.obs.map(o => <div key={o.id} className="fa-qi"><span className={`al-sev al-sev-${o.sev}`}/><span>{o.label} · {o.loc}</span><em>{o.synced ? "synced" : "pending"}</em></div>)}
  </>);
}

Object.assign(window, { FieldPage, faQ });
