/* ============================================================
   analysis.jsx — centre pane: document + extraction + lines
   (useState/useEffect come from helpers.jsx — shared global scope)
   ============================================================ */

/* ---- scanned / digital paper preview ---- */
function PaperPreview({ inv }) {
  const scanned = inv.source === "scan";
  const lines = (inv.raw || "").split("\n");
  return (
    <div className={`paper ${scanned ? "scanned" : "digital"}`}>
      {scanned && <>
        <div className="smudge" style={{ width: 46, height: 30, top: 22, right: 16 }}></div>
        <div className="smudge" style={{ width: 30, height: 22, bottom: 40, left: 12 }}></div>
        <div className="scanline" style={{ top: "38%" }}></div>
        <div className="crease" style={{ top: "52%" }}></div>
      </>}
      {lines.map((l, i) => (
        <div key={i} className={l.includes("smudged") || l.includes("faint") || l.includes("not shown") ? "faint" : ""}>
          {l || "\u00A0"}
        </div>
      ))}
    </div>
  );
}

function DocChip({ icon, t, s, missing }) {
  return (
    <div className={`docchip${missing ? " missing" : ""}`}>
      <Icon name={missing ? "alertTri" : icon} size={15} />
      <div>
        <div className="dc-t">{t}</div>
        <div className="dc-s">{s}</div>
      </div>
    </div>
  );
}

/* ---- processing (shimmer) ---- */
const PROC_STEPS = [
  { t: "Reading document", ic: "fileSearch" },
  { t: "Extracting line items", ic: "scan" },
  { t: "Matching to PO + goods-receipt", ic: "link" },
  { t: "Checking contracted rates", ic: "scale" },
];
function Processing({ source }) {
  const [step, setStep] = useState(0);
  useEffect(() => {
    const t1 = setTimeout(() => setStep(1), 420);
    const t2 = setTimeout(() => setStep(2), 880);
    const t3 = setTimeout(() => setStep(3), 1280);
    return () => [t1, t2, t3].forEach(clearTimeout);
  }, []);
  return (
    <div className="proc fade-in">
      <div className="pstat">
        <span className="spin"></span>
        Extracting &amp; matching…
        <span className="mono">{source === "scan" ? "OCR · scanned paper" : "parsing · digital PDF"}</span>
      </div>
      <div className="proc-steps">
        {PROC_STEPS.map((s, i) => (
          <div key={i} className={`st ${i < step ? "done" : ""} ${i === step ? "active" : ""}`}>
            <span className="ic"><Icon name={i < step ? "check" : s.ic} size={15} /></span>
            {s.t}
          </div>
        ))}
      </div>
      <div className="shimmer-row" style={{ marginTop: 6 }}></div>
      <div className="shimmer-row" style={{ width: "82%" }}></div>
      <div className="shimmer-row" style={{ width: "91%" }}></div>
    </div>
  );
}

/* ---- extracted lines table ---- */
function LinesTable({ inv, onEvidence }) {
  const fmt = window.RECON.fmtMoney;
  const [flash, setFlash] = useState(true);
  useEffect(() => { const t = setTimeout(() => setFlash(false), 1000); return () => clearTimeout(t); }, [inv.id]);
  const t = inv.totals;
  return (
    <div className="fade-in">
      <div className="lines-head">
        <span className="t">Extracted lines · 3-way match</span>
        <span className="legend">
          <i><span className="sw" style={{ background: "var(--state-verified)" }}></span>match</i>
          <i><span className="sw" style={{ background: "var(--state-danger)" }}></span>exception</i>
        </span>
      </div>
      <table className="lines">
        <thead>
          <tr>
            <th>Service</th>
            <th className="num">Invoiced</th>
            <th className="num">Contracted</th>
            <th className="num">Δ</th>
            <th>Evidence</th>
            <th style={{ textAlign: "center", width: 44 }}></th>
          </tr>
        </thead>
        <tbody>
          {inv.lines.map((ln) => {
            const exc = ln.verdict === "exception";
            return (
              <tr key={ln.id} className={exc ? `exc${flash ? " flash" : ""}` : ""}>
                <td className="svc">{ln.svc}<span className="qty">{ln.detail}</span></td>
                <td className="num">{ln.invoiced === 0 ? "—" : fmt(ln.invoiced)}</td>
                <td className="num ref">{ln.reference < 0 ? fmt(ln.reference) : (ln.reference === 0 ? "—" : fmt(ln.reference))}</td>
                <td className={`num delta ${exc ? "pos" : "zero"}`}>
                  {ln.delta === 0 ? "$0.00" : fmt(ln.delta, true)}
                </td>
                <td>
                  {exc
                    ? <button className="ev-link" onClick={() => onEvidence(ln.evidence)}><Icon name="external" size={12} />view</button>
                    : <span className="ev-dash">—</span>}
                </td>
                <td style={{ textAlign: "center" }}>
                  <span className={`verdict-ic ${exc ? "bad" : "ok"}`}>
                    <Icon name={exc ? "alertCircle" : "checkCircle"} size={16} />
                  </span>
                </td>
              </tr>
            );
          })}
        </tbody>
        <tfoot>
          <tr>
            <td className="lab">Total</td>
            <td className="num">{fmt(t.invoiced)}</td>
            <td className="num">{fmt(t.reference)}</td>
            <td className={`num delta ${t.exception ? "pos" : "zero"}`}>{t.exception ? fmt(t.invoiced - t.reference, true) : "$0.00"}</td>
            <td colSpan="2"></td>
          </tr>
        </tfoot>
      </table>
    </div>
  );
}

