/* SkyOps — Inspection lifecycle close-out: review finalisation → report sign-off & delivery → archive,
   plus real file exports (report PDF, flight plan KML / DJI WPML). */

const { useState: uSLC } = React;

function skyDownload(name, content, type) {
  const blob = content instanceof Blob ? content : new Blob([content], { type: type || "text/plain" });
  const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = name;
  document.body.appendChild(a); a.click(); setTimeout(() => { URL.revokeObjectURL(a.href); a.remove(); }, 500);
}
function skyToast(msg) { window.dispatchEvent(new CustomEvent("skyops:toast", { detail: msg })); }

/* Minimal single-page PDF (Helvetica text lines) */
function skyPdf(lines) {
  const esc = (s) => String(s).replace(/[\\()]/g, (m) => "\\" + m).replace(/[^\x20-\x7E]/g, (c) => ({ "°": " deg", "€": "EUR ", "·": "-", "—": "-", "–": "-", "→": "->", "ç": "c", "ã": "a", "á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u", "ñ": "n", "Ó": "O", "É": "E" }[c] || ""));
  let y = 800; const ops = lines.map(([t, sz = 10, b]) => { const s = `BT /${b ? "F2" : "F1"} ${sz} Tf 50 ${y} Td (${esc(t)}) Tj ET`; y -= sz + 8; return s; }).join("\n");
  const objs = ["<< /Type /Catalog /Pages 2 0 R >>", "<< /Type /Pages /Kids [3 0 R] /Count 1 >>", "<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Contents 4 0 R /Resources << /Font << /F1 5 0 R /F2 6 0 R >> >> >>", `<< /Length ${ops.length} >>\nstream\n${ops}\nendstream`, "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>", "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>"];
  let out = "%PDF-1.4\n", offs = [];
  objs.forEach((o, i) => { offs.push(out.length); out += `${i + 1} 0 obj\n${o}\nendobj\n`; });
  const x = out.length; out += `xref\n0 ${objs.length + 1}\n0000000000 65535 f \n` + offs.map(o => String(o).padStart(10, "0") + " 00000 n \n").join("") + `trailer\n<< /Size ${objs.length + 1} /Root 1 0 R >>\nstartxref\n${x}\n%%EOF`;
  return new Blob([out], { type: "application/pdf" });
}
function reportPdf(mic, site, zones) {
  const ready = zones.filter(z => z.status === "ready");
  const c = ready.map(z => window.zrGet(mic.id, z.id).counts);
  const sum = (k) => c.reduce((a, x) => a + (x[k] || 0), 0);
  return skyPdf([
    [`${site.name} - ${mic.cycle} inspection report`, 18, true], [`${mic.id} - IEC TS 62446-3 aerial thermography - issued ${window.SKY_TODAY}`, 9],
    ["", 6], ["Executive summary", 13, true],
    [`${ready.length} of ${zones.length} zones reported - ${(mic.coverage || 0)}% coverage - ${(mic.detections || 0).toLocaleString("en-US")} observations`, 10],
    [`Class of abnormality: CoA 3 (critical) ${sum("cls3")} - CoA 2 ${sum("cls2")} - CoA 1 ${sum("cls1")}`, 10],
    [`Cleaning required: ${sum("soiled")} modules`, 10],
    ["", 6], ["Zones", 13, true],
    ...ready.map((z, i) => [`${z.id}  ${z.name || ""}   CoA3 ${c[i].cls3 || 0}   CoA2 ${c[i].cls2 || 0}   soiled ${c[i].soiled || 0}`, 10]),
    ["", 6], ["Capture conditions", 13, true], ["Irradiance >= 600 W/m2 - wind < 4 m/s - emissivity 0.85 - radiometric LWIR 640x512", 10],
    ["", 6], [`Signed off by: ${mic.signoff?.by || "-"}  ${mic.signoff?.at || ""}`, 10], ["Generated by SkyOps", 8],
  ]);
}

