"use client";

import * as React from "react";

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import { TopCustomers } from "@/components/medora/customer-reports";
import { ExpenseForm, ExpensePaymentsReport, expenseProblems, type ExpenseDraft } from "@/components/medora/expenses";
import { HeldOrdersLog, type HeldOrder, type ProcessedHold } from "@/components/medora/held-orders";
import { LabelPrintPlan, LabelSizes, type LabelSize } from "@/components/medora/label-plan";
import { productProblems, ProductRecordForm, type ProductDraft, type ProductLists } from "@/components/medora/product-record";
import { StocktakeVariance } from "@/components/medora/stocktake-variance";
import { AppearanceSummary, UserMenu, type Appearance } from "@/components/medora/user-menu";
import { Button } from "@/components/ui/button";
import { toast } from "@/components/ui/toast";
import { TODAY } from "@/lib/mock-data";

/* ------------------------------------ Product record (IN-01, IN-04) ------------------------------------ */

const LISTS: ProductLists = {
  categories: { Antibiotics: ["Penicillins", "Macrolides"], Analgesics: ["Paracetamol", "NSAIDs"], Dermatology: ["Emollients"], Vitamins: [] },
  brands: ["GSK", "Cosmos", "Beiersdorf", "Dawa Ltd"],
  units: ["Tablet", "Capsule", "Millilitre", "Strip", "Box"],
  suppliers: ["Harleys Ltd", "Dawa Ltd", "Surgipharm", "Cosmos Ltd"],
  taxCodes: [
    { code: "A", label: "Exempt" },
    { code: "B", label: "VAT 16%" },
    { code: "C", label: "Zero-rated" },
  ],
  shelves: ["A1 Analgesics", "B2 Antibiotics", "C1 Diabetes", "D3 Skin care"],
  itemClasses: [
    { code: "51101500", label: "Antibacterials" },
    { code: "51142100", label: "Analgesics" },
    { code: "53131600", label: "Skin care" },
  ],
  itemTypes: [
    { code: "1", label: "Raw material" },
    { code: "2", label: "Finished product" },
    { code: "3", label: "Service" },
  ],
  origins: [
    { code: "KE", label: "Kenya" },
    { code: "IN", label: "India" },
    { code: "GB", label: "United Kingdom" },
  ],
  packaging: [
    { code: "BX", label: "Box" },
    { code: "BL", label: "Blister" },
    { code: "BT", label: "Bottle" },
  ],
};

function ProductRecordDemo() {
  const [d, setD] = React.useState<ProductDraft>({
    type: "Product",
    name: "Augmentin 625 mg tablets, 14s",
    code: "ANT-0042",
    barcode: "6164001234567",
    description: "Amoxicillin and clavulanic acid",
    category: "Antibiotics",
    subCategory: "Penicillins",
    brand: "GSK",
    unit: "Box",
    supplier: "Surgipharm",
    cost: "1020",
    price: "1260",
    taxCode: "A",
    rx: true,
    minMargin: "20",
    manageStock: true,
    image: "",
    reorderLevel: "10",
    reorderQty: "",
    shelf: "B2 Antibiotics",
    hsCode: "3004.10",
    itemClass: "51101500",
    itemType: "",
    origin: "",
    packaging: "BX",
  });
  const [tried, setTried] = React.useState(false);
  const { problems, etimsGaps } = productProblems(d, { codes: ["ANT-0041"], barcodes: ["6161100000137"] }, LISTS);
  return (
    <Example title="Product record" description="Save as it is: the barcode's check digit is wrong, the price gives 19% against a 20% minimum margin, and two eTIMS codes are missing (allowed, but it can't go on an eTIMS receipt yet). Try Service to see the stock fields drop away">
      <ProductRecordForm d={d} onChange={setD} lists={LISTS} problems={problems} etimsGaps={etimsGaps} show={tried} />
      <div className="mt-4 flex justify-end">
        <Button
          onClick={() => {
            setTried(true);
            if (Object.keys(problems).length) return;
            toast.add({ title: `${d.name} saved`, description: etimsGaps.length ? `Not yet registered with KRA: add the ${etimsGaps.join(" and ")}.` : "Registered with KRA for eTIMS." });
          }}
        >
          Save product
        </Button>
      </div>
    </Example>
  );
}

export function ProductRecordSection() {
  return (
    <Section id="product-record" title="Product record" description="IN-01 and IN-04: every field a product carries, in tabs that count their problems. Lists come from the setup lists, never free text. eTIMS codes may be added later, but the badge and toast say plainly that the item can't be sold on an eTIMS receipt until they're complete.">
      <ProductRecordDemo />
    </Section>
  );
}

