/* global React, Icon, Pill, SrcChip, Field, ON_HIRE, RECON_SUMMARY, TRANSPORT_INVOICES, CS_TEAM */
const { useState, useEffect, useMemo } = React;

function CSView({ flow, advanceFlow }) {
  const [screen, setScreen] = useState("recon"); // recon | active | agreements | invoices | inbox

  useEffect(() => {
    if (!flow) return;
    if (flow.id === "monthly-recon") setScreen("recon");
    if (flow.id === "transport-invoice") setScreen("invoices");
    if (flow.id === "off-hire-detected") setScreen("recon");
  }, [flow?.id, flow?.step]);

  return (
    <div className="view-inner">
      <div className="row" style={{ justifyContent: "space-between", alignItems: "flex-start" }}>
        <div>
          <div className="row" style={{ gap: 8 }}>
            <h2 className="page-title">Customer services</h2>
            <Pill tone="info" noDot>Emma · signed in</Pill>
          </div>
          <p className="page-sub">Kill the manual monthly reconciliation and the transport invoice coding pain.</p>
        </div>
        <div className="row" style={{ gap: 6, flexWrap: "wrap" }}>
          <Tab active={screen==="recon"}      onClick={()=>setScreen("recon")}      icon="refresh"  label="Monthly recon" />
          <Tab active={screen==="active"}     onClick={()=>setScreen("active")}     icon="container"label="Active hires" />
          <Tab active={screen==="invoices"}   onClick={()=>setScreen("invoices")}   icon="doc"      label="Transport invoices" />
          <Tab active={screen==="agreements"} onClick={()=>setScreen("agreements")} icon="flag"     label="Hire agreements" />
          <Tab active={screen==="inbox"}      onClick={()=>setScreen("inbox")}      icon="mail"     label="WeCare inbox" />
        </div>
      </div>

      {screen === "recon" && <ReconHero flow={flow} advanceFlow={advanceFlow} />}
      {screen === "active" && <ActiveHires />}
      {screen === "invoices" && <TransportInvoices flow={flow} advanceFlow={advanceFlow} />}
      {screen === "agreements" && <HireAgreements />}
      {screen === "inbox" && <WeCareInbox />}
    </div>
  );
}

function Tab({ active, onClick, icon, label }) {
  return (
    <button className={`btn ${active ? "primary" : ""}`} onClick={onClick} style={{ height: 30 }}>
      <Icon name={icon} size={13} /> {label}
    </button>
  );
}