/* Flight plan exports from the planner's AOI/waypoints */
function fpCoords(poly, wps, prof) {
  if (wps && wps.length && wps[0].lat) return wps.map(w => [w.lng, w.lat]);
  const lat0 = +(prof?.lat || 38.5912), lng0 = +(prof?.lng || -7.8834);
  return (poly || []).map(([x, y]) => [+(lng0 + (x - 500) * 1.2e-5).toFixed(6), +(lat0 - (y - 280) * 0.9e-5).toFixed(6)]);
}
function fpKml(name, coords, alt) {
  const ring = [...coords, coords[0]].map(([lng, lat]) => `${lng},${lat},${alt}`).join(" ");
  return `<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2"><Document><name>${name}</name>\n<Placemark><name>AOI</name><Polygon><altitudeMode>relativeToGround</altitudeMode><outerBoundaryIs><LinearRing><coordinates>${ring}</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>\n</Document></kml>\n`;
}
function fpWpml(name, coords, alt, speed) {
  const pts = coords.map(([lng, lat], i) => `  <Placemark><Point><coordinates>${lng},${lat}</coordinates></Point><wpml:index>${i}</wpml:index><wpml:executeHeight>${alt}</wpml:executeHeight><wpml:waypointSpeed>${speed}</wpml:waypointSpeed>${i ? "<wpml:actionGroup><wpml:action><wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc></wpml:action></wpml:actionGroup>" : ""}</Placemark>`).join("\n");
  return `<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.2"><Document>\n  <wpml:missionConfig><wpml:flyToWaylineMode>safely</wpml:flyToWaylineMode><wpml:finishAction>goHome</wpml:finishAction><wpml:droneInfo><wpml:droneEnumValue>89</wpml:droneEnumValue></wpml:droneInfo><wpml:payloadInfo><wpml:payloadEnumValue>82</wpml:payloadEnumValue></wpml:payloadInfo></wpml:missionConfig>\n  <Folder><wpml:templateId>0</wpml:templateId><wpml:executeHeightMode>relativeToStartPoint</wpml:executeHeightMode><wpml:autoFlightSpeed>${speed}</wpml:autoFlightSpeed>\n${pts}\n  </Folder>\n</Document></kml>\n`;
}

/* ── Report delivery ──────────────────────────────────────────── */
function DeliverModal({ mic, site, zones, onClose, onDone }) {
  const team = (() => { try { return JSON.parse(localStorage.getItem("skyops_site_team_v1") || "{}")[site.id] || {}; } catch { return {}; } })();
  const [to, setTo] = uSLC([`${(team.owner || "E. Vasconcelos")} · asset owner`, `${team.manager || "M. Rivera"} · site manager`]);
  const [extra, setExtra] = uSLC("");
  const [fmt, setFmt] = uSLC({ pdf: true, portal: true, csv: true, ir: false });
  const [msg, setMsg] = uSLC(`Please find the ${mic.cycle} inspection report for ${site.name}. Critical findings have work orders open; details in the portal.`);
  const [ok, setOk] = uSLC(false);
  const ready = zones.filter(z => z.status === "ready").length;
  const partial = ready < zones.length;
  const send = () => {
    const link = `https://portal.skyops.io/r/${mic.id.toLowerCase()}-${Math.random().toString(36).slice(2, 7)}`;
    const v = (mic.delivery?.version || 0) + 1;
    mic.signoff = { by: window.__personaName || "I. Duarte", at: window.SKY_TODAY };
    mic.delivery = { at: window.SKY_TODAY, to: [...to, ...extra.split(",").map(s => s.trim()).filter(Boolean)], by: mic.signoff.by, link, version: v, formats: Object.keys(fmt).filter(k => fmt[k]), views: 0, partial };
    window.micAdvance ? window.micAdvance(mic, { reported: 1, review: 1 }, "reported") : (mic.status = "reported");
    window.saveMicState && window.saveMicState(mic);
    onDone(); onClose(); skyToast(`Report v${v} delivered to ${mic.delivery.to.length} recipients`);
  };
  return <div className="ni-scrim" onClick={onClose}>
    <div className="ni-modal dl-modal" role="dialog" aria-label="Deliver report" onClick={e => e.stopPropagation()}>
      <div className="ni-hd"><div><div className="kicker">Deliver report</div><h3>{site.name} · {mic.cycle}</h3><span className="sec">{mic.id} · {site.name} · version {(mic.delivery?.version || 0) + 1}</span></div><button className="ask-hd-btn" onClick={onClose}><Icon name="x" size={13}/></button></div>
      <div className="ni-body dl-body">
        {partial && <div className="dl-warn"><Icon name="alert" size={12}/><span>{ready} of {zones.length} zones reported. Delivering now sends a partial report; a new version is sent when the remaining zones finish.</span></div>}
        <div className="field"><span>Recipients</span>
          <div className="dl-to">{to.map(t => <span key={t} className="dl-chip">{t}<button onClick={() => setTo(to.filter(x => x !== t))} aria-label={`Remove ${t}`}><Icon name="x" size={9}/></button></span>)}</div>
          <input className="inp" value={extra} onChange={e => setExtra(e.target.value)} placeholder="Add emails, comma-separated"/></div>
        <div className="field"><span>Include</span>
          <div className="dl-fmt">{[["pdf", "Report PDF", "client-branded · IEC TS 62446-3"], ["portal", "Portal link", "interactive twin, zone maps, module list · expires in 90 days"], ["csv", "Defect list CSV", "module, class, ΔT, GPS"], ["ir", "Radiometric images", "ZIP · large"]].map(([k, l, d]) => <label key={k} className={`ni-inh ${fmt[k] ? "on" : ""}`}><input type="checkbox" checked={fmt[k]} onChange={e => setFmt(x => ({ ...x, [k]: e.target.checked }))}/><span><b>{l}</b><em>{d}</em></span></label>)}</div></div>
        <label className="field"><span>Message</span><textarea className="inp" rows={3} style={{ height: "auto" }} value={msg} onChange={e => setMsg(e.target.value)}/></label>
        <label className={`dl-sign ${ok ? "on" : ""}`}><input type="checkbox" checked={ok} onChange={e => setOk(e.target.checked)}/><span><b>Sign off as reviewing analyst</b><em>I confirm detections were reviewed and the report follows IEC TS 62446-3. My name and date appear on the report.</em></span></label>
      </div>
      <div className="ni-ft"><button className="btn btn-ghost" onClick={() => skyDownload(`${mic.id}-report.pdf`, reportPdf(mic, site, zones))}><Icon name="download" size={12}/>Preview PDF</button><span className="grow"/>
        <button className="btn btn-secondary" onClick={onClose}>Cancel</button>
        <button className="btn btn-primary" disabled={!ok || to.length + extra.split(",").filter(s => s.trim()).length === 0} onClick={send}><Icon name="send" size={12}/>Sign off & deliver</button></div>
    </div>
  </div>;
}

