"use client";

import * as React from "react";
import { BanknoteIcon, FileTextIcon, SendIcon, ShoppingCartIcon, XIcon } from "lucide-react";

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import { AssetHistory, autoMatch, ClaimBadge, ClaimPaymentForm, claimsByScheme, depreciation, depreciationSchedule, PettyCashBook, PettyEntryForm, QuoteCheck, Reconciler, type Asset, type AssetEvent, type Claim, type PettyEntry, type QuoteLine, type RecLine } from "@/components/medora/accounts-ops";
import { RecordDrawer } from "@/components/medora/drawer";
import { RowActions } from "@/components/medora/row-actions";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { toast } from "@/components/ui/toast";
import { formatDate, TODAY } from "@/lib/mock-data";
import { cn } from "@/lib/utils";

const fd = (d: string) => formatDate(d);
const n2 = (n: number) => n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });

const STATEMENT: RecLine[] = [
  { id: "s1", date: "2026-10-02", ref: "DEP 004412", details: "Cash deposit, Westlands", amount: 120000 },
  { id: "s2", date: "2026-10-06", ref: "EFT 88120", details: "Dawa Distributors Ltd", amount: -84300 },
  { id: "s3", date: "2026-10-09", ref: "SO 2210", details: "Sarit Centre rent", amount: -180000 },
  { id: "s4", date: "2026-10-15", ref: "RTGS 55102", details: "Aga Khan Hospital", amount: 52150 },
  { id: "s5", date: "2026-10-18", ref: "CHG", details: "Ledger fees, October", amount: -1250 },
  { id: "s6", date: "2026-10-19", ref: "CHG SMS", details: "SMS alert charges", amount: -350 },
];
const BOOK: RecLine[] = [
  { id: "b1", date: "2026-10-02", ref: "DRP-2026-0141", details: "Cash drop from Westlands drawer", amount: 120000 },
  { id: "b2", date: "2026-10-05", ref: "PAY-0101", details: "Payment to Dawa Distributors Ltd", amount: -84300 },
  { id: "b3", date: "2026-10-09", ref: "EXP-2026-0230", details: "October rent", amount: -180000 },
  { id: "b4", date: "2026-10-14", ref: "RCP-2026-0077", details: "Aga Khan Hospital, INV-2026-00741", amount: 52150 },
  { id: "b5", date: "2026-10-18", ref: "JV-2026-0411", details: "Bank charges, October", amount: -1250 },
  { id: "b6", date: "2026-10-20", ref: "DRP-2026-0150", details: "Cash drop from Westlands drawer", amount: 36500 },
];

function ReconcileDemo() {
  const [book, setBook] = React.useState(BOOK);
  const [matches, setMatches] = React.useState<Record<string, string>>({});
  const [ran, setRan] = React.useState(false);
  const recorded = book.some((b) => b.id === "b7");
  return (
    <Example title="Reconcile Equity Bank, October statement" description="Auto-match pairs same amounts within 3 days. The SMS charge isn't in Medora yet; record it, and the outstanding cash drop carries forward" bare>
      <div className="flex flex-wrap gap-2 border-b border-border px-4 py-3">
        <Button
          size="sm"
          variant="outline"
          onClick={() => {
            setMatches(autoMatch(STATEMENT, book));
            setRan(true);
          }}
        >
          Auto-match
        </Button>
        <Button
          size="sm"
          variant="outline"
          disabled={!ran || recorded}
          onClick={() => {
            setBook((b) => [...b, { id: "b7", date: "2026-10-19", ref: "JV-2026-0413", details: "SMS alert charges", amount: -350 }]);
            setMatches((m) => ({ ...m, s6: "b7" }));
            toast.add({ title: "Journal JV-2026-0413 posted", description: "Bank charges 6100 debit, Equity Bank 1040 credit, KES 350.00." });
          }}
        >
          Record SMS charge (KES 350.00)
        </Button>
      </div>
      <div className="p-4">
        <Reconciler
          statement={STATEMENT}
          book={book}
          opening={506000}
          closing={412250}
          matches={matches}
          formatDate={fd}
          onUnmatch={(sid) =>
            setMatches((m) => {
              const n = { ...m };
              delete n[sid];
              return n;
            })
          }
          onMatch={(sid, bid) => setMatches((m) => ({ ...m, [sid]: bid }))}
        />
      </div>
    </Example>
  );
}