function ReconHero({ flow, advanceFlow }) {
  const [matched, setMatched] = useState(0);
  const [phase, setPhase] = useState("pre"); // pre | running | done
  const [exceptions, setExceptions] = useState(ON_HIRE.filter(c => c.state !== "matched"));
  const [resolved, setResolved] = useState([]);
  const [viewing, setViewing] = useState(null);

  // On mount, animate the auto-match
  useEffect(() => {
    let alive = true;
    (async () => {
      await sleep(260);
      if (!alive) return;
      setPhase("running");
      for (let i = 1; i <= 95; i += 1) {
        await sleep(i < 60 ? 8 : i < 85 ? 16 : 28);
        if (!alive) return;
        setMatched(i);
      }
      setPhase("done");
    })();
    return () => { alive = false; };
  }, []);

  const sleep = ms => new Promise(r => setTimeout(r, ms));

  const resolveOne = (id, action) => {
    setResolved(r => [...r, { id, action }]);
    setExceptions(e => e.filter(x => x.id !== id));
    setViewing(null);
    if (flow?.id === "monthly-recon") advanceFlow();
    if (flow?.id === "off-hire-detected") advanceFlow();
  };

  return (
    <>
      {/* Summary strip */}
      <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr 1fr 1fr", gap: 10, marginBottom: 16 }}>
        <div className="card" style={{ padding: "14px 16px" }}>
          <div className="row" style={{ justifyContent: "space-between" }}>
            <div>
              <div style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", fontWeight: 700, color: "var(--ink-500)" }}>April repeating invoice run</div>
              <div style={{ fontSize: 13, marginTop: 2 }}>Last run <span className="mono">{RECON_SUMMARY.lastRun}</span> · <SrcChip src="Cin7" /> ↔ <SrcChip src="Xero" /></div>
            </div>
            <div className="mono" style={{ fontSize: 28, fontWeight: 600, color: "var(--brand-cyan-600)" }}>
              {Math.round((matched / (matched + exceptions.length + resolved.length || 1)) * 100)}%
            </div>
          </div>
          <div style={{ marginTop: 10, height: 6, background: "var(--ink-100)", borderRadius: 999, overflow: "hidden" }}>
            <div style={{ width: `${(matched/99)*100}%`, height: "100%", background: "var(--brand-cyan)", transition: "width .1s linear" }} />
          </div>
          <div className="row" style={{ justifyContent: "space-between", marginTop: 6, fontSize: 11.5, color: "var(--ink-500)" }}>
            <span>{phase === "running" ? "Auto-matching Cin7 on-hire ↔ Xero repeating invoices…" : phase === "done" ? "Auto-match complete. Exceptions surfaced below." : "Preparing…"}</span>
            <span className="mono">{matched + resolved.length} / 99</span>
          </div>
        </div>
        <ReconKpi label="Auto-matched"    v={String(matched)} tone="ok" />
        <ReconKpi label="Exceptions"      v={String(exceptions.length)} tone={exceptions.length ? "warn" : "ok"} />
        <ReconKpi label="Off-hire detected" v={String(ON_HIRE.filter(c=>c.state==="off-hire").length)} tone="err" sub="from depot gate-ins" />
      </div>

      <div style={{ display: "grid", gridTemplateColumns: viewing ? "1.4fr 1fr" : "1fr", gap: 16, alignItems: "start" }}>
        <div className="card">
          <div className="card-head">
            <h3>Exceptions needing human judgment</h3>
            <span className="count">· {exceptions.length} open</span>
            <div className="right">
              <Pill tone="ok" noDot>{matched} collapsed as auto-matched</Pill>
            </div>
          </div>
          {exceptions.length === 0 ? (
            <EmptyReconDone resolved={resolved} />
          ) : (
            <div style={{ padding: 6 }}>
              {exceptions.map(e => (
                <ExceptionRow key={e.id} e={e} onOpen={() => setViewing(e)} active={viewing?.id === e.id} />
              ))}
            </div>
          )}

          {resolved.length > 0 && (
            <div style={{ padding: "10px 14px", borderTop: "1px solid var(--line)", background: "var(--ok-bg)", color: "var(--ok)", fontSize: 12.5, display: "flex", alignItems: "center", gap: 8 }}>
              <Icon name="check" size={14} />
              Resolved in this session: {resolved.map(r => r.id.replace("SCNU-","…")).join(", ")}
            </div>
          )}

          <details style={{ padding: "10px 14px", borderTop: "1px solid var(--line)" }}>
            <summary style={{ cursor: "pointer", fontSize: 12.5, color: "var(--ink-500)", fontWeight: 600 }}>Show {matched} auto-matched containers</summary>
            <div style={{ marginTop: 10, maxHeight: 180, overflow: "auto" }} className="scroll">
              {ON_HIRE.filter(c => c.state === "matched").map(c => (
                <div key={c.id} style={{ display: "grid", gridTemplateColumns: "160px 1fr 120px 100px auto", gap: 10, padding: "6px 4px", fontSize: 12, borderBottom: "1px solid var(--line-soft)", alignItems: "center" }}>
                  <span className="mono">{c.id}</span>
                  <span>{c.customer}</span>
                  <span><SrcChip src="Cin7" /> {c.depot}</span>
                  <span><SrcChip src="Xero" /> <span className="mono">{c.xeroInv}</span></span>
                  <Pill tone="ok" noDot>Matched</Pill>
                </div>
              ))}
            </div>
          </details>
        </div>

        {viewing && <ExceptionPanel e={viewing} onResolve={resolveOne} onClose={() => setViewing(null)} />}
      </div>
    </>
  );
}

