"use client";

import * as React from "react";

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import {
  BarcodeLabel,
  DispensingLabel,
  DocumentSheet,
  Ean13,
  LabelRoll,
  LabelSheet,
  labelSheetCount,
  PrintButton,
  ShelfLabel,
  type DocLine,
  type DocumentKind,
  type Etims,
  type Issuer,
  type LabelProduct,
} from "@/components/medora/print";
import { Receipt, type CartItem } from "@/components/medora/sale";
import { Field, FieldLabel } from "@/components/ui/field";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { Switch } from "@/components/ui/switch";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { addDays, products, TODAY } from "@/lib/mock-data";

const ISSUER: Issuer = {
  name: "Medora Pharmacy Ltd",
  branch: "Westlands Main",
  address: ["Sarit Centre, Ground Floor", "PO Box 473-00100, Nairobi"],
  kraPin: "P051924221B",
  phone: "+254 712 345 678",
  email: "westlands@medora.co.ke",
};

const PRINTED_AT = `${TODAY}T14:05:00`;
const PRINTED_BY = "Grace Wanjiru";

const SIGNED: Etims = {
  state: "signed",
  scuId: "KRACU0300001234",
  cuInvoiceNo: "0300001234/00783",
  internalData: "4F2K-77QH-ZP3M-9X1D",
  signature: "B7CD-0E3A-91F2-55AC",
  signedAt: `${TODAY}T14:04:52`,
  qrUrl: "https://etims.kra.go.ke/common/link/etims/receipt/indexEtimsReceiptData?Data=P051924221B00300001234",
};

const LINES: DocLine[] = [
  { code: "2130", name: "Evit 400 IU capsules, 30s", qty: 2, unit: "pk", price: 450, vat: "A" },
  { code: "6161", name: "Panadol 500 mg tablets, 100s", qty: 3, unit: "pk", price: 520, discount: 20, vat: "A" },
  { code: "4402", name: "Amoxil 500 mg capsules, 21s", qty: 1, unit: "pk", price: 380, vat: "A" },
  { code: "8810", name: "Nivea Soft cream 200 ml", qty: 2, unit: "pc", price: 610, vat: "B" },
  { code: "9021", name: "Surgical gloves, medium, box of 100", qty: 1, unit: "box", price: 950, vat: "B" },
];

const LONG_LINES: DocLine[] = Array.from({ length: 42 }, (_, i) => {
  const p = products[i % products.length];
  return { code: String(1000 + i * 7), name: `${p.name} ${p.strength} ${p.form.toLowerCase()}s`, qty: 1 + (i % 4), unit: "pk", price: p.price * 20, vat: p.category === "Consumables" ? "B" : "A" };
});

const DELIVERY: DocLine[] = [
  { code: "2130", name: "Evit 400 IU capsules, 30s", qty: 2, ordered: 2, batch: "EV24117", expiry: "2027-08-31" },
  { code: "6161", name: "Panadol 500 mg tablets, 100s", qty: 3, ordered: 4, batch: "PN30981", expiry: "2028-01-31" },
  { code: "4402", name: "Amoxil 500 mg capsules, 21s", qty: 1, ordered: 1, batch: "AX55102", expiry: "2027-03-31" },
];