const CLAIMS: Claim[] = [
  { ref: "CLM-2026-0101", scheme: "AAR Insurance", member: "Mary Wambui", sale: "SALE-005188", date: "2026-10-18", claimed: 2205, paid: 0, status: "Draft" },
  { ref: "CLM-2026-0094", scheme: "AAR Insurance", member: "Ali Hassan", sale: "SALE-005060", date: "2026-09-21", submitted: "2026-09-22", claimed: 8400, paid: 0, status: "Submitted" },
  { ref: "CLM-2026-0088", scheme: "Jubilee Health", member: "Kevin Otieno", sale: "SALE-004990", date: "2026-09-02", submitted: "2026-09-03", claimed: 5600, paid: 4200, status: "Part paid", reason: "Paid at scheme tariff" },
  { ref: "CLM-2026-0079", scheme: "Madison", member: "Faith Njeri", sale: "SALE-004870", date: "2026-08-11", submitted: "2026-08-12", claimed: 3150, paid: 0, status: "Rejected", reason: "Member not active on date of service" },
  { ref: "CLM-2026-0071", scheme: "Jubilee Health", member: "Rose Akinyi", sale: "SALE-004791", date: "2026-07-28", submitted: "2026-07-29", claimed: 4800, paid: 4800, status: "Paid" },
];