function EmptyReconDone({ resolved }) {
  return (
    <div style={{ padding: 40, textAlign: "center" }}>
      <div style={{ width: 56, height: 56, margin: "0 auto", borderRadius: 28, background: "var(--ok-bg)", color: "var(--ok)", display: "grid", placeItems: "center" }}>
        <Icon name="check" size={26} />
      </div>
      <h3 style={{ margin: "14px 0 4px" }}>All exceptions resolved</h3>
      <p className="muted" style={{ fontSize: 13, margin: 0 }}>
        {resolved.length} exception{resolved.length !== 1 ? "s" : ""} handled this session. April's run is clean.
      </p>
    </div>
  );
}

function ReconKpi({ label, v, tone, sub }) {
  return (
    <div className="card" style={{ padding: "14px 16px" }}>
      <div style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", fontWeight: 700, color: "var(--ink-500)" }}>{label}</div>
      <div className="mono" style={{ fontSize: 26, fontWeight: 600, color: tone === "ok" ? "var(--ok)" : tone === "err" ? "var(--err)" : tone === "warn" ? "var(--warn)" : "var(--ink-900)" }}>{v}</div>
      {sub && <div style={{ fontSize: 11.5, color: "var(--ink-500)" }}>{sub}</div>}
    </div>
  );
}

function ExceptionRow({ e, onOpen, active }) {
  const tone = e.state === "off-hire" ? "err" : "warn";
  return (
    <button onClick={onOpen} className="slide-in" style={{
      width: "100%", textAlign: "left", display: "grid", gridTemplateColumns: "140px 1fr 140px auto", gap: 12,
      padding: "12px 10px", border: "1px solid " + (active ? "var(--brand-cyan)" : "var(--line-soft)"),
      background: active ? "var(--brand-cyan-50)" : "var(--card)",
      borderRadius: 8, marginBottom: 8, alignItems: "center",
    }}>
      <div className="mono" style={{ fontWeight: 600, fontSize: 12.5 }}>{e.id}</div>
      <div>
        <div style={{ fontWeight: 600, fontSize: 13 }}>{e.customer}</div>
        <div style={{ fontSize: 12, color: "var(--ink-500)" }}>{e.issue}</div>
      </div>
      <div>
        <Pill tone={tone} noDot>{e.state === "off-hire" ? "Off-hire detected" : "Exception"}</Pill>
      </div>
      <Icon name="chev_r" size={14} style={{ color: "var(--ink-400)" }} />
    </button>
  );
}

function ExceptionPanel({ e, onResolve, onClose }) {
  const isOffHire = e.state === "off-hire";
  return (
    <div className="card slide-in">
      <div className="card-head">
        <h3>{isOffHire ? "Off-hire decision" : "Resolve exception"}</h3>
        <div className="right">
          <button className="btn ghost sm" onClick={onClose}>Close</button>
        </div>
      </div>
      <div style={{ padding: 16 }}>
        <Field label="Customer" src="Cin7" big>{e.customer}</Field>
        <div className="mt-12" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <Field label="Container" src="Cin7"><span className="mono">{e.id}</span></Field>
          <Field label="Depot" src="Cin7">{e.depot}</Field>
          <Field label="On hire since" src="Cin7">{e.since}</Field>
          <Field label="Xero repeating invoice" src="Xero">{e.xeroInv ? <span className="mono">{e.xeroInv}</span> : <span className="muted">— none —</span>}</Field>
        </div>

        <div className="mt-16" style={{ padding: 12, background: "var(--ink-50)", borderRadius: 8, border: "1px solid var(--line)" }}>
          <div className="row" style={{ gap: 8 }}>
            <Icon name={isOffHire ? "warn" : "link"} size={14} style={{ color: isOffHire ? "var(--err)" : "var(--warn)" }} />
            <strong style={{ fontSize: 13 }}>{e.issue}</strong>
          </div>
          {isOffHire && (
            <div className="muted" style={{ fontSize: 12, marginTop: 6 }}>
              Gate-in detected by ops at Tauranga depot on 22 Apr. No off-hire request was lodged. If this is genuine, kill the Xero repeating invoice before May's run.
            </div>
          )}
        </div>

        <div className="col mt-16" style={{ gap: 8 }}>
          {isOffHire ? (
            <>
              <button className="btn primary" onClick={() => onResolve(e.id, "off-hired")}>
                <Icon name="check" size={13} /> Mark off-hired · kill Xero RI-0508
              </button>
              <button className="btn" onClick={() => onResolve(e.id, "kept")}>Keep on hire (customer still has it)</button>
              <button className="btn ghost">Flag to sales rep instead</button>
            </>
          ) : (
            <>
              <button className="btn primary" onClick={() => onResolve(e.id, "third-confirmed")}>
                <Icon name="check" size={13} /> Confirm 3rd container is on hire · add to Xero RI-0481
              </button>
              <button className="btn" onClick={() => onResolve(e.id, "off-hired")}>One container is off-hired · kill line in Cin7</button>
              <button className="btn ghost" onClick={() => onResolve(e.id, "sales")}>Flag to sales rep (Hayden)</button>
            </>
          )}
        </div>

        <div className="mt-16" style={{ fontSize: 11.5, color: "var(--ink-500)" }}>
          <Icon name="bolt" size={11} /> The Hub is learning: after 3 similar resolutions this pattern will auto-collapse.
        </div>
      </div>
    </div>
  );
}

