"use client";

import * as React from "react";
import { PackagePlusIcon, SendIcon } from "lucide-react";

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import { ApprovalRecord } from "@/components/medora/approval";
import { ConfirmDialog } from "@/components/medora/confirm-dialog";
import { DescriptionList } from "@/components/medora/description-list";
import { ConversionPreview, ReorderPicker, suggestQty, TransferBadge, TransferReceive, TransferSendLines, WasteLines, type ReorderRow, type TransferLine, type TransferStage, type TransferStockOption, type WasteLine } from "@/components/medora/stock-ops";
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { toast } from "@/components/ui/toast";

const kes = (n: number) => `KES ${n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;

function ConversionDemo() {
  const [qty, setQty] = React.useState(2);
  const [done, setDone] = React.useState(false);
  const link = { parent: { name: "Panadol 500 mg, box of 100", unit: "boxes", stock: done ? 10 : 12, unitCost: 300 }, child: { name: "Panadol 500 mg, strip of 10", unit: "strips", stock: done ? 23 : 3 }, perParent: 10 };
  return (
    <Example title="Stock conversion" description="Break a box into strips at a fixed rate; value moves from one product to the other unchanged">
      <div className="space-y-3">
        <ConversionPreview link={link} qty={qty} onQty={setQty} />
        <div className="flex flex-wrap items-end justify-end gap-3">
          <Field className="w-48">
            <FieldLabel htmlFor="cnv-loc">At</FieldLabel>
            <NativeSelect id="cnv-loc">
              <NativeSelectOption>Westlands, Store room</NativeSelectOption>
              <NativeSelectOption>Westlands, Dispensary</NativeSelectOption>
            </NativeSelect>
          </Field>
          <Button
            disabled={qty === 0 || done}
            onClick={() => {
              setDone(true);
              toast.add({ title: "Conversion CNV-2026-0004 recorded", description: `${qty} boxes into ${qty * 10} strips.` });
            }}
          >
            Convert {qty} {qty === 1 ? "box" : "boxes"}
          </Button>
        </div>
      </div>
    </Example>
  );
}

const SEND_OPTIONS: TransferStockOption[] = [
  { id: "o1", name: "Panadol 500 mg, strip of 10", batch: "PN31544", expiry: "2028-04-30", available: 220 },
  { id: "o2", name: "Panadol 500 mg, strip of 10", batch: "PN30981", expiry: "2027-11-30", available: 140 },
  { id: "o3", name: "Amoxil 500 mg capsules, 21s", batch: "AX55102", expiry: "2027-03-31", available: 30 },
  { id: "o4", name: "ORS sachets", batch: "OR11920", expiry: "2027-06-30", available: 400 },
];

function TransferDemo() {
  const [stage, setStage] = React.useState<TransferStage>("draft");
  const [to, setTo] = React.useState("Kilimani");
  const [sendQty, setSendQty] = React.useState<Record<string, number>>({ o2: 100, o3: 24, o4: 50 });
  const [sendTried, setSendTried] = React.useState(false);
  const [counts, setCounts] = React.useState<Record<string, number>>({});
  const [notes, setNotes] = React.useState<Record<string, string>>({});
  const [tried, setTried] = React.useState(false);
  const lines: TransferLine[] = SEND_OPTIONS.filter((o) => (sendQty[o.id] ?? 0) > 0).map((o) => ({ id: o.id, name: o.name, batch: o.batch, sent: sendQty[o.id] }));
  const short = lines.filter((l) => (counts[l.id] ?? l.sent) < l.sent);
  const missingNote = short.some((l) => !notes[l.id]?.trim());
  const sendErr = to === "Westlands Main" ? "A transfer has to go to a different branch." : !lines.length ? "Add at least one line to send." : undefined;
  return (
    <Example title="Branch transfer: send, then receive" description="Lines are batches, earliest expiry first, and can't exceed what Westlands holds. Once sent, it's in transit; the receiving branch counts what arrived, and a shortfall needs a note" bare>
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3">
        <div className="flex flex-wrap items-center gap-2">
          <span className="font-mono font-semibold">TRF-2026-0043</span> <TransferBadge stage={stage} />
        </div>
        <span className="text-sm text-muted-foreground">{stage === "draft" ? "From Westlands Main" : `Sent 20 Oct 2026, 09:40 by Peter Kamau to ${to}`}</span>
      </div>
      <div className="space-y-3 p-4">
        {stage === "draft" ? (
          <>
            <div className="flex flex-wrap items-end gap-3">
              <Field className="w-56">
                <FieldLabel htmlFor="trf-to">Send to</FieldLabel>
                <NativeSelect id="trf-to" value={to} onChange={(e) => setTo(e.target.value)}>
                  {["Kilimani", "Nyali", "Milimani", "Westlands Main"].map((b) => (
                    <NativeSelectOption key={b}>{b}</NativeSelectOption>
                  ))}
                </NativeSelect>
              </Field>
              <Field className="min-w-56 flex-1">
                <FieldLabel htmlFor="trf-note">Note (optional)</FieldLabel>
                <Input id="trf-note" placeholder="e.g. Cover for the weekend rush" />
              </Field>
            </div>
            <TransferSendLines options={SEND_OPTIONS} qty={sendQty} onQty={(id, n) => setSendQty((q) => ({ ...q, [id]: n }))} />
            {sendTried && sendErr ? <p className="text-sm text-status-error-text">{sendErr}</p> : null}
            <div className="flex justify-end">
              <Button
                onClick={() => {
                  setSendTried(true);
                  if (sendErr) return;
                  setStage("in-transit");
                  toast.add({ title: "Transfer dispatched", description: `${lines.reduce((s, l) => s + l.sent, 0)} units left Westlands; in transit to ${to}.` });
                }}
              >
                <SendIcon data-icon="inline-start" />
                Dispatch to {to}
              </Button>
            </div>
          </>
        ) : stage === "in-transit" ? (
          <>
            <TransferReceive lines={lines} counts={counts} notes={notes} onCount={(id, n) => setCounts((c) => ({ ...c, [id]: n }))} onNote={(id, s) => setNotes((x) => ({ ...x, [id]: s }))} />
            {tried && missingNote ? <p className="text-sm text-status-error-text">Say what happened to each missing item.</p> : null}
            <div className="flex justify-end">
              <Button
                onClick={() => {
                  setTried(true);
                  if (missingNote) return;
                  setStage(short.length ? "received-short" : "received");
                  toast.add({ title: short.length ? "Received short" : "Transfer received", description: `Stock added to ${to}, Store room.` });
                }}
              >
                Accept {lines.reduce((s, l) => s + (counts[l.id] ?? l.sent), 0)} units into {to}
              </Button>
            </div>
          </>
        ) : (
          <DescriptionList
            variant="inline"
            density="compact"
            items={lines.map((l) => ({ label: l.name, value: `${counts[l.id] ?? l.sent} of ${l.sent}${(counts[l.id] ?? l.sent) < l.sent ? ` · ${notes[l.id]}` : ""}` }))}
          />
        )}
      </div>
    </Example>
  );
}

function IssueDemo() {
  return (
    <Example title="Issue stock" description="Stock used inside the pharmacy (the clinic room, the staff first-aid box) leaves stock without a sale">
      <div className="grid gap-3 sm:grid-cols-2">
        <Field>
          <FieldLabel htmlFor="iss-from">From</FieldLabel>
          <NativeSelect id="iss-from">
            <NativeSelectOption>Westlands, Store room</NativeSelectOption>
          </NativeSelect>
        </Field>
        <Field>
          <FieldLabel htmlFor="iss-to">To</FieldLabel>
          <NativeSelect id="iss-to">
            <NativeSelectOption>Clinic room</NativeSelectOption>
            <NativeSelectOption>First-aid box</NativeSelectOption>
          </NativeSelect>
        </Field>
        <Field>
          <FieldLabel htmlFor="iss-ref">Internal reference</FieldLabel>
          <Input id="iss-ref" placeholder="e.g. Clinic request 14" />
        </Field>
        <Field>
          <FieldLabel htmlFor="iss-item">Item and quantity</FieldLabel>
          <Input id="iss-item" defaultValue="Surgical gloves, box of 100 × 2" />
        </Field>
      </div>
      <div className="mt-3 flex justify-end">
        <Button variant="outline" onClick={() => toast.add({ title: "Issue ISS-2026-0012 recorded", description: "Not a sale: no revenue, cost goes to Clinic supplies." })}>
          <SendIcon data-icon="inline-start" />
          Issue stock
        </Button>
      </div>
    </Example>
  );
}

const WASTE_REASONS = ["Expired", "Damaged", "Broken seal", "Recalled by supplier", "Cold chain failure"];
const WASTE: WasteLine[] = [
  { id: "w1", name: "Augmentin 625 mg, 14s", batch: "AG77310", expiry: "30 Sep 2026", qty: 12, available: 12, unitCost: 850, reason: "Expired" },
  { id: "w2", name: "Insulin glargine pen", batch: "IG20915", expiry: "31 Mar 2027", qty: 2, available: 9, unitCost: 1450, reason: "Cold chain failure" },
];

function WasteDemo() {
  const [lines, setLines] = React.useState(WASTE);
  const [stage, setStage] = React.useState<"draft" | "pending">("draft");
  const [confirming, setConfirming] = React.useState(false);
  const total = lines.reduce((s, l) => s + l.qty * l.unitCost, 0);
  return (
    <Example title="Waste write-off" description="Per batch, no more than the batch holds, with a managed reason; valued at cost and sent for approval">
      <div className="space-y-3">
        {stage === "draft" ? (
          <>
            <WasteLines lines={lines} reasons={WASTE_REASONS} onChange={(id, patch) => setLines((xs) => xs.map((x) => (x.id === id ? { ...x, ...patch } : x)))} />
            <div className="flex justify-end">
              <Button disabled={total === 0} onClick={() => setConfirming(true)}>
                Submit {kes(total)} for approval
              </Button>
            </div>
          </>
        ) : (
          <ApprovalRecord
            request={{
              id: "WST-2026-0008",
              action: "waste",
              title: `Write off ${lines.reduce((s, l) => s + l.qty, 0)} units (${kes(total)} at cost)`,
              why: lines.map((l) => `${l.qty} × ${l.name}: ${l.reason}`).join("; "),
              amount: total,
              requestedBy: "Peter Kamau (Branch admin)",
              requestedAt: new Date("2026-10-20T14:01:00"),
            }}
          />
        )}
      </div>
      <ConfirmDialog
        open={confirming}
        onOpenChange={setConfirming}
        level="A"
        title={`Submit ${kes(total)} of waste for approval?`}
        consequences={["Nothing leaves stock until it's approved.", "Once approved it posts to Stock write-offs (5100) and appears on the waste report."]}
        actionLabel="Submit for approval"
        onConfirm={() => setStage("pending")}
      />
    </Example>
  );
}

const REORDER: ReorderRow[] = [
  { id: 1, name: "Panadol 500 mg, strip of 10", stock: 3, reorderLevel: 40, avgDaily: 6, leadDays: 3, packSize: 10, supplier: "Dawa Distributors", lastCost: 30 },
  { id: 2, name: "Amoxil 500 mg capsules, 21s", stock: 0, reorderLevel: 10, avgDaily: 1.5, leadDays: 5, packSize: 6, supplier: "Harleys Ltd", lastCost: 290 },
  { id: 3, name: "Metformin 500 mg, 100s", stock: 4, reorderLevel: 8, avgDaily: 0.8, leadDays: 5, packSize: 1, supplier: "Harleys Ltd", lastCost: 410 },
  { id: 4, name: "ORS sachets", stock: 12, reorderLevel: 30, avgDaily: 2, leadDays: 2, packSize: 50, supplier: "Dawa Distributors", lastCost: 18 },
];

function ReorderDemo() {
  const [picked, setPicked] = React.useState<Set<number>>(new Set([1, 2, 3]));
  const [qty, setQty] = React.useState<Record<number, number>>({});
  const bySupplier = [...new Set(REORDER.filter((r) => picked.has(r.id)).map((r) => r.supplier))];
  const total = REORDER.filter((r) => picked.has(r.id)).reduce((s, r) => s + (qty[r.id] ?? suggestQty(r)) * r.lastCost, 0);
  return (
    <Example title="Low stock → purchase order" description="Suggested quantity covers lead time plus 30 days of sales, in whole packs. One draft PO per supplier" bare>
      <div className="space-y-3 p-4">
        <ReorderPicker
          rows={REORDER}
          picked={picked}
          qty={qty}
          onPick={(id, on) =>
            setPicked((s) => {
              const n = new Set(s);
              if (on) n.add(id);
              else n.delete(id);
              return n;
            })
          }
          onQty={(id, n) => setQty((q) => ({ ...q, [id]: n }))}
        />
        <div className="flex flex-wrap items-center justify-end gap-3">
          <span className="text-sm text-muted-foreground tabular-nums">
            {picked.size} items, {kes(total)} at last cost
          </span>
          <Button disabled={!picked.size} onClick={() => toast.add({ title: `${bySupplier.length} draft ${bySupplier.length === 1 ? "PO" : "POs"} created`, description: bySupplier.join(", ") })}>
            <PackagePlusIcon data-icon="inline-start" />
            Create {bySupplier.length || ""} draft {bySupplier.length === 1 ? "PO" : "POs"}
          </Button>
        </div>
      </div>
    </Example>
  );
}

export function StockOpsSection() {
  return (
    <Section
      id="stock-ops"
      title="Conversion, transfers, waste and reordering"
      description="Stock movements other than sales and receiving. Each checks quantities against what's really there (a box can't be converted twice, a transfer can't arrive with more than was sent, a batch can't lose more than it holds) and writes to the inventory log with its document number."
    >
      <div className="grid gap-4 lg:grid-cols-2">
        <ConversionDemo />
        <IssueDemo />
      </div>
      <TransferDemo />
      <WasteDemo />
      <ReorderDemo />
    </Section>
  );
}