function ClaimsDemo() {
  const [claims, setClaims] = React.useState(CLAIMS);
  const [paying, setPaying] = React.useState<Claim | null>(null);
  const summary = claimsByScheme(claims, TODAY);
  const set = (ref: string, patch: Partial<Claim>) => setClaims((xs) => xs.map((x) => (x.ref === ref ? { ...x, ...patch } : x)));
  const raised = claims.some((c) => c.sale === "SALE-005200");
  return (
    <Example title="Insurance claims" description="Raised from a sale to a scheme member for the scheme's share; submitted; then paid, part paid (or written off with the scheme's reason) or rejected. Each scheme shows what's still due" bare>
      <div className="flex justify-end border-b border-border px-4 py-3">
        <Button
          size="sm"
          variant="outline"
          disabled={raised}
          onClick={() => {
            setClaims((xs) => [{ ref: "CLM-2026-0102", scheme: "AAR Insurance", member: "Mary Wambui", sale: "SALE-005200", date: TODAY, claimed: 1070.1, paid: 0, status: "Draft" }, ...xs]);
            toast.add({ title: "Claim CLM-2026-0102 raised", description: "From SALE-005200: the scheme's 90% share of KES 1,189.00." });
          }}
        >
          Raise claim from SALE-005200
        </Button>
      </div>
      <div className="space-y-4 p-4">
        <div className="grid gap-3 sm:grid-cols-3">
          {summary.map(([scheme, s]) => (
            <div key={scheme} className="rounded-lg border border-[var(--color-border-panel)] bg-card p-3 text-sm">
              <p className="font-semibold">{scheme}</p>
              <p className="tabular-nums">Due KES {n2(s.due)}</p>
              <p className="text-xs text-muted-foreground tabular-nums">
                Claimed {n2(s.claimed)} · received {n2(s.paid)}
                {s.oldest ? <span className={cn(s.oldest > 30 && "font-medium text-status-warning-text")}> · oldest waiting {s.oldest} days</span> : null}
              </p>
            </div>
          ))}
        </div>
        <div className="overflow-x-auto rounded-lg border border-[var(--color-border-panel)]">
          <table className="w-full border-collapse text-sm tabular-nums">
            <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
              <tr>
                {["Claim", "Scheme and member", "Sale", "Claimed", "Paid", "Status", ""].map((h, i) => (
                  <th key={i} scope="col" className={cn("px-3 py-2 font-medium", (h === "Claimed" || h === "Paid") && "text-right")}>
                    {h || <span className="sr-only">Actions</span>}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody className="divide-y divide-[var(--color-border-subtle)]">
              {claims.map((c) => (
                <tr key={c.ref}>
                  <td className="px-3 py-2 font-mono text-xs">
                    {c.ref}
                    <span className="block font-sans text-muted-foreground">{fd(c.date)}</span>
                  </td>
                  <td className="px-3 py-2">
                    {c.scheme}
                    <span className="block text-xs text-muted-foreground">{c.member}</span>
                  </td>
                  <td className="px-3 py-2 font-mono text-xs">{c.sale}</td>
                  <td className="px-3 py-2 text-right">{n2(c.claimed)}</td>
                  <td className="px-3 py-2 text-right">{c.paid ? n2(c.paid) : "–"}</td>
                  <td className="px-3 py-2">
                    <ClaimBadge status={c.status} />
                    {c.reason ? <span className="mt-0.5 block text-xs text-muted-foreground">{c.reason}</span> : null}
                  </td>
                  <td className="px-2 py-2 text-right">
                    <RowActions
                      label={c.ref}
                      actions={
                        c.status === "Draft"
                          ? [{ label: "Submit to scheme", icon: SendIcon, onSelect: () => (set(c.ref, { status: "Submitted", submitted: TODAY }), toast.add({ title: `${c.ref} submitted to ${c.scheme}` })) }]
                          : c.status === "Submitted" || c.status === "Part paid"
                            ? [
                                { label: "Record payment…", icon: BanknoteIcon, onSelect: () => setPaying(c) },
                                { label: "Mark rejected…", icon: XIcon, destructive: true, onSelect: () => set(c.ref, { status: "Rejected", reason: "Rejected by the scheme" }) },
                              ]
                            : []
                      }
                    />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      {paying ? (
        <RecordDrawer open onOpenChange={(o) => !o && setPaying(null)} title={`Payment for ${paying.ref}`} subtitle={`${paying.scheme} · ${paying.member}`}>
          <ClaimPaymentForm
            claim={paying}
            onSave={(p) => {
              const paid = Math.round((paying.paid + p.amount) * 100) / 100;
              const settled = p.writeOff || paid >= paying.claimed;
              set(paying.ref, { paid, status: settled ? "Paid" : "Part paid", reason: p.writeOff ? `${p.reason} (written off KES ${n2(paying.claimed - paid)})` : paying.reason });
              toast.add({ title: `KES ${n2(p.amount)} recorded`, description: `${paying.ref} is now ${settled ? "paid" : "part paid"}. Ref ${p.reference}.` });
              setPaying(null);
            }}
          />
        </RecordDrawer>
      ) : null}
    </Example>
  );
}

const PETTY: PettyEntry[] = [
  { id: "e1", date: "2026-10-01", kind: "Top-up", details: "Restore float", amount: 3150, voucher: "PC-TOP-019", receipt: true },
  { id: "e2", date: "2026-10-03", kind: "Spend", category: "Cleaning", details: "Detergent and mops", amount: 1240, voucher: "PC-0201", receipt: true },
  { id: "e3", date: "2026-10-07", kind: "Spend", category: "Transport", details: "Boda to Kilimani with transfer", amount: 300, voucher: "PC-0202", receipt: false },
  { id: "e4", date: "2026-10-11", kind: "Spend", category: "Office", details: "Printer paper, 2 reams", amount: 1100, voucher: "PC-0203", receipt: true },
  { id: "e5", date: "2026-10-16", kind: "Spend", category: "Staff tea", details: "Milk and sugar", amount: 450, voucher: "PC-0204", receipt: true },
];

const ASSETS: Asset[] = [
  { code: "AST-001", name: "Pharmacy fridge, 400 L", category: "Equipment", location: "Westlands, Dispensary", serial: "LG-7741-K", bought: "2024-03-15", cost: 185000, ratePct: 12.5, status: "In use" },
  { code: "AST-002", name: "POS terminal and printer", category: "Computers", location: "Westlands, Front shop", allocatedTo: "Kevin Mutua", bought: "2025-07-01", cost: 96000, ratePct: 33.33, status: "In use" },
  { code: "AST-003", name: "Delivery motorbike", category: "Vehicles", location: "Westlands", allocatedTo: "Ali Hassan", serial: "KMFA 221Q", bought: "2023-01-10", cost: 165000, ratePct: 25, status: "In repair" },
];

const EVENTS: Record<string, AssetEvent[]> = {
  "AST-001": [
    { id: "a1", date: "2024-03-15", kind: "Moved", detail: "Installed in Westlands, Dispensary", by: "Peter Kamau" },
    { id: "a2", date: "2025-08-02", kind: "Maintenance", detail: "Thermostat replaced, Coolserve Ltd", cost: 6500, by: "Peter Kamau" },
  ],
  "AST-002": [{ id: "b1", date: "2025-07-01", kind: "Allocated", detail: "To Kevin Mutua, Till 1", by: "Grace Wanjiru" }],
  "AST-003": [
    { id: "c1", date: "2023-01-10", kind: "Allocated", detail: "To Ali Hassan for deliveries", by: "Peter Kamau" },
    { id: "c2", date: "2026-10-14", kind: "Maintenance", detail: "Gearbox repair, in the workshop until 25 Oct", cost: 18400, by: "Peter Kamau" },
  ],
};

function PettyAndAssetsDemo() {
  const [asset, setAsset] = React.useState(ASSETS[0].code);
  const [assets, setAssets] = React.useState(ASSETS);
  const [events, setEvents] = React.useState(EVENTS);
  const [petty, setPetty] = React.useState(PETTY);
  const a = assets.find((x) => x.code === asset)!;
  const pettyBalance = petty.reduce((s, e) => s + (e.kind === "Top-up" ? e.amount : -e.amount), 1850);
  const log = (code: string, e: Omit<AssetEvent, "id" | "date" | "by">) => setEvents((x) => ({ ...x, [code]: [...(x[code] ?? []), { ...e, id: `${code}-${Date.now()}`, date: TODAY, by: "Grace Wanjiru" }] }));
  return (
    <>
      <Example title="Petty cash, Westlands" description="Float KES 5,000.00; KES 1,850.00 was left on 1 Oct and topped up. A spend can't exceed what's in the box; over KES 500 needs a receipt">
        <div className="space-y-4">
          <PettyEntryForm
            balance={pettyBalance}
            float={5000}
            categories={["Cleaning", "Transport", "Office", "Staff tea", "Repairs"]}
            receiptFreeLimit={500}
            onSave={(e) => {
              const voucher = e.kind === "Spend" ? `PC-0${205 + petty.length - 5}` : `PC-TOP-0${20 + petty.length - 5}`;
              setPetty((xs) => [...xs, { ...e, id: voucher, date: TODAY, voucher }]);
              toast.add({ title: `Voucher ${voucher} recorded` });
            }}
          />
          <PettyCashBook float={5000} opening={1850} entries={petty} formatDate={fd} />
        </div>
      </Example>
      <Example title="Asset register" description="Straight-line at the yearly % of cost, by whole months. Choose an asset to see its schedule" bare>
        <div className="space-y-4 p-4">
          <div className="overflow-x-auto rounded-lg border border-[var(--color-border-panel)]">
            <table className="w-full border-collapse text-sm tabular-nums">
              <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
                <tr>
                  {["Asset", "Where and who", "Cost", "Rate", "Depreciated", "Book value"].map((h) => (
                    <th key={h} scope="col" className={cn("px-3 py-2 font-medium", ["Cost", "Rate", "Depreciated", "Book value"].includes(h) && "text-right")}>
                      {h}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody className="divide-y divide-[var(--color-border-subtle)]">
                {assets.map((x) => {
                  const d = depreciation(x, TODAY);
                  return (
                    <tr key={x.code} className={cn(x.code === asset && "bg-[var(--color-bg-selected)]")}>
                      <th scope="row" className="px-3 py-2 text-left font-medium">
                        <button type="button" className="cursor-pointer text-left underline-offset-2 hover:underline" onClick={() => setAsset(x.code)} aria-pressed={x.code === asset}>
                          {x.name}
                        </button>
                        <span className="block font-mono text-xs font-normal text-muted-foreground">
                          {x.code}
                          {x.serial ? ` · ${x.serial}` : ""}
                        </span>
                      </th>
                      <td className="px-3 py-2">
                        {x.location}
                        <span className="block text-xs text-muted-foreground">
                          {x.allocatedTo ?? "Not allocated"} · {x.status}
                        </span>
                      </td>
                      <td className="px-3 py-2 text-right">{n2(x.cost)}</td>
                      <td className="px-3 py-2 text-right">{x.ratePct}%</td>
                      <td className="px-3 py-2 text-right">{n2(d.accumulated)}</td>
                      <td className="px-3 py-2 text-right font-semibold">{n2(d.nbv)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
          <div>
            <h4 className="mb-1.5 text-sm font-semibold">
              Schedule: {a.name}, bought {fd(a.bought)}
            </h4>
            <div className="overflow-x-auto rounded-lg border border-[var(--color-border-panel)]">
              <table className="w-full border-collapse text-sm tabular-nums">
                <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
                  <tr>
                    <th scope="col" className="px-3 py-2 font-medium">
                      Year
                    </th>
                    <th scope="col" className="px-3 py-2 text-right font-medium">
                      Depreciation
                    </th>
                    <th scope="col" className="px-3 py-2 text-right font-medium">
                      Book value at year end
                    </th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-[var(--color-border-subtle)]">
                  {depreciationSchedule(a).map((r) => (
                    <tr key={r.year} className={cn(String(r.year) === TODAY.slice(0, 4) && "font-semibold")}>
                      <td className="px-3 py-1.5">{r.year}</td>
                      <td className="px-3 py-1.5 text-right">{n2(r.charge)}</td>
                      <td className="px-3 py-1.5 text-right">{n2(r.nbv)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
          <div className="space-y-2">
            <div className="flex flex-wrap items-center justify-between gap-2">
              <h4 className="text-sm font-semibold">History: {a.name}</h4>
              <div className="flex flex-wrap gap-2">
                {a.allocatedTo ? (
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => {
                      log(a.code, { kind: "Revoked", detail: `Returned by ${a.allocatedTo}` });
                      setAssets((xs) => xs.map((x) => (x.code === a.code ? { ...x, allocatedTo: undefined } : x)));
                    }}
                  >
                    Revoke from {a.allocatedTo}
                  </Button>
                ) : (
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => {
                      log(a.code, { kind: "Allocated", detail: "To Grace Wanjiru" });
                      setAssets((xs) => xs.map((x) => (x.code === a.code ? { ...x, allocatedTo: "Grace Wanjiru" } : x)));
                    }}
                  >
                    Allocate to Grace Wanjiru
                  </Button>
                )}
                <Button size="sm" variant="outline" onClick={() => log(a.code, { kind: "Maintenance", detail: "Service visit", cost: 2500 })}>
                  Log a KES 2,500 service
                </Button>
              </div>
            </div>
            <AssetHistory events={events[a.code] ?? []} formatDate={fd} />
          </div>
        </div>
      </Example>
    </>
  );
}

const QUOTE: QuoteLine[] = [
  { id: "q1", name: "Surgical gloves, box of 100", qty: 20, quoted: 950, current: 990, inStock: 34 },
  { id: "q2", name: "Hand sanitiser 5 L", qty: 6, quoted: 2400, current: 2400, inStock: 4 },
  { id: "q3", name: "Face masks, box of 50", qty: 30, quoted: 450, current: 420, inStock: 120 },
];

function QuoteDemo() {
  const [honour, setHonour] = React.useState(true);
  return (
    <Example title="Convert quotation QUO-2026-00112" description="Aga Khan Hospital, valid until 3 Oct 2026. Checked against today's prices and stock before it becomes an invoice or a sale" bare>
      <div className="space-y-3 p-4">
        <p className="rounded-md border border-status-warning-border bg-status-warning-bg px-3 py-2 text-sm text-status-warning-text">This quotation expired 17 days ago. Honour the quoted prices, or use today&apos;s and tell the customer.</p>
        <label className="flex items-center gap-2 text-sm">
          <Switch checked={honour} onCheckedChange={setHonour} /> Honour quoted prices
        </label>
        <QuoteCheck lines={QUOTE} honour={honour} />
        <p className="text-sm text-muted-foreground">Hand sanitiser is 2 short: the invoice can go now and the rest follows on a delivery note, or wait for stock.</p>
        <div className="flex flex-wrap justify-end gap-2">
          <Button variant="outline" onClick={() => toast.add({ title: "Sale opened at the till", description: "QUO-2026-00112 lines added." })}>
            <ShoppingCartIcon data-icon="inline-start" />
            Convert to sale
          </Button>
          <Button onClick={() => toast.add({ title: "Invoice INV-2026-00790 created", description: `At ${honour ? "quoted" : "today's"} prices; QUO-2026-00112 marked Converted.` })}>
            <FileTextIcon data-icon="inline-start" />
            Convert to invoice
          </Button>
        </div>
      </div>
    </Example>
  );
}

export function AccountsOpsSection() {
  return (
    <Section
      id="accounts-ops"
      title="Reconciliation, claims, petty cash, assets and quotations"
      description="Accounts work around the ledger. Each shows the figure that matters and how it was reached: the difference left to reconcile, what a scheme still owes, the top-up a float needs, an asset's book value, and how a quotation's prices changed."
    >
      <ReconcileDemo />
      <ClaimsDemo />
      <PettyAndAssetsDemo />
      <QuoteDemo />
    </Section>
  );
}
