// Inventory valuation tab — Task 5 of docs/superpowers/plans/2026-08-03-inventory.md.
// GET /api/c/reports/inventory-valuation?asOf= (server/src/reports.ts) does all
// the deriving; this formats it and puts the tie on the report's face.
//
// See reports/inventoryValuationData.ts for why the tie is per account rather
// than one total, and why neither of its two numbers is stored.
//
// The value column here IS the inventory line on the balance sheet, account by
// account — that is what the tie asserts. So the report says so, and links each
// account through to its own register (CLAUDE.md §9, "every number drills
// through").

import { useState } from "react";
import { useCompany } from "../lib/company";
import { useApiGet } from "../lib/useApiGet";
import { fmtMoney } from "../lib/money";
import { fmtDate, todayIso } from "../lib/date";
import { ErrorBanner } from "../components/ErrorBanner";
import { fmtQuantity, fmtUnitCost } from "../items/itemTypes";
import type { NavTarget } from "../lib/useHashView";
import {
  groupByAccount, tieExplanation, tieLine, tieVerdict,
  type ValuationAccount, type ValuationData,
} from "./inventoryValuationData";

export function InventoryValuationReport({
  navigate,
}: {
  navigate: (target: NavTarget) => void;
}) {
  const { selectedCompanyId } = useCompany();
  const [asOf, setAsOf] = useState(todayIso());

  const { data, loading, error, retry } = useApiGet<ValuationData>(
    `/api/c/reports/inventory-valuation?asOf=${asOf}`,
    selectedCompanyId,
  );

  const groups = data ? groupByAccount(data) : [];
  const hasRows = groups.some((g) => g.items.length > 0) || (data?.accounts.length ?? 0) > 0;

  return (
    <div>
      <div className="report-toolbar">
        <div className="date-inputs">
          <label>
            As of
            <input type="date" value={asOf} onChange={(ev) => setAsOf(ev.target.value)} />
          </label>
        </div>
        <button
          type="button"
          className="btn print-btn"
          onClick={() =>
            navigate({ view: "print", printType: "inventory-valuation", params: { asOf } })
          }
        >
          Print / Save as PDF
        </button>
      </div>

      {error && <ErrorBanner message={error} onRetry={retry} />}
      {loading && !data && <p className="msg-inline">Loading&hellip;</p>}
      {!loading && !error && data && !hasRows && (
        <div className="empty-state">
          Nothing on the shelf as of this date. Stocked items appear here once a bill, a build or an
          opening count has put some of them on it.
        </div>
      )}

      {data && hasRows && (
        <>
          <div
            className={data.ties ? "confirm-panel" : "error-banner banner-stack"}
            style={{ marginBottom: 16 }}
          >
            <p style={{ marginBottom: 0 }}>
              <strong>
                {data.ties
                  ? "Your stock ties to your books."
                  : "Your stock does not tie to your books."}
              </strong>{" "}
              {tieVerdict(data)}
            </p>
          </div>

          {groups.map((group) => (
            <div
              className="card"
              style={{ marginBottom: 18 }}
              key={group.account?.accountId ?? "unattached"}
            >
              <h2>
                {group.account ? (
                  <button
                    type="button"
                    className="acct-link"
                    onClick={() =>
                      navigate({ view: "transactions", accountId: group.account!.accountId })
                    }
                  >
                    {group.account.name}
                  </button>
                ) : (
                  "Not in an inventory account"
                )}
              </h2>

              {group.items.length === 0 ? (
                <p className="sub">
                  No stock left in this account as of {fmtDate(asOf)}.
                </p>
              ) : (
                <table>
                  <thead>
                    <tr>
                      <th>Item</th>
                      <th className="num">On hand</th>
                      <th className="num">Average cost</th>
                      <th className="num">Value</th>
                    </tr>
                  </thead>
                  <tbody>
                    {group.items.map((item) => (
                      <tr
                        key={item.itemId}
                        style={{ cursor: "pointer" }}
                        onClick={() => navigate({ view: "item", id: item.itemId })}
                      >
                        <td>
                          {item.name}
                          {item.sku && <div className="register-memo-sub">SKU {item.sku}</div>}
                        </td>
                        <td className="num">{fmtQuantity(item.qtyOnHand)}</td>
                        <td className="num">{fmtUnitCost(item.averageCost)}</td>
                        <td className="num">{fmtMoney(item.value)}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}

              {group.account && (
                <TieFooter account={group.account} />
              )}
              {!group.account && (
                <p className="sub" style={{ marginBottom: 0 }}>
                  These items don&rsquo;t point at an inventory account, so there is nothing on the
                  balance sheet for them to tie to. Open each one and set its inventory account.
                </p>
              )}
            </div>
          ))}

          <div className="card">
            <div className="rows">
              <div className="row total">
                <span className="n">Everything on the shelf, as of {fmtDate(asOf)}</span>
                <span className="a">{fmtMoney(data.totalValue)}</span>
              </div>
            </div>
            <p className="sub" style={{ marginBottom: 0 }}>
              This is the inventory total on your balance sheet for the same date. Nothing here is
              stored: every figure is worked out from your stock movements and your journal entries
              the moment you ask for it.
            </p>
          </div>
        </>
      )}
    </div>
  );
}

/** The tie, on the face of the account it belongs to. Shared shape with the
 *  print view (PrintInventoryValuation.tsx) — same sentence, same classes. */
export function TieFooter({ account }: { account: ValuationAccount }) {
  const explanation = tieExplanation(account);
  return (
    <>
      <p className={`tie-line${explanation ? " tie-line-bad" : ""}`}>{tieLine(account)}</p>
      {explanation && <p className="tie-explain">{explanation}</p>}
    </>
  );
}