function ActiveHires() {
  return (
    <div className="card">
      <div className="card-head">
        <h3>Active hires</h3><span className="count">· 99 on hire · <SrcChip src="Cin7" /></span>
        <div className="right">
          <button className="btn sm"><Icon name="filter" size={12} /> Depot</button>
          <button className="btn sm"><Icon name="filter" size={12} /> Customer</button>
        </div>
      </div>
      <table className="tbl">
        <thead><tr><th>Container</th><th>Customer</th><th>Depot</th><th>Since</th><th>Last invoice</th><th>State</th></tr></thead>
        <tbody>
          {ON_HIRE.map(c => (
            <tr key={c.id}>
              <td><span className="mono">{c.id}</span> <span className="muted" style={{ fontSize: 11 }}>{c.type}</span></td>
              <td>{c.customer}</td>
              <td>{c.depot}</td>
              <td className="muted">{c.since}</td>
              <td>{c.lastInv}</td>
              <td>
                {c.state === "matched" && <Pill tone="ok" noDot>Matched</Pill>}
                {c.state === "exception" && <Pill tone="warn" noDot>Exception</Pill>}
                {c.state === "off-hire" && <Pill tone="err" noDot>Off-hire detected</Pill>}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function TransportInvoices({ flow, advanceFlow }) {
  const [open, setOpen] = useState(TRANSPORT_INVOICES[1]);
  const [confirmed, setConfirmed] = useState([]);

  const confirm = (invId, lineId) => {
    const key = `${invId}::${lineId}`;
    setConfirmed(c => [...c, key]);
    if (flow?.id === "transport-invoice") advanceFlow();
  };

  const isConfirmed = (invId, lineId) => confirmed.includes(`${invId}::${lineId}`);

  return (
    <div style={{ display: "grid", gridTemplateColumns: "320px 1fr", gap: 16, alignItems: "start" }}>
      <div className="card">
        <div className="card-head"><h3>Inbox</h3><span className="count">· 3</span></div>
        <div style={{ padding: 6 }}>
          {TRANSPORT_INVOICES.map(inv => (
            <button key={inv.id} onClick={() => setOpen(inv)} style={{
              width: "100%", textAlign: "left", padding: 10, borderRadius: 8,
              border: "1px solid " + (open.id === inv.id ? "var(--brand-cyan)" : "transparent"),
              background: open.id === inv.id ? "var(--brand-cyan-50)" : "transparent",
              marginBottom: 4, display: "flex", justifyContent: "space-between", alignItems: "center"
            }}>
              <div>
                <div style={{ fontWeight: 700, fontSize: 13 }}>{inv.vendor}</div>
                <div className="muted" style={{ fontSize: 11.5 }}><span className="mono">{inv.id}</span> · {inv.received}</div>
              </div>
              <span className="mono" style={{ fontSize: 12, fontWeight: 600 }}>{inv.total}</span>
            </button>
          ))}
        </div>
      </div>

      <div className="card">
        <div className="card-head">
          <h3>{open.vendor}</h3>
          <span className="count">· <span className="mono">{open.id}</span> · {open.total}</span>
          <div className="right">
            <SrcChip src="Outlook" /><SrcChip src="Hub" />
          </div>
        </div>
        <div style={{ padding: 16 }}>
          <p className="muted" style={{ fontSize: 12.5, marginTop: 0 }}>
            Parsed into lines. For each line, the Hub proposed a sales order match based on container / release / address. Confirm or correct — on confirm the cost drops into the Cin7 SO's delivery cost field and a PO is raised.
          </p>

          {open.lines.map(line => {
            const done = isConfirmed(open.id, line.id);
            return (
              <div key={line.id} className={done ? "slide-in" : ""} style={{
                border: "1px solid " + (done ? "var(--ok)" : "var(--line)"),
                background: done ? "var(--ok-bg)" : "var(--card)",
                borderRadius: 8, padding: 12, marginBottom: 10,
                display: "grid", gridTemplateColumns: "1fr 200px auto", gap: 12, alignItems: "center"
              }}>
                <div>
                  <div style={{ fontWeight: 600, fontSize: 13 }}>{line.desc}</div>
                  {line.container && <div className="muted" style={{ fontSize: 11.5 }}><span className="mono">{line.container}</span></div>}
                  {line.pending && <div style={{ fontSize: 11.5, color: "var(--warn)" }}>Line missing container number — waiting on driver photo</div>}
                  {line.ambiguous && <div style={{ fontSize: 11.5, color: "var(--warn)" }}>{line.suggestion}</div>}
                </div>
                <div>
                  <div style={{ fontSize: 11, color: "var(--ink-500)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.06em" }}>Proposed match</div>
                  {line.match
                    ? <div style={{ fontSize: 13 }}><span className="mono" style={{ fontWeight: 600 }}>{line.match}</span> <SrcChip src="Cin7" /></div>
                    : <div className="muted" style={{ fontSize: 13 }}>— no match —</div>}
                  {line.confidence > 0 && !done && (
                    <div className="row" style={{ gap: 6, marginTop: 4 }}>
                      <div style={{ flex: 1, height: 4, background: "var(--ink-100)", borderRadius: 2, overflow: "hidden" }}>
                        <div style={{ width: `${line.confidence * 100}%`, height: "100%", background: line.confidence > 0.85 ? "var(--ok)" : line.confidence > 0.6 ? "var(--warn)" : "var(--err)" }} />
                      </div>
                      <span className="mono" style={{ fontSize: 11, color: "var(--ink-500)" }}>{Math.round(line.confidence * 100)}%</span>
                    </div>
                  )}
                </div>
                <div style={{ textAlign: "right" }}>
                  <div className="mono" style={{ fontWeight: 700, fontSize: 13 }}>{line.amount}</div>
                  {done
                    ? <Pill tone="ok" noDot>Coded to Cin7</Pill>
                    : line.pending
                      ? <Pill tone="warn" noDot>Waiting</Pill>
                      : <button className="btn primary sm mt-8" onClick={() => confirm(open.id, line.id)}><Icon name="check" size={12} /> Confirm</button>}
                </div>
              </div>
            );
          })}

          <div style={{ marginTop: 12, padding: 12, background: "var(--ink-50)", borderRadius: 8, border: "1px dashed var(--line)", fontSize: 12.5, color: "var(--ink-700)" }}>
            <Icon name="bolt" size={12} /> Feeds the <strong>Transport GP</strong> report on the leadership dashboard.
          </div>
        </div>
      </div>
    </div>
  );
}

function HireAgreements() {
  const items = [
    { customer: "Rangitata Orchards Ltd",     step: "signed",    when: "Today 08:12", ppsr: "filed",   folder: "Rangitata Orchards/2026-04" },
    { customer: "Selwyn Build Co.",           step: "sent",      when: "Yesterday",   ppsr: "queued",  folder: "—" },
    { customer: "Kiwi Kiwifruit Co-op",       step: "drafted",   when: "Today 07:45", ppsr: "—",       folder: "—" },
    { customer: "AddictionFoods Ltd",         step: "signed",    when: "18 Apr",     ppsr: "filed",   folder: "AddictionFoods/2023-11 (consolidated)" },
  ];
  const tones = { signed: "ok", sent: "info", drafted: "warn" };
  return (
    <div className="card">
      <div className="card-head">
        <h3>Hire agreements</h3>
        <span className="count">· generate → sign → file</span>
        <div className="right"><SrcChip src="Adobe Sign" /><SrcChip src="OneDrive" /><SrcChip src="Cin7" /></div>
      </div>
      <table className="tbl">
        <thead><tr><th>Customer</th><th>Stage</th><th>Updated</th><th>PPSR</th><th>Filed to OneDrive</th><th style={{width:160}}></th></tr></thead>
        <tbody>
          {items.map((i, idx) => (
            <tr key={idx}>
              <td>{i.customer}</td>
              <td><Pill tone={tones[i.step]} noDot>{i.step}</Pill></td>
              <td className="muted">{i.when}</td>
              <td>{i.ppsr === "filed" ? <Pill tone="ok" noDot>Filed</Pill> : i.ppsr === "queued" ? <Pill tone="warn" noDot>Queued</Pill> : <span className="muted">—</span>}</td>
              <td className="mono" style={{ fontSize: 11.5 }}>{i.folder}</td>
              <td>
                {i.step === "drafted" && <button className="btn sm primary"><Icon name="play" size={11} /> Send for signature</button>}
                {i.step === "sent" && <button className="btn sm">Resend</button>}
                {i.step === "signed" && <button className="btn sm">Open PDF</button>}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <div style={{ padding: 12, borderTop: "1px solid var(--line)", fontSize: 12.5, color: "var(--ink-500)" }}>
        <Icon name="bolt" size={11} /> Signed PDFs auto-file by <span className="mono">Customer / YYYY-MM</span> — no more "AdictionFoods 2, 3, 4".
      </div>
    </div>
  );
}

function WeCareInbox() {
  const items = [
    { who: "Go Logistics NZ", subj: "Re: ETA Thursday delivery", owner: "Emma", urgent: true,  preview: "Can we push to Friday afternoon?" },
    { who: "Kiwi Kiwifruit Co-op", subj: "Container returned — please confirm", owner: "Daisy", urgent: true, preview: "Dropped back at Tauranga yard 22 Apr." },
    { who: "AddictionFoods", subj: "Invoice copy request", owner: "Kathy", urgent: false, preview: "Need April hire invoice for their auditor." },
    { who: "[FYI] Outlook rule", subj: "Delivery confirmation — Selwyn Build Co.", owner: "—", urgent: false, preview: "Auto-processed. Collapsed." },
  ];
  return (
    <div className="card">
      <div className="card-head">
        <h3>WeCare — filtered</h3>
        <span className="count">· 12 collapsed as FYI / duplicate</span>
        <div className="right"><SrcChip src="Outlook" /></div>
      </div>
      <table className="tbl">
        <thead><tr><th style={{width:80}}>Owner</th><th>From</th><th>Subject</th><th style={{width:90}}></th></tr></thead>
        <tbody>
          {items.map((i, idx) => (
            <tr key={idx}>
              <td><span className="pill no-dot" style={{ background: "var(--ink-100)" }}>{i.owner}</span></td>
              <td>{i.who}</td>
              <td><div style={{ fontWeight: 600 }}>{i.subj}</div><div className="muted" style={{ fontSize: 11.5 }}>{i.preview}</div></td>
              <td>{i.urgent ? <Pill tone="err" noDot>Needs action</Pill> : <Pill tone="ok" noDot>Handled</Pill>}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

window.CSView = CSView;