function DocumentsDemo() {
  const [kind, setKind] = React.useState<DocumentKind>("invoice");
  const [signed, setSigned] = React.useState(true);
  const [reprint, setReprint] = React.useState(false);
  const [long, setLong] = React.useState(false);
  const ref = React.useRef<HTMLDivElement>(null);
  const reference = kind === "invoice" ? "INV-2026-00783" : kind === "quotation" ? "QUO-2026-00112" : "DN-2026-00451";

  return (
    <Example
      title="A4 document"
      description="Same template for the three documents. Print opens the browser dialog with only the document on A4; long documents repeat the table header with the reference on every page"
      bare
    >
      <div className="flex flex-wrap items-center gap-x-5 gap-y-3 border-b border-border px-4 py-3">
        <ToggleGroup variant="outline" size="sm" spacing={0} aria-label="Document" value={[kind]} onValueChange={(v: string[]) => v[0] && setKind(v[0] as DocumentKind)}>
          <ToggleGroupItem value="invoice">Tax invoice</ToggleGroupItem>
          <ToggleGroupItem value="quotation">Quotation</ToggleGroupItem>
          <ToggleGroupItem value="delivery-note">Delivery note</ToggleGroupItem>
        </ToggleGroup>
        {kind === "invoice" ? (
          <label className="flex items-center gap-2 text-sm">
            <Switch checked={signed} onCheckedChange={setSigned} /> Signed by KRA
          </label>
        ) : null}
        <label className="flex items-center gap-2 text-sm">
          <Switch checked={reprint} onCheckedChange={setReprint} /> Reprint
        </label>
        {kind !== "delivery-note" ? (
          <label className="flex items-center gap-2 text-sm">
            <Switch checked={long} onCheckedChange={setLong} /> 42 lines
          </label>
        ) : null}
        <div className="ml-auto">
          <PrintButton target={ref} paper="a4" label={`Print ${kind === "delivery-note" ? "delivery note" : kind === "invoice" ? "invoice" : "quotation"}`} />
        </div>
      </div>
      <div className="overflow-x-auto bg-muted/50 p-6">
        <DocumentSheet
          ref={ref}
          kind={kind}
          issuer={ISSUER}
          party={
            kind === "delivery-note"
              ? { name: "Aga Khan Hospital, Main Store", address: ["3rd Parklands Avenue, Nairobi"], phone: "+254 20 366 2000" }
              : { name: "Alfred Kirimi", kraPin: "A012345678Z", phone: "+254 722 111 222", address: ["Riverside Drive, Nairobi"] }
          }
          reference={reference}
          date={TODAY}
          lines={kind === "delivery-note" ? DELIVERY : long ? LONG_LINES : LINES}
          printedBy={PRINTED_BY}
          printedAt={PRINTED_AT}
          status={kind === "invoice" ? "Part paid" : undefined}
          paid={kind === "invoice" ? 2000 : undefined}
          dueDate={kind === "invoice" ? addDays(TODAY, 30) : undefined}
          validUntil={kind === "quotation" ? addDays(TODAY, 14) : undefined}
          related={kind === "invoice" ? [{ label: "Sale", value: "SALE-005200" }] : kind === "delivery-note" ? [{ label: "Invoice", value: "INV-2026-00783" }] : []}
          etims={kind === "invoice" ? (signed ? SIGNED : { state: "queued" }) : undefined}
          reprint={reprint}
          paymentDetails={kind === "delivery-note" ? [] : ["M-Pesa Paybill 247247, account INV-2026-00783", "Equity Bank, Westlands, a/c 0170 2900 1234 56", "Cheques payable to Medora Pharmacy Ltd"]}
          notes={kind === "quotation" ? ["Prescription-only items are supplied against a valid prescription.", "Prices include delivery within Nairobi."] : kind === "invoice" ? ["Goods once sold are not returnable without this invoice."] : []}
        />
      </div>
    </Example>
  );
}

const cart: CartItem[] = [
  { id: 1, name: "Panadol 500 mg", unitPrice: 5, qty: 20, taxCode: "A" },
  { id: 2, name: "Amoxil 500 mg", unitPrice: 15, qty: 21, taxCode: "A" },
  { id: 3, name: "Nivea Soft cream 200 ml", unitPrice: 610, qty: 1, taxCode: "B" },
];

function ReceiptsDemo() {
  const r80 = React.useRef<HTMLDivElement>(null);
  const r58 = React.useRef<HTMLDivElement>(null);
  const base = { receiptNo: "RCP-005200", date: TODAY, time: "14:32", cashier: "Kevin Mutua", branch: "Westlands Main", items: cart, method: "Cash" as const, tendered: 1000 };
  return (
    <Example title="Thermal receipts" description="80 mm signed by KRA, with VAT worked out per tax code (medicines exempt, the cream at 16%); 58 mm reprint while the sale is still queued for eTIMS, on the old flat 16%" className="flex flex-wrap items-start justify-center gap-8 bg-muted/40">
      <div className="space-y-3">
        <Receipt ref={r80} data={{ ...base, etims: SIGNED, tendered: 2000, taxCodes: [{ code: "A", name: "Exempt", rate: 0 }, { code: "B", name: "VAT", rate: 16 }] }} paper="80mm" />
        <div className="flex justify-center">
          <PrintButton target={r80} paper="receipt-80" label="Print 80 mm" />
        </div>
      </div>
      <div className="space-y-3">
        <Receipt ref={r58} data={{ ...base, method: "M-Pesa", mpesaRef: "SJK4L8P2QX", tendered: undefined, reprint: { at: PRINTED_AT, by: "Kevin Mutua" } }} paper="58mm" />
        <div className="flex justify-center">
          <PrintButton target={r58} paper="receipt-58" label="Print 58 mm" />
        </div>
      </div>
    </Example>
  );
}

const labelProducts: LabelProduct[] = products
  .filter((p) => p.type === "Product")
  .slice(0, 9)
  .map((p, i) => ({
    name: p.name,
    strength: p.strength,
    pack: `${p.form}, strip of 10`,
    price: p.price * 10,
    unitPrice: { amount: p.price, unit: p.form.toLowerCase() },
    // Mock barcodes don't carry valid check digits; the first 12 digits get one added.
    barcode: i === 8 ? "2130" : p.barcode.slice(0, 12),
    shelf: p.shelf,
    rx: p.requiresRx,
  }));