/* ------------------------------------ Expenses (AC-16) ------------------------------------ */

const EXP_CATS = [
  { name: "Rent", account: "6000 Rent" },
  { name: "Electricity", account: "6200 Utilities" },
  { name: "Water", account: "6200 Utilities" },
  { name: "Internet", account: "6210 Communication" },
  { name: "Cleaning", account: "6300 Cleaning" },
  { name: "Delivery and transport", account: "6400 Transport" },
  { name: "Security", account: "6500 Security" },
  { name: "Repairs", account: "6600 Repairs and maintenance" },
  { name: "Advertising", account: "6700 Marketing" },
  { name: "Bank charges", account: "6100 Bank charges" },
];
const PAYERS = [
  { name: "Equity Bank", account: "1040 Equity Bank" },
  { name: "M-Pesa till 512330", account: "1021 M-Pesa till 512330" },
  { name: "Petty cash, Westlands", account: "1015 Petty cash, Westlands" },
];

function ExpenseDemo() {
  const [d, setD] = React.useState<ExpenseDraft>({ category: "Electricity", date: TODAY, amount: "12,840", vatClaimable: true, supplier: "Kenya Power", reference: "SEP-26-118204", cuNo: "", paidFrom: "Equity Bank", branch: "Westlands Main", note: "" });
  const [tried, setTried] = React.useState(false);
  const { problems, warnings } = expenseProblems(d, TODAY, ["kenya power|sep-26-118204"]);
  return (
    <Example title="Record an expense" description="VAT is ticked but there's no CU number, and this Kenya Power reference is already recorded. The ledger entry updates as you type">
      <ExpenseForm d={d} onChange={setD} categories={EXP_CATS} payers={PAYERS} branches={["Westlands Main", "Kilimani", "Nyali", "Milimani"]} problems={problems} warnings={warnings} show={tried} />
      <div className="mt-4 flex justify-end">
        <Button
          onClick={() => {
            setTried(true);
            if (!Object.keys(problems).length) toast.add({ title: "Expense recorded", description: `${d.category}, KES ${d.amount}, posted to the ledger.` });
          }}
        >
          Save expense
        </Button>
      </div>
    </Example>
  );
}

export function ExpensesSection() {
  return (
    <Section id="expenses" title="Expenses" description="AC-16: category, date, amount, supplier, reference and CU invoice number, posting to the ledger. The entry it will make is shown before saving. The payments report groups the period's expenses by category and by the account they were paid from.">
      <ExpenseDemo />
      <Example title="Expenses payment report" description="Open a category to see its payments">
        <ExpensePaymentsReport
          period="1–20 Oct 2026, all branches"
          rows={[
            { ref: "EXP-0401", date: "2026-10-01", category: "Rent", supplier: "Sarit Centre Ltd", paidFrom: "Equity Bank", amount: 85000, vat: 0 },
            { ref: "EXP-0412", date: "2026-10-19", category: "Electricity", supplier: "Kenya Power", paidFrom: "Equity Bank", amount: 12840, vat: 1771.03 },
            { ref: "EXP-0405", date: "2026-10-06", category: "Water", supplier: "Nairobi Water", paidFrom: "M-Pesa till 512330", amount: 3210, vat: 0 },
            { ref: "EXP-0403", date: "2026-10-03", category: "Internet", supplier: "Safaricom", paidFrom: "M-Pesa till 512330", amount: 4640, vat: 640 },
            { ref: "PC-0088", date: "2026-10-18", category: "Cleaning", paidFrom: "Petty cash, Westlands", amount: 1350, vat: 0 },
            { ref: "EXP-0409", date: "2026-10-14", category: "Delivery and transport", supplier: "Sendy", paidFrom: "M-Pesa till 512330", amount: 9860, vat: 0 },
            { ref: "EXP-0402", date: "2026-10-01", category: "Security", supplier: "SGA Security", paidFrom: "Equity Bank", amount: 18000, vat: 0 },
            { ref: "EXP-0415", date: "2026-10-20", category: "Bank charges", paidFrom: "Equity Bank", amount: 1450, vat: 0 },
            { ref: "EXP-0407", date: "2026-10-09", category: "Advertising", supplier: "Radio Jambo", paidFrom: "Equity Bank", amount: 23000, vat: 3172.41 },
            { ref: "EXP-0410", date: "2026-10-15", category: "Repairs", supplier: "CoolAir Ltd", paidFrom: "Equity Bank", amount: 35000, vat: 4827.59 },
          ]}
        />
      </Example>
    </Section>
  );
}

