/* Business — the contracts behind the prices, the chasing of what is owed, and
   whether an episode paid for itself.
   Commit model: INSTANT on all three. Logging a chase needs a note and an
   outcome, so it opens a staged dialog from App.jsx; nothing else here commits.

   These three screens exist to close the loop Finance opens: Contracts says what
   a payer agreed to pay, Credit control says who has not paid it, and Cost and
   margin says whether the price covered the care. Every figure divides an array
   metrics.js owns, so none of them can disagree with the invoice it came from. */
(() => {
  const {
    Button, Badge, Avatar, Select, Alert, AlertTitle, AlertDescription,
    Table, TableHeader, TableBody, TableRow, TableHead, TableCell, TableFooter,
  } = window.OriginDesignSystem_7c998b;

  /* ── Contracts and tariffs ───────────────────────────────────────────── */
  function ContractsScreen({ data, now, viewer, onNavigate, onExport }) {
    const [payer, setPayer] = React.useState("all");
    const findings = offContractLines(data);
    const expiring = contractsExpiring(data.contracts, now);
    const priced = data.contractPrices.length;
    const cover = data.tariffItems.length * data.contracts.length;
    const items = payer === "all" ? data.tariffItems : data.tariffItems.filter((item) => data.contractPrices.some((p) => p.payer === payer && p.itemId === item.id));

    return (
      <>
        <PageHeader
          path="/contracts"
          title="Contracts and tariffs"
          sub={"What each payer has agreed to pay for each thing the hospital bills. An invoice line is checked against this at render, so a price billed off contract is a finding rather than a difference nobody sees."}
          actions={<ExportMenu scope={priced + " contracted prices across " + data.contracts.length + " contracts"} onExport={(format) => onExport("Contracts and tariffs", "Every contracted price", priced, format)} />}
        />
        <Figures items={[
          { label: "Live contracts", value: data.contracts.filter((c) => c.status === "live").length, qualifier: expiring.length ? expiring.length + " expiring within 30 days" : "none expiring within 30 days" },
          { label: "Contracted prices", value: priced, qualifier: "of " + cover + " possible payer and item pairs — the rest are not covered" },
          { label: "Lines off contract", value: findings.length, qualifier: findings.filter((f) => f.kind === "no_price").length + " with no contracted price, " + findings.filter((f) => f.kind === "different").length + " priced differently" },
          { label: "Billed off contract", value: formatPounds(findings.reduce((n, f) => n + (f.kind === "no_price" ? lineTotal(f.line) : Math.abs(f.difference) * f.line.qty), 0)), qualifier: "the value at risk if a payer queries these lines" },
        ]} />

        {expiring.length ? (
          <div className="hd-alertwrap">
            <Alert variant="warning">
              <AlertTitle>{expiring.length === 1 ? "One contract expires within 30 days" : expiring.length + " contracts expire within 30 days"}</AlertTitle>
              <AlertDescription>
                {expiring.map((c) => c.name + " — " + CONTRACT_FLAGS.daysLeft(c, now) + " days left, " + contractPricesFor(data, c.payer).length + " prices under it").join(" · ")}. Renewal is negotiated before the end date; prices stop applying the day after.
              </AlertDescription>
            </Alert>
          </div>
        ) : null}

        <Band title={"Contracts (" + data.contracts.length + ")"} note="One per payer. The terms here decide the due date every invoice to that payer is given.">
          <div className="hd-split">
            {data.contracts.map((contract) => {
              const prices = contractPricesFor(data, contract.payer);
              const invoices = data.invoices.filter((i) => i.payer === contract.payer && INVOICE_FLAGS.billable(i));
              const soon = CONTRACT_FLAGS.expiringSoon(contract, now);
              return (
                <div className={"hd-tile" + (soon ? "" : " hd-tile--tint")} key={contract.id}>
                  <span className="hd-tile__label">{labelOf(PAYERS, contract.payer)}</span>
                  <span className="hd-person__name">{contract.name}</span>
                  <span className="hd-actions__row" style={{ marginBlock: "var(--space-1)" }}>
                    <StatusBadge values={CONTRACT_STATUS} value={contract.status} />
                    {soon ? <Badge size="sm" variant="warning">{CONTRACT_FLAGS.daysLeft(contract, now)} days left</Badge> : null}
                  </span>
                  <span className="hd-footnote">
                    {contract.dueDays ? "Payment terms " + contract.dueDays + " days" : "Payable before care"} · {prices.length} contracted {prices.length === 1 ? "price" : "prices"} · {invoices.length} issued {invoices.length === 1 ? "invoice" : "invoices"} worth {formatPounds(invoices.reduce((n, i) => n + invoiceTotal(i), 0))}
                  </span>
                  <span className="hd-footnote">
                    {contract.expiresAt ? "Runs to " + formatWhen(contract.expiresAt, now) : "No end date"} · signed {formatWhen(contract.signedAt, now)}
                  </span>
                  <span className="hd-footnote">{contract.note}</span>
                  <Button variant="link" size="xs" onClick={() => setPayer(contract.payer)}>Show its prices</Button>
                </div>
              );
            })}
          </div>
        </Band>

        <Band title="The price list" note="A blank cell is a price the contract does not carry — billing that item to that payer is off contract."
          actions={
            <span className="hd-filters__select">
              <Select size="sm" aria-label="Payer" items={[{ value: "all", label: "Every payer" }].concat(PAYERS)} value={payer} onValueChange={setPayer} />
            </span>
          }>
          <div className="hd-tablewrap">
            <table className="hd-matrix">
              <thead>
                <tr>
                  <th scope="col">Item</th>
                  <th scope="col">Code</th>
                  <th scope="col">Kind</th>
                  {(payer === "all" ? PAYERS : PAYERS.filter((p) => p.value === payer)).map((p) => <th scope="col" key={p.value} style={{ textAlign: "right" }}>{p.label}</th>)}
                </tr>
              </thead>
              <tbody>
                {items.map((item) => (
                  <tr key={item.id}>
                    <th scope="row" style={{ fontWeight: "var(--font-weight-medium)", color: "var(--foreground)" }}>{item.label}</th>
                    <td className="hd-footnote" style={{ fontFamily: "var(--font-mono)" }}>{item.code}</td>
                    <td>{labelOf(BILL_LINE_KINDS, item.kind)}</td>
                    {(payer === "all" ? PAYERS : PAYERS.filter((p) => p.value === payer)).map((p) => {
                      const price = contractedPrice(data, p.value, item.label);
                      return <td key={p.value} className="hd-num">{price === null ? <span className="hd-muted">—</span> : formatPounds(price)}</td>;
                    })}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          {payer !== "all" ? <p className="hd-footnote" style={{ marginTop: "var(--space-3)" }}>Showing the {items.length} items {labelOf(PAYERS, payer)} carries a price for, of {data.tariffItems.length} in the tariff. <button type="button" className="hd-linkbtn" onClick={() => setPayer("all")}>Show every payer</button></p> : null}
        </Band>

        <Band flush title={"Lines billed off contract (" + findings.length + ")"} note="Every invoice line whose unit price is not the contracted one, or whose item the contract does not price at all.">
          {findings.length ? (
            <TableWrap>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Invoice</TableHead>
                    <TableHead>Line</TableHead>
                    <TableHead>Payer</TableHead>
                    <TableHead className="hd-num">Billed</TableHead>
                    <TableHead className="hd-num">Contract</TableHead>
                    <TableHead>Finding</TableHead>
                    <TableHead>Action</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {findings.map((finding, index) => (
                    <TableRow key={finding.invoice.id + index}>
                      <TableCell><button type="button" className="hd-linkbtn" onClick={() => onNavigate("/invoices/" + finding.invoice.id)}>{finding.invoice.reference}</button></TableCell>
                      <TableCell>
                        <span className="hd-person__text">
                          <span className="hd-person__name">{finding.line.label}</span>
                          <span className="hd-person__meta">{patientName(data.patients, finding.invoice.patientId)} · {finding.line.qty} × {formatPoundsExact(finding.line.unitMinor)}</span>
                        </span>
                      </TableCell>
                      <TableCell>{labelOf(PAYERS, finding.invoice.payer)}</TableCell>
                      <TableCell className="hd-num">{formatPoundsExact(finding.line.unitMinor)}</TableCell>
                      <TableCell className="hd-num">{finding.price === null ? <span className="hd-muted">No price</span> : formatPoundsExact(finding.price)}</TableCell>
                      <TableCell>
                        {finding.kind === "no_price"
                          ? <Badge size="sm" variant="warning">Not in the contract</Badge>
                          : <Badge size="sm" variant="warning">{finding.difference > 0 ? "Over by " : "Under by "}{formatPoundsExact(Math.abs(finding.difference))}</Badge>}
                      </TableCell>
                      <TableCell><Button variant="outline" size="sm" onClick={() => onNavigate("/invoices/" + finding.invoice.id)}>Open invoice</Button></TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </TableWrap>
          ) : <p className="hd-footnote" style={{ paddingInline: "var(--card-pad)" }}>Every invoice line is priced exactly as its payer's contract says.</p>}
        </Band>
      </>
    );
  }

  /* ── Credit control ──────────────────────────────────────────────────── */
  function CreditControlScreen({ data, now, viewer, onNavigate, onChase, onExport }) {
    const rows = creditWorklist(data, now);
    const overdue = rows.filter((r) => r.overdue);
    const promised = rows.filter((r) => r.promised > 0);
    const failed = rows.filter((r) => r.failed.length);
    const disputed = invoicesDisputed(data.invoices);
    const outstanding = rows.reduce((n, r) => n + r.balance, 0);

    return (
      <>
        <PageHeader
          path="/credit-control"
          title="Credit control"
          sub={"Every issued invoice with a balance, in due-date order. A disputed invoice is not chased — the query is answered first — so the " + disputed.length + " disputed " + (disputed.length === 1 ? "invoice is" : "invoices are") + " not in this list."}
          actions={<ExportMenu scope={rows.length + " invoices with a balance"} onExport={(format) => onExport("Credit control worklist", "Issued invoices with a balance", rows.length, format)} />}
        />
        <Figures items={[
          { label: "Chaseable balance", value: formatPounds(outstanding), qualifier: "across " + rows.length + (rows.length === 1 ? " invoice" : " invoices") + " with money still to come" },
          { label: "Past due", value: formatPounds(overdue.reduce((n, r) => n + r.balance, 0)), qualifier: overdue.length ? overdue.length + (overdue.length === 1 ? " invoice, oldest " : " invoices, oldest ") + formatCountdown(overdue[0].invoice.dueAt, now) : "nothing in this list is past its due date" },
          { label: "Payment promised", value: formatPounds(promised.reduce((n, r) => n + r.promised, 0)), qualifier: promised.length ? "advised by " + promised.map((r) => labelOf(PAYERS, r.invoice.payer)).join(", ") + " and not yet cleared" : "nobody has promised a payment" },
          { label: "Returned payments", value: failed.length, qualifier: failed.length ? failed.map((r) => r.invoice.reference).join(", ") + " — the money came back" : "no payment has been returned" },
        ]} />

        {failed.length ? (
          <div className="hd-alertwrap">
            <Alert variant="error">
              <AlertTitle>{failed.length === 1 ? "One payment was returned" : failed.length + " payments were returned"}</AlertTitle>
              <AlertDescription>{failed.map((r) => r.invoice.reference + " — " + r.failed.map((p) => formatPoundsExact(p.amountMinor) + ", " + (p.note || "no reason recorded")).join("; ")).join(" · ")}</AlertDescription>
            </Alert>
          </div>
        ) : null}

        <Band title={"Worklist (" + rows.length + ")"} note="The next step comes from the chase ladder: reminder, statement, call, final notice, then the debt agency.">
          {rows.length ? (
            <div className="hd-rows">
              {rows.map((row) => {
                const patient = patientById(data.patients, row.invoice.patientId);
                return (
                  <div className="hd-row" key={row.invoice.id}>
                    <div className="hd-row__text">
                      <span className="hd-row__title">
                        <button type="button" className="hd-linkbtn" onClick={() => onNavigate("/invoices/" + row.invoice.id)}>{row.invoice.reference}</button>
                        {" · "}{formatPoundsExact(row.balance)} outstanding
                      </span>
                      <span className="hd-row__note">
                        <PersonCell name={patient.name} avatar={patient.avatar} size={22} onOpen={() => onNavigate("/patients/" + patient.id)} />
                      </span>
                      <span className="hd-row__note">
                        {labelOf(PAYERS, row.invoice.payer)} · {contractDueDays(data.contracts, row.invoice.payer)}-day terms · due {formatWhen(row.invoice.dueAt, now)}
                        {" · "}<span className={row.overdue ? "hd-warn" : ""}>{formatCountdown(row.invoice.dueAt, now)}</span>
                        {row.last ? " · last contact " + labelOf(CHASE_STEPS, row.last.step).toLowerCase() + " " + formatWhen(row.last.at, now) + ", " + labelOf(CHASE_OUTCOMES, row.last.outcome).toLowerCase() : " · never chased"}
                      </span>
                      {row.promised ? <span className="hd-row__note">{formatPoundsExact(row.promised)} advised and not cleared.</span> : null}
                    </div>
                    <span className="hd-actions__row">
                      <StatusBadge values={INVOICE_STATUS} value={row.invoice.status} />
                      {row.overdue ? <Badge size="sm" variant="warning">Past due</Badge> : null}
                      <Badge size="sm" variant="secondary">{row.chases.length} {row.chases.length === 1 ? "contact" : "contacts"}</Badge>
                    </span>
                    <Transitions transitions={chaseTransitions(row, viewer)} onRun={(t) => onChase(row, t)} />
                  </div>
                );
              })}
            </div>
          ) : <p className="hd-footnote">Nothing to chase. Every issued invoice is either settled or disputed.</p>}
        </Band>

        <Band tint flush title={"Contact history (" + data.chases.length + ")"} note="Every chase against every invoice, newest first.">
          {data.chases.length ? (
            <TableWrap>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>When</TableHead>
                    <TableHead>Invoice</TableHead>
                    <TableHead>Step</TableHead>
                    <TableHead>Outcome</TableHead>
                    <TableHead>What was said</TableHead>
                    <TableHead>By</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {data.chases.slice().sort((a, b) => b.at - a.at).map((chase) => {
                    const invoice = data.invoices.find((i) => i.id === chase.invoiceId);
                    return (
                      <TableRow key={chase.id}>
                        <TableCell><Clock at={chase.at} now={now} /></TableCell>
                        <TableCell><button type="button" className="hd-linkbtn" onClick={() => onNavigate("/invoices/" + chase.invoiceId)}>{invoice ? invoice.reference : chase.invoiceId}</button></TableCell>
                        <TableCell>{labelOf(CHASE_STEPS, chase.step)}</TableCell>
                        <TableCell>{labelOf(CHASE_OUTCOMES, chase.outcome)}</TableCell>
                        <TableCell style={{ whiteSpace: "normal", maxWidth: "26rem" }}>{chase.note}</TableCell>
                        <TableCell>{staffName(data.staff, chase.byId)}</TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </TableWrap>
          ) : <p className="hd-footnote" style={{ paddingInline: "var(--card-pad)" }}>No payer has been contacted yet.</p>}
        </Band>
      </>
    );
  }

  /* ── Cost and margin per episode ─────────────────────────────────────── */
  function MarginScreen({ data, now, viewer, onNavigate, onExport }) {
    const rows = marginRows(data, now);
    const kinds = costByKind(data, now);
    const billed = rows.reduce((n, r) => n + r.billed, 0);
    const cost = rows.reduce((n, r) => n + r.cost, 0);
    const uncosted = rows.reduce((n, r) => n + r.uncosted, 0);
    const thin = rows.filter((r) => r.rate < 0.15);
    const losing = rows.filter((r) => r.margin < 0);

    return (
      <>
        <PageHeader
          path="/margin"
          title="Cost and margin"
          sub={"What each issued episode was billed against what it cost to deliver. Bed days at the ward's own day cost, procedures at their planned theatre minutes, drug courses from the order's frequency — " + COST_RATES.source + "."}
          actions={<ExportMenu scope={rows.length + " issued episodes with a cost"} onExport={(format) => onExport("Cost and margin", "Issued episodes as at " + new Date(now).toLocaleDateString("en-GB", { day: "numeric", month: "short" }), rows.length, format)} />}
        />
        <Figures items={[
          { label: "Billed", value: formatPounds(billed), qualifier: "across " + rows.length + " issued " + (rows.length === 1 ? "episode" : "episodes") },
          { label: "Cost to deliver", value: formatPounds(cost), qualifier: Math.round((cost / billed) * 100) + "% of what was billed" },
          { label: "Margin", value: formatPounds(billed - cost), qualifier: Math.round(((billed - cost) / billed) * 100) + "% over the same episodes" },
          { label: "Billing with no cost attached", value: formatPounds(uncosted), qualifier: "lines that name no record, so nothing can be costed against them" },
        ]} />

        {thin.length ? (
          <div className="hd-alertwrap">
            <Alert variant="warning">
              <AlertTitle>{thin.length === 1 ? "One episode is under a 15% margin" : thin.length + " episodes are under a 15% margin"}</AlertTitle>
              <AlertDescription>
                {thin.map((r) => r.invoice.reference + " — " + Math.round(r.rate * 100) + "% on " + formatPounds(r.billed) + " billed").join(" · ")}.
                {losing.length ? " " + losing.length + " of them cost more than they were billed." : " None of them cost more than they were billed."}
              </AlertDescription>
            </Alert>
          </div>
        ) : null}

        <div className="hd-cols hd-cols--wide">
          <div className="hd-stack">
            <Band flush title={"By episode (" + rows.length + ")"} note="Thinnest margin first. An episode is one issued invoice and the care its lines name.">
              <TableWrap>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Invoice</TableHead>
                      <TableHead>Patient</TableHead>
                      <TableHead className="hd-num">Billed</TableHead>
                      <TableHead className="hd-num">Cost</TableHead>
                      <TableHead className="hd-num">Margin</TableHead>
                      <TableHead style={{ minWidth: "8rem" }}>Margin rate</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {rows.map((row) => {
                      const patient = patientById(data.patients, row.invoice.patientId);
                      return (
                        <TableRow key={row.invoice.id}>
                          <TableCell>
                            <span className="hd-person__text">
                              <span className="hd-person__name"><button type="button" className="hd-linkbtn" onClick={() => onNavigate("/invoices/" + row.invoice.id)}>{row.invoice.reference}</button></span>
                              <span className="hd-person__meta">{labelOf(PAYERS, row.invoice.payer)}{row.uncosted ? " · " + formatPounds(row.uncosted) + " uncosted" : ""}</span>
                            </span>
                          </TableCell>
                          <TableCell><PersonCell name={patient.name} avatar={patient.avatar} size={24} onOpen={() => onNavigate("/patients/" + patient.id)} /></TableCell>
                          <TableCell className="hd-num">{formatPounds(row.billed)}</TableCell>
                          <TableCell className="hd-num">{formatPounds(row.cost)}</TableCell>
                          <TableCell className="hd-num">{formatPounds(row.margin)}</TableCell>
                          <TableCell>
                            <span style={{ display: "flex", flexDirection: "column", gap: 4, minWidth: "7rem" }}>
                              <span className="hd-footnote">{Math.round(row.rate * 100)}%</span>
                              <StockBar percent={Math.max(0, row.rate * 100)} tone={row.rate < 0.15 ? "warn" : null} />
                            </span>
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                  <TableFooter>
                    <TableRow>
                      <TableCell colSpan={2}>All issued episodes</TableCell>
                      <TableCell className="hd-num">{formatPounds(billed)}</TableCell>
                      <TableCell className="hd-num">{formatPounds(cost)}</TableCell>
                      <TableCell className="hd-num">{formatPounds(billed - cost)}</TableCell>
                      <TableCell className="hd-num">{Math.round(((billed - cost) / billed) * 100)}%</TableCell>
                    </TableRow>
                  </TableFooter>
                </Table>
              </TableWrap>
            </Band>
          </div>
          <div className="hd-stack">
            <Band title="Where the cost sits" note="Every line on an issued invoice, grouped by kind, billed against costed.">
              <div className="hd-stack">
                {kinds.map((kind) => (
                  <div className="hd-tile" key={kind.kind}>
                    <span className="hd-tile__label">{kind.label}</span>
                    <span className="hd-tile__value">{formatPounds(kind.margin)}</span>
                    <StockBar percent={kind.billed ? (kind.cost / kind.billed) * 100 : 0} tone={kind.billed && kind.cost / kind.billed > 0.85 ? "warn" : null} />
                    <span className="hd-footnote">
                      {formatPounds(kind.billed)} billed · {formatPounds(kind.cost)} cost · {kind.lines} {kind.lines === 1 ? "line" : "lines"}
                      {kind.cost === 0 ? " · nothing costed against it" : ""}
                    </span>
                  </div>
                ))}
              </div>
            </Band>
            <Band tint title="The cost model" note="Stated here so a figure above can be argued with.">
              <div className="hd-stack">
                {WARDS.map((ward) => (
                  <div className="hd-row hd-row--quiet" key={ward.value}>
                    <div className="hd-row__text">
                      <span className="hd-row__title">{wardName(ward.value)}</span>
                      <span className="hd-row__note">Cost of one bed day on this ward</span>
                    </div>
                    <span className="hd-tile__value">{formatPounds(COST_RATES.bedDayByWard[ward.value])}</span>
                  </div>
                ))}
                <div className="hd-row hd-row--quiet">
                  <div className="hd-row__text">
                    <span className="hd-row__title">Theatre</span>
                    <span className="hd-row__note">Cost of one theatre minute, staffed</span>
                  </div>
                  <span className="hd-tile__value">{formatPoundsExact(COST_RATES.theatreMinute)}</span>
                </div>
                <div className="hd-row hd-row--quiet">
                  <div className="hd-row__text">
                    <span className="hd-row__title">Drugs</span>
                    <span className="hd-row__note">Doses in the course × the formulary unit cost</span>
                  </div>
                  <span className="hd-tile__value"><button type="button" className="hd-linkbtn" onClick={() => onNavigate("/formulary")}>Formulary</button></span>
                </div>
              </div>
            </Band>
          </div>
        </div>
      </>
    );
  }

  Object.assign(window, { ContractsScreen, CreditControlScreen, MarginScreen });
})();