function DeliveryBar({ mic, site, zones, go }) {
  const [open, setOpen] = uSLC(false);
  const [, f] = uSLC(0);
  React.useEffect(() => { const h = () => setOpen(true); window.addEventListener("skyops:deliver", h); return () => window.removeEventListener("skyops:deliver", h); }, []);
  const d = mic.delivery;
  const pdf = () => { skyDownload(`${mic.id}-${site.name.replace(/\s+/g, "-")}-report.pdf`, reportPdf(mic, site, zones)); skyToast("Report PDF downloaded"); };
  return <>
    <div className={`dl-bar ${d ? "is-sent" : ""}`}>
      {d ? <>
        <Icon name="check_circle" size={14}/>
        <div className="dl-bar-m"><b>Delivered v{d.version} · {d.at}</b><span>to {d.to.join(", ")} · signed off by {d.by}{d.partial ? " · partial" : ""}</span></div>
        <span className="dl-link mono">{d.link.replace("https://", "")}</span>
        <button className="btn btn-ghost btn-xs" onClick={() => { navigator.clipboard && navigator.clipboard.writeText(d.link); skyToast("Portal link copied"); }}><Icon name="copy" size={11}/>Copy link</button>
        <button className="btn btn-ghost btn-xs" onClick={pdf}><Icon name="download" size={11}/>PDF</button>
        <button className="btn btn-secondary btn-xs" onClick={() => setOpen(true)}><Icon name="send" size={11}/>Send new version</button>
        <button className="btn btn-primary btn-xs" onClick={() => window.__inNav && window.__inNav.setWsStage("archive")}>Archive<Icon name="arrow_right" size={11}/></button>
      </> : <>
        <Icon name="send" size={14}/>
        <div className="dl-bar-m"><b>Not delivered yet</b><span>Sign off and send to the client. The portal link and PDF are generated on delivery.</span></div>
        <span className="grow"/>
        <button className="btn btn-secondary btn-xs" onClick={pdf}><Icon name="download" size={11}/>Download PDF</button>
        <button className="btn btn-primary btn-xs" onClick={() => setOpen(true)}><Icon name="send" size={11}/>Deliver to client</button>
      </>}
    </div>
    {open && <DeliverModal mic={mic} site={site} zones={zones} onClose={() => setOpen(false)} onDone={() => f(x => x + 1)}/>}
  </>;
}

Object.assign(window, { skyDownload, skyToast, skyPdf, reportPdf, fpCoords, fpKml, fpWpml, DeliverModal, DeliveryBar });