function LabelsDemo() {
  const [startAt, setStartAt] = React.useState(1);
  const sheetCount = labelSheetCount(labelProducts.length, startAt);
  const sheet = React.useRef<HTMLDivElement>(null);
  const roll = React.useRef<HTMLDivElement>(null);
  const disp = React.useRef<HTMLDivElement>(null);
  return (
    <>
      <Example title="Shelf labels, A4 sheet of 21" description="70 × 42.3 mm, no sheet margins. Start at skips labels already used on a part-used sheet. The last label has an internal code, so it prints the code instead of an unscannable barcode" bare>
        <div className="flex flex-wrap items-end gap-4 border-b border-border px-4 py-3">
          <Field className="w-40">
            <FieldLabel htmlFor="start-at">Start at label</FieldLabel>
            <NativeSelect id="start-at" value={String(startAt)} onChange={(e) => setStartAt(Number(e.target.value))}>
              {Array.from({ length: 21 }, (_, i) => (
                <NativeSelectOption key={i} value={String(i + 1)}>
                  {i + 1}
                  {i === 0 ? " (new sheet)" : ""}
                </NativeSelectOption>
              ))}
            </NativeSelect>
          </Field>
          <p className="pb-2 text-sm text-muted-foreground">
            {labelProducts.length} labels{startAt > 1 ? `, starting at label ${startAt}` : ""}
            {sheetCount > 1 ? `; ${startAt - 1 + labelProducts.length - 21} continue on a second sheet` : ""}
          </p>
          <div className="ml-auto">
            <PrintButton target={sheet} paper="sheet-21" label={sheetCount > 1 ? `Print ${sheetCount} sheets` : "Print sheet"} />
          </div>
        </div>
        <div className="overflow-x-auto bg-muted/50 p-6">
          <LabelSheet ref={sheet} startAt={startAt}>
            {labelProducts.map((p) => (
              <ShelfLabel key={p.name} product={p} printedOn={TODAY} />
            ))}
          </LabelSheet>
        </div>
      </Example>
      <div className="grid gap-4 lg:grid-cols-2">
        <Example title="Barcode labels, 38 × 25 mm roll" description="For stock that arrives without a barcode; one label per printed page">
          <div className="space-y-3">
            <LabelRoll ref={roll}>
              {labelProducts.slice(0, 3).map((p) => (
                <BarcodeLabel key={p.name} product={p} />
              ))}
            </LabelRoll>
            <PrintButton target={roll} paper="label-38x25" label="Print 3 labels" />
          </div>
        </Example>
        <Example title="Dispensing label, 70 × 40 mm" description="Patient, medicine, quantity, directions (largest), warnings, pharmacy and Rx number">
          <div className="space-y-3">
            <LabelRoll ref={disp}>
              {[
                <DispensingLabel
                  key="d"
                  issuer={ISSUER}
                  label={{
                    patient: "Mary Wambui",
                    medicine: "Amoxicillin 500 mg capsules",
                    quantity: "21",
                    directions: "Take ONE capsule THREE times a day for 7 days.",
                    warnings: ["Finish the course, even if you feel better.", "Keep out of reach of children."],
                    rxNo: "RX-2026-0912",
                    date: TODAY,
                    pharmacist: "GW",
                  }}
                />,
              ]}
            </LabelRoll>
            <PrintButton target={disp} paper="label-70x40" label="Print label" />
          </div>
        </Example>
      </div>
      <Example title="EAN-13" description="Valid code with check digit; 12 digits get the check digit added; a wrong check digit or internal code prints as text">
        <div className="flex flex-wrap items-end gap-8 bg-white p-2">
          <Ean13 value="4006381333931" width={37.3} />
          <Ean13 value="616110000013" width={30} />
          <Ean13 value="4006381333932" />
          <Ean13 value="2130" />
        </div>
      </Example>
    </>
  );
}

export function PrintDocumentsSection() {
  return (
    <Section
      id="documents"
      title="Documents"
      description="A4 tax invoice, quotation and delivery note on one template: one-colour logo, branch details and KRA PIN from Settings, references, the other party, lines, totals by VAT class (eTIMS types A to E), and the KRA block. Status is a word, never a colour, so it survives a monochrome printer. A reprint says Copy on every page."
    >
      <DocumentsDemo />
    </Section>
  );
}

export function PrintReceiptsSection() {
  return (
    <Section id="receipts" title="Receipts" description="Thermal receipt at 80 mm and 58 mm. With KRA details once signed; while the sale is queued for eTIMS, it says they will follow.">
      <ReceiptsDemo />
    </Section>
  );
}

export function PrintLabelsSection() {
  return (
    <Section id="labels" title="Labels" description="Shelf-edge labels on an A4 sheet, barcode labels and dispensing labels on rolls. Price is the largest text on a shelf label; directions are the largest on a dispensing label.">
      <LabelsDemo />
    </Section>
  );
}