/* ---- missing-doc state ---- */
function MissingDocAnalysis({ inv }) {
  return (
    <div className="fade-in">
      <div className="missing-doc" style={{ marginBottom: 16 }}>
        <Icon name="alertTri" size={20} />
        <div>
          <div className="t">Goods-receipt note missing — match withheld</div>
          <div className="s">No GRN is on file for {inv.po}. The system will not guess a quantity match against the PO alone. This invoice is routed for a manual goods-receipt check before any line can be cleared.</div>
        </div>
      </div>
      <div className="lines-head"><span className="t">Extracted lines · awaiting goods-receipt</span></div>
      <table className="lines">
        <thead><tr><th>Service</th><th className="num">Invoiced</th><th className="num">PO</th><th>Receipt</th></tr></thead>
        <tbody>
          <tr><td className="svc">32 MPa concrete<span className="qty">18 m³ @ $215.00</span></td><td className="num">$3,870.00</td><td className="num ref">$3,870.00</td><td><span className="pill pill--review"><span className="d"></span>no GRN</span></td></tr>
          <tr><td className="svc">Pump hire<span className="qty">Half day</span></td><td className="num">$480.00</td><td className="num ref">$480.00</td><td><span className="pill pill--review"><span className="d"></span>no GRN</span></td></tr>
          <tr><td className="svc">Cartage<span className="qty">—</span></td><td className="num">$325.00</td><td className="num ref">$325.00</td><td><span className="pill pill--review"><span className="d"></span>no GRN</span></td></tr>
        </tbody>
      </table>
    </div>
  );
}

function Analysis({ inv, processing, onEvidence, matchMeta }) {
  if (!inv) {
    return (
      <div className="pane">
        <div className="pane-hd"><div className="row"><h2>Analysis</h2></div><div className="sub">Extraction &amp; 3-way match</div></div>
        <div className="pane-body">
          <div className="an-empty">
            <span className="glyph"><Icon name="fileSearch" size={56} /></span>
            <div className="t">Select an invoice to analyse</div>
            <div className="s">Pick a pending invoice from the queue. Extraction runs against its purchase order, goods-receipt note and contracted rate card — exceptions are surfaced with evidence.</div>
          </div>
        </div>
      </div>
    );
  }
  const fmt = window.RECON.fmtMoney;
  const grnMissing = !inv.grn;
  return (
    <div className="pane">
      <div className="pane-hd">
        <div className="row"><h2>Analysis</h2>
          <span className="mono" style={{ fontSize: 11, color: "var(--rmai-fg-mut)" }}>{inv.id}</span>
        </div>
        <div className="sub" style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <span>Extraction &amp; 3-way match · {inv.vendor}</span>
          {!processing && matchMeta && (matchMeta.source === "live" || matchMeta.source === "live-approx") &&
            <span className="src" style={{ display: "inline-flex", alignItems: "center", gap: 4, color: "var(--rmai-green)", fontWeight: 600 }}>
              <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--rmai-green)", display: "inline-block" }}></span>
              matched · live model{matchMeta.ms ? " · " + matchMeta.ms + "ms" : ""}
            </span>}
        </div>
      </div>
      <div className="pane-body">
        <div className="an-wrap">
          <div className="scan">
            <PaperPreview inv={inv} />
            <div className="side">
              <span className="lbl">Documents matched</span>
              <DocChip icon={inv.source === "pdf" ? "pdf" : "scan"} t={inv.source === "pdf" ? "Invoice · digital PDF" : "Invoice · scanned paper"} s={inv.id} />
              <DocChip icon="inbox" t="Purchase order" s={inv.po} />
              <DocChip icon="checkCircle" t="Goods-receipt note" s={inv.grn || "not on file"} missing={grnMissing} />
              <div style={{ fontSize: 10.5, color: "var(--rmai-fg-mut)", lineHeight: 1.5, marginTop: 2 }}>
                Rate card · {inv.vendor.split(" ")[0]} agreement on file
              </div>
            </div>
          </div>

          {processing
            ? <Processing source={inv.source} />
            : inv.kind === "missing-doc"
              ? <MissingDocAnalysis inv={inv} />
              : <LinesTable inv={inv} onEvidence={onEvidence} />}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Analysis });