/* ------------------------------------ Stock-take variance (IN-13) ------------------------------------ */

export function StocktakeVarianceSection() {
  return (
    <Section id="stocktake-variance" title="Stock-take variance report" description="IN-13: after counts are applied, what each stock take changed, at cost and at selling price. Losses and finds are shown separately as well as netted, so a large loss can't hide behind a miscount elsewhere.">
      <Example title="ST-2026-041" description="Applied 20 Oct 2026">
        <StocktakeVariance
          reference="ST-2026-041"
          location="Westlands Main, Dispensary"
          countedOn="20 Oct 2026"
          countedBy="Peter Kamau"
          lines={[
            { item: "Panadol 500 mg, strip", unit: "strips", system: 420, counted: 412, cost: 32, price: 58, note: "Two opened boxes on the counter" },
            { item: "Amoxil 500 mg, 21s", unit: "packs", system: 48, counted: 48, cost: 210, price: 320 },
            { item: "Nivea Soft cream 200 ml", unit: "tubes", system: 18, counted: 17, cost: 455, price: 610 },
            { item: "Calamine lotion 100 ml", unit: "bottles", system: 22, counted: 24, cost: 160, price: 240, note: "Two found in the store room" },
            { item: "Augmentin 625 mg, 14s", unit: "boxes", system: 40, counted: 37, cost: 1020, price: 1260 },
            { item: "Metformin 500 mg, 100s", unit: "packs", system: 14, counted: 14, cost: 330, price: 450 },
          ]}
        />
      </Example>
    </Section>
  );
}

/* ------------------------------------ Top bar and user menu (DB-12, ST-17) ------------------------------------ */

export function UserMenuSection() {
  const [a, setA] = React.useState<Appearance>({ sidebar: "light", text: "default" });
  return (
    <Section id="user-menu" title="Top bar identity and user menu" description="DB-12 and ST-17: the top bar always shows who is signed in, their role and branch. Profile, Appearance and password live in the user's own menu, not in Settings. The app shell above uses it; its Appearance switches the real sidebar.">
      <Example title="User menu" description="Open it; Appearance has the sidebar tone and text size">
        <div className="flex flex-col items-end gap-2">
          <div className="flex w-full items-center justify-end gap-3 rounded-md border border-border bg-background px-3 py-2">
            <span className="mr-auto text-sm text-muted-foreground">Top bar</span>
            <UserMenu name="Grace Wanjiru" email="grace@medora.co.ke" role="Pharmacist" branch="Westlands Main" appearance={a} onAppearance={setA} onProfile={() => toast.add({ title: "Opens your profile" })} onPassword={() => toast.add({ title: "Opens change password or passcode" })} onSignOut={() => toast.add({ title: "Signed out" })} />
          </div>
          <AppearanceSummary appearance={a} />
        </div>
      </Example>
    </Section>
  );
}

/* ------------------------------------ Barcode labels (IN-06) ------------------------------------ */

export function LabelSizesSection() {
  const [sizes, setSizes] = React.useState<LabelSize[]>([
    { id: "a", name: "Shelf roll 38 × 25", width: 38, height: 25, perSheet: 1 },
    { id: "b", name: "Price sticker 70 × 40", width: 70, height: 40, perSheet: 1 },
    { id: "c", name: "A4 sheet, 65 labels", width: 38, height: 21, perSheet: 65 },
  ]);
  return (
    <Section id="label-sizes" title="Saved label sizes and the print plan" description="IN-06: label sizes are saved once and picked by name. The print plan suggests quantities (e.g. what was just received) and says how many labels and sheets that makes.">
      <div className="grid gap-4 xl:grid-cols-2">
        <Example title="Saved label sizes" description="Try a size of 25 × 15 mm">
          <LabelSizes sizes={sizes} onChange={setSizes} />
        </Example>
        <Example title="Print labels" description="From GRN-2026-0318: quantities default to what was received">
          <LabelPrintPlan
            sizes={sizes}
            items={[
              { id: 1, name: "Nivea Soft cream 200 ml", barcode: "4005900036650", suggested: 18, why: "18 received" },
              { id: 2, name: "Calamine lotion 100 ml", barcode: "6161100004401", suggested: 12, why: "12 received" },
              { id: 3, name: "Panadol 500 mg, strip", barcode: "6161100000137", suggested: 0, why: "sold from the box; no label" },
            ]}
            onPrint={(p) => toast.add({ title: `Printing ${p.labels} labels`, description: `${p.size.name}${p.size.perSheet > 1 ? `, ${p.sheets} sheets` : ""}.` })}
          />
        </Example>
      </div>
    </Section>
  );
}

