"use client";

import * as React from "react";

import { kes } from "@/components/medora/payroll";
import { Checkbox } from "@/components/ui/checkbox";
import { cn } from "@/lib/utils";
import { count } from "@/lib/format";

/*
 * Stock-take variance report (IN-13): after counts are applied, what the count changed, per item, valued
 * at cost and at selling price. Losses and gains are shown separately as well as netted, because a net of
 * zero can hide a large loss on one item offset by a miscount on another.
 */

export type VarianceLine = { item: string; unit: string; system: number; counted: number; cost: number; price: number; note?: string };

export function varianceTotals(lines: VarianceLine[]) {
  const t = { lossCost: 0, gainCost: 0, lossPrice: 0, gainPrice: 0, systemCost: 0, itemsOff: 0 };
  for (const l of lines) {
    const d = l.counted - l.system;
    t.systemCost += l.system * l.cost;
    if (d < 0) {
      t.lossCost += -d * l.cost;
      t.lossPrice += -d * l.price;
    } else if (d > 0) {
      t.gainCost += d * l.cost;
      t.gainPrice += d * l.price;
    }
    if (d) t.itemsOff++;
  }
  return t;
}

/** "boxes" → "box", "tubes" → "tube": units are stored plural. */
const one = (unit: string) => (unit.endsWith("xes") ? unit.slice(0, -2) : unit.replace(/s$/, ""));

export function StocktakeVariance({ reference, location, countedOn, countedBy, lines }: { reference: string; location: string; countedOn: string; countedBy: string; lines: VarianceLine[] }) {
  const [onlyDiffs, setOnlyDiffs] = React.useState(true);
  const t = varianceTotals(lines);
  const shown = (onlyDiffs ? lines.filter((l) => l.counted !== l.system) : lines).slice().sort((a, b) => (a.counted - a.system) * a.cost - (b.counted - b.system) * b.cost);
  const netCost = t.gainCost - t.lossCost;
  const netPrice = t.gainPrice - t.lossPrice;
  const shrink = t.systemCost ? (t.lossCost / t.systemCost) * 100 : 0;
  const tiles = [
    { label: "Lost (at cost)", value: `−${kes(t.lossCost)}`, sub: `−${kes(t.lossPrice)} at selling price` },
    { label: "Found (at cost)", value: `+${kes(t.gainCost)}`, sub: `+${kes(t.gainPrice)} at selling price` },
    { label: "Net change (at cost)", value: `${netCost < 0 ? "−" : "+"}${kes(Math.abs(netCost))}`, sub: `${netPrice < 0 ? "−" : "+"}${kes(Math.abs(netPrice))} at selling price` },
    { label: "Shrinkage", value: `${shrink.toFixed(2)}%`, sub: `of ${kes(t.systemCost)} expected stock` },
  ];
  return (
    <div className="space-y-3">
      <p className="text-sm text-muted-foreground">
        <span className="font-mono text-foreground">{reference}</span> · {location} · counted {countedOn} by {countedBy} · {t.itemsOff} of {lines.length} items differed
      </p>
      <div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
        {tiles.map((x) => (
          <div key={x.label} className="rounded-md border border-[var(--color-border-panel)] p-2 bg-card">
            <p className="text-xs text-muted-foreground">{x.label}</p>
            <p className="font-semibold tabular-nums">{x.value}</p>
            <p className="text-xs text-muted-foreground tabular-nums">{x.sub}</p>
          </div>
        ))}
      </div>
      <label className="flex items-center gap-2 text-sm">
        <Checkbox checked={onlyDiffs} onCheckedChange={(v) => setOnlyDiffs(!!v)} />
        Only items that differed
      </label>
      <div className="overflow-x-auto rounded-md border border-[var(--color-border-panel)] bg-card">
        <table className="w-full min-w-[720px] text-sm">
          <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
            <tr>
              <th className="px-3 py-2 font-medium">Item</th>
              <th className="px-3 py-2 text-right font-medium">Expected</th>
              <th className="px-3 py-2 text-right font-medium">Counted</th>
              <th className="px-3 py-2 text-right font-medium">Difference</th>
              <th className="px-3 py-2 text-right font-medium">At cost</th>
              <th className="px-3 py-2 text-right font-medium">At selling price</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-[var(--color-border-subtle)]">
            {shown.map((l) => {
              const d = l.counted - l.system;
              const sign = (v: number) => (v < 0 ? `−${kes(-v)}` : v > 0 ? `+${kes(v)}` : "–");
              return (
                <tr key={l.item}>
                  <td className="px-3 py-2">
                    {l.item}
                    {l.note ? <span className="block text-xs text-muted-foreground">“{l.note}”</span> : null}
                  </td>
                  <td className="px-3 py-2 text-right tabular-nums">{l.system}</td>
                  <td className="px-3 py-2 text-right tabular-nums">{l.counted}</td>
                  <td className={cn("px-3 py-2 text-right font-medium tabular-nums", d < 0 ? "text-status-error-text" : d > 0 ? "text-status-success-text" : "")}>
                    {d === 0 ? "None" : `${d < 0 ? "Short" : "Over"} ${Math.abs(d)} ${Math.abs(d) === 1 ? one(l.unit) : l.unit}`}
                  </td>
                  <td className="px-3 py-2 text-right tabular-nums">{sign(d * l.cost)}</td>
                  <td className="px-3 py-2 text-right tabular-nums">{sign(d * l.price)}</td>
                </tr>
              );
            })}
          </tbody>
          <tfoot className="border-t-2 border-[var(--color-border-panel)] bg-muted/30 font-semibold">
            <tr>
              <td colSpan={4} className="px-3 py-2">
                Net change ({count(t.itemsOff, "item")})
              </td>
              <td className="px-3 py-2 text-right tabular-nums">{netCost < 0 ? `−${kes(-netCost)}` : `+${kes(netCost)}`}</td>
              <td className="px-3 py-2 text-right tabular-nums">{netPrice < 0 ? `−${kes(-netPrice)}` : `+${kes(netPrice)}`}</td>
            </tr>
          </tfoot>
        </table>
      </div>
    </div>
  );
}