/* ------------------------------------ Held orders (PS-10) ------------------------------------ */

export function HeldOrdersSection() {
  const [held, setHeld] = React.useState<HeldOrder[]>([
    { ref: "HLD-0091", heldAt: "14:22", cashier: "Kevin Mutua", customer: "Mary Wambui", items: 4, total: 2184 },
    { ref: "HLD-0092", heldAt: "14:51", cashier: "Faith Njeri", items: 1, total: 610 },
  ]);
  const [done, setDone] = React.useState<ProcessedHold[]>([
    { ref: "HLD-0089", heldAt: "11:05", cashier: "Kevin Mutua", items: 3, total: 1589.2, outcome: "Sold", by: "Kevin Mutua", at: "11:19", saleRef: "RCP-005214" },
    { ref: "HLD-0087", heldAt: "09:40", cashier: "Faith Njeri", items: 2, total: 845, outcome: "Deleted", by: "Grace Wanjiru", at: "10:02", reason: "Customer left" },
  ]);
  const [canDelete, setCanDelete] = React.useState(true);
  return (
    <Section id="held-orders" title="Held orders and what became of them" description="PS-10: baskets parked at the till can be recalled by anyone. Deleting one needs the Delete permission on POS and a reason, and is logged; processed holds stay listed, so no basket disappears without a trace.">
      <Example title="Held orders, Westlands Main, today" description="Switch the permission off to see Delete disabled">
        <div className="mb-3 flex gap-2">
          <Button size="sm" variant={canDelete ? "secondary" : "ghost"} onClick={() => setCanDelete(true)}>
            As a manager
          </Button>
          <Button size="sm" variant={!canDelete ? "secondary" : "ghost"} onClick={() => setCanDelete(false)}>
            As a cashier
          </Button>
        </div>
        <HeldOrdersLog
          held={held}
          processed={done}
          canDelete={canDelete}
          onRecall={(ref) => toast.add({ title: `${ref} recalled to the till` })}
          onDelete={(ref, reason) => {
            const h = held.find((x) => x.ref === ref);
            if (!h) return;
            setHeld(held.filter((x) => x.ref !== ref));
            setDone([{ ...h, outcome: "Deleted", by: "Grace Wanjiru", at: "15:04", reason }, ...done]);
            toast.add({ title: `${ref} deleted`, description: `Reason: ${reason}. Logged.` });
          }}
        />
      </Example>
    </Section>
  );
}

/* ------------------------------------ Customer reports (RP-09) ------------------------------------ */

export function CustomerReportsSection() {
  return (
    <Section id="customer-reports" title="Customer reports" description="RP-09: top customers by spend, visits or what they owe; each opens to recent purchases and links to the statement. Walk-in sales are one line, so the total matches sales.">
      <Example title="Top customers" description="1–20 Oct 2026, all branches">
        <TopCustomers
          period="1–20 Oct 2026"
          walkIn={{ spend: 1139900, visits: 3280 }}
          onStatement={(id) => toast.add({ title: "Opens the statement in Accounts", description: `Customer ${id}` })}
          customers={[
            { id: 7, name: "Aga Khan Hospital", group: "Corporate", spend: 96420, visits: 6, balance: 3297.2, lastVisit: "19 Oct", purchases: [{ ref: "INV-2026-00783", date: "1 Oct", items: 14, total: 5297.2 }, { ref: "INV-2026-00790", date: "12 Oct", items: 22, total: 31480 }] },
            { id: 2, name: "Mary Wambui", group: "Loyalty", spend: 18640, visits: 14, balance: 0, lastVisit: "20 Oct", purchases: [{ ref: "RCP-005214", date: "20 Oct", items: 3, total: 1589.2 }, { ref: "RCP-005102", date: "16 Oct", items: 2, total: 960 }] },
            { id: 5, name: "John Otieno", spend: 12310, visits: 9, balance: 1500, lastVisit: "18 Oct", purchases: [{ ref: "RCP-005066", date: "18 Oct", items: 1, total: 1260 }] },
            { id: 9, name: "Ali Hassan", group: "Senior", spend: 9880, visits: 7, balance: 0, lastVisit: "17 Oct", purchases: [{ ref: "RCP-004990", date: "17 Oct", items: 4, total: 2120 }] },
            { id: 11, name: "Faith Kamau", spend: 7450, visits: 5, balance: 0, lastVisit: "15 Oct", purchases: [{ ref: "RCP-004871", date: "15 Oct", items: 2, total: 1340 }] },
          ]}
        />
      </Example>
    </Section>
  );
}
