"use client";

import * as React from "react";
import { PlusIcon } from "lucide-react";

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import {
  B2BChain,
  branchProblems,
  C2BRow,
  ConsentList,
  EtimsQueue,
  LocationsEditor,
  MoneyLinks,
  moneyLinkProblems,
  OnlineProducts,
  ShelvesList,
  zoneProblems,
  type B2BDoc,
  type BranchDraft,
  type C2BPayment,
  type EtimsQueueItem,
  type MoneyLink,
  type OnlineProduct,
  type PlaceLocation,
  type Zone,
} from "@/components/medora/admin-more";
import { FileUpload } from "@/components/medora/file-upload";
import { Button } from "@/components/ui/button";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { toast } from "@/components/ui/toast";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";

/* ------------------------------------- Branch ------------------------------------- */

function BranchDemo() {
  const [d, setD] = React.useState<BranchDraft>({ name: "Karen", address: "The Hub, Dagoretti Road", postal: "PO Box 1220-00502", town: "Nairobi", kraPin: "P05192422", phone: "0712 345 680", email: "karen@medora.co.ke", till: "880211" });
  const [links, setLinks] = React.useState<MoneyLink[]>([
    { role: "Cash drawer", account: "" },
    { role: "M-Pesa till", account: "1021 M-Pesa till 512330" },
    { role: "Bank", account: "1040 Equity Bank" },
  ]);
  const [tried, setTried] = React.useState(false);
  const p = branchProblems(d, ["Westlands Main", "Kilimani", "Nyali", "Milimani"]);
  const lp = moneyLinkProblems(links, { "1021 M-Pesa till 512330": "Kilimani" });
  const f = (k: keyof BranchDraft, label: string, extra?: React.ComponentProps<typeof Input>) => (
    <Field data-invalid={tried && !!p[k]}>
      <FieldLabel htmlFor={`br-${k}`}>{label}</FieldLabel>
      <Input id={`br-${k}`} value={d[k]} onChange={(e) => setD({ ...d, [k]: e.target.value })} aria-invalid={tried && !!p[k]} {...extra} />
      {tried && p[k] ? <FieldError>{p[k]}</FieldError> : null}
    </Field>
  );
  return (
    <Example title="Branch and its money accounts" description="Details printed on receipts, and which ledger accounts are this branch's drawer, till, terminals and bank. Save as it is: the PIN is short, there's no cash drawer, and the till account belongs to Kilimani">
      <div className="grid gap-6 lg:grid-cols-2">
        <div className="grid gap-3 sm:grid-cols-2">
          {f("name", "Branch name")}
          {f("town", "Town")}
          {f("address", "Physical address")}
          {f("postal", "Postal address")}
          {f("kraPin", "KRA PIN", { className: "font-mono uppercase" })}
          {f("phone", "Phone", { inputMode: "tel" })}
          {f("email", "Email", { type: "email" })}
          {f("till", "M-Pesa till number", { inputMode: "numeric" })}
          <div className="sm:col-span-2">
            <FileUpload label="Logo for receipts" hint="PNG or SVG, under 500 KB; printed in black" kind="image" accept={[".png", ".svg"]} maxBytes={500 * 1024} compact upload={async (_f, prog) => prog(100)} />
          </div>
        </div>
        <div className="space-y-3">
          <h4 className="text-sm font-semibold">Money accounts</h4>
          <MoneyLinks links={links} onChange={setLinks} accounts={[{ code: "1012", name: "Cash drawer, Karen" }, { code: "1021", name: "M-Pesa till 512330" }, { code: "1022", name: "M-Pesa till 880211" }, { code: "1031", name: "Card terminal, Karen" }, { code: "1040", name: "Equity Bank" }]} />
          {tried && lp.length ? (
            <ul className="list-disc pl-5 text-sm text-status-error-text">
              {lp.map((x) => (
                <li key={x}>{x}</li>
              ))}
            </ul>
          ) : null}
        </div>
      </div>
      <div className="mt-4 flex justify-end">
        <Button
          onClick={() => {
            setTried(true);
            if (!Object.keys(p).length && !lp.length) toast.add({ title: `${d.name} saved` });
          }}
        >
          Save branch
        </Button>
      </div>
    </Example>
  );
}

/* ------------------------------ Locations, shelves, zones ------------------------------ */

function PlacesDemo() {
  const [locs, setLocs] = React.useState<PlaceLocation[]>([
    { id: "l1", name: "Dispensary", kind: "Physical", inPos: true, units: 9210 },
    { id: "l2", name: "Store room", kind: "Physical", inPos: false, units: 7340, details: "Back of the shop; key with the branch admin" },
    { id: "l3", name: "Online orders", kind: "Virtual", inPos: false, units: 0 },
  ]);
  const [zones, setZones] = React.useState<Zone[]>([
    { name: "Westlands", fee: "200" },
    { name: "Kilimani", fee: "300" },
    { name: "Karen", fee: "500" },
  ]);
  const zp = zoneProblems(zones);
  return (
    <div className="grid gap-4 xl:grid-cols-3">
      <Example title="Locations, Westlands Main" description="Physical or virtual; which ones the till sells from. Try hiding Dispensary from the till, or deleting Store room">
        <LocationsEditor locations={locs} onChange={setLocs} onBlocked={(m) => toast.add({ type: "error", title: "Can't do that", description: m })} />
      </Example>
      <Example title="Shelves and racks" description="Search and page through; products are assigned a shelf from this list">
        <ShelvesList shelves={Array.from({ length: 14 }, (_, i) => ({ code: `${String.fromCharCode(65 + Math.floor(i / 3))}${(i % 3) + 1}`, description: ["Analgesics", "Antibiotics", "Diabetes", "Skin care", "Vitamins"][Math.floor(i / 3) % 5], products: 6 + ((i * 7) % 19) }))} />
      </Example>
      <Example title="Delivery zones" description="The zone fills in the fee at the till; the cashier can change it">
        <div className="space-y-2">
          {zones.map((z, i) => (
            <div key={i} className="flex gap-2">
              <Input aria-label={`Zone ${i + 1} name`} value={z.name} onChange={(e) => setZones(zones.map((x, j) => (j === i ? { ...x, name: e.target.value } : x)))} />
              <Input aria-label={`Zone ${i + 1} fee`} className="w-24 tabular-nums" inputMode="decimal" value={z.fee} onChange={(e) => setZones(zones.map((x, j) => (j === i ? { ...x, fee: e.target.value } : x)))} />
            </div>
          ))}
          {zp.length ? <p className="text-xs text-status-error-text">{zp.join(" ")}</p> : null}
          <Button size="sm" variant="outline" onClick={() => setZones([...zones, { name: "", fee: "0" }])}>
            <PlusIcon data-icon="inline-start" />
            Add zone
          </Button>
        </div>
      </Example>
    </div>
  );
}

/* --------------------------------- Integrations --------------------------------- */

const C2B: C2BPayment[] = [
  { code: "QJK7ABC101", at: "13:58", amount: 1189, phone: "07•• ••• 678", payer: "MARY W", account: "", suggestion: { kind: "sale", ref: "SALE-005200", label: "SALE-005200 (KES 1,189.00 at 13:56, waiting for M-Pesa)" } },
  { code: "QJK7ABC144", at: "11:20", amount: 5000, phone: "07•• ••• 200", payer: "AGA KHAN HOSP", account: "INV783", suggestion: { kind: "customer", ref: "INV-2026-00783", label: "a part payment of INV-2026-00783, Aga Khan Hospital" } },
  { code: "QJK7ABC162", at: "09:02", amount: 350, phone: "07•• ••• 913", payer: "JOHN K", account: "medicine" },
];

const QUEUE: EtimsQueueItem[] = [
  { ref: "SALE-005201", kind: "Sale", at: "14:40", amount: 845.2, status: "Queued", attempts: 2, reason: "KRA didn't answer; retrying every 5 minutes" },
  { ref: "SALE-005188", kind: "Sale", at: "11:48", amount: 2450, status: "Rejected", attempts: 1, reason: "Buyer PIN not valid", fix: "Correct the customer's KRA PIN, then resend." },
  { ref: "CN-2026-0091", kind: "Credit note", at: "Yesterday", amount: 707.6, status: "Rejected", attempts: 1, reason: "Item not registered with KRA", fix: "Register Nivea Soft cream under eTIMS items first." },
  { ref: "GRN-2026-0318", kind: "Purchase", at: "18 Oct", amount: 15567.6, status: "Queued", attempts: 1, reason: "Purchases are sent to KRA as their specification requires; waiting for KRA" },
];

function IntegrationsMoreDemo() {
  const [c2b, setC2b] = React.useState(C2B);
  const [queue, setQueue] = React.useState(QUEUE);
  const [online, setOnline] = React.useState<OnlineProduct[]>([
    { id: 1, name: "Panadol 500 mg, strip of 10", online: true, price: 58, available: 180, buffer: 10, lastSync: "14:30" },
    { id: 2, name: "Nivea Soft cream 200 ml", online: true, price: 610, onlinePrice: 595, available: 3, buffer: 5, lastSync: "14:30" },
    { id: 3, name: "Augmentin 625 mg, 14s", online: true, price: 1260, available: 40, buffer: 5, rx: true, error: "Shop rejected the price: below its minimum" },
    { id: 4, name: "Calamine lotion 100 ml", online: false, price: 240, available: 22, buffer: 5 },
  ]);
  const [channel, setChannel] = React.useState<"sms" | "email">("sms");
  return (
    <>
      <div className="grid gap-4 xl:grid-cols-2">
        <Example title="Unmatched M-Pesa payments" description="Payments made straight to the till or paybill that no sale or account claimed. Match each, or mark it not ours to refund" bare>
          <ul className="divide-y divide-[var(--color-border-subtle)]">
            {c2b.map((p) => (
              <C2BRow
                key={p.code}
                p={p}
                onMatch={(ref) => {
                  setC2b((xs) => xs.filter((x) => x.code !== p.code));
                  toast.add({ title: `${p.code} matched to ${ref}` });
                }}
                onSkip={() => {
                  setC2b((xs) => xs.filter((x) => x.code !== p.code));
                  toast.add({ title: `${p.code} marked for refund`, description: "Refund it from the M-Pesa portal; it's kept on the unmatched report." });
                }}
              />
            ))}
            {!c2b.length ? <li className="px-3 py-6 text-center text-sm text-muted-foreground">Every payment is matched.</li> : null}
          </ul>
        </Example>
        <Example title="eTIMS: not yet signed" description="Queued items send themselves when KRA answers; rejected ones say what to fix first">
          <EtimsQueue
            items={queue}
            onResend={(ref) => {
              setQueue((xs) => xs.filter((x) => x.ref !== ref));
              toast.add({ title: `${ref} sent to KRA`, description: "Signed: KRA invoice number added to the sale." });
            }}
          />
        </Example>
      </div>
      <Example title="Online shop products" description="What's listed, at what price, and the stock the shop sees after a safety buffer so the last units aren't sold twice">
        <OnlineProducts rows={online} onChange={(id, patch) => setOnline((xs) => xs.map((x) => (x.id === id ? { ...x, ...patch, lastSync: undefined, error: undefined } : x)))} />
      </Example>
      <div className="grid gap-4 xl:grid-cols-2">
        <Example title="Marketing consent" description="Promotions go only to customers who opted in; every message carries a way to opt out (Reply STOP, or an unsubscribe link)">
          <div className="space-y-3">
            <ToggleGroup variant="outline" size="sm" spacing={0} aria-label="Channel" value={[channel]} onValueChange={(v: string[]) => v[0] && setChannel(v[0] as "sms" | "email")}>
              <ToggleGroupItem value="sms">SMS</ToggleGroupItem>
              <ToggleGroupItem value="email">Email</ToggleGroupItem>
            </ToggleGroup>
            <ConsentList
              channel={channel}
              rows={[
                { customer: "Mary Wambui", sms: true, email: true, source: "at the till", on: "3 Mar 2024" },
                { customer: "John Otieno", sms: true, email: false, source: "online shop", on: "12 Aug 2026" },
                { customer: "Faith Njeri", sms: true, email: false, source: "at the till", on: "1 Feb 2025", optedOut: "18 Oct 2026 (replied STOP)" },
                { customer: "Ali Hassan", sms: false, email: false, source: "", on: "" },
              ]}
            />
          </div>
        </Example>
        <Example title="B2B order to delivery" description="Aga Khan Hospital: an order becomes an invoice, then a delivery note; each links to the next, with what's paid">
          <B2BChain
            docs={
              [
                { kind: "Order", ref: "SO-2026-0041", status: "Confirmed 1 Oct", amount: 5297.2 },
                { kind: "Invoice", ref: "INV-2026-00783", status: "Part paid · due 19 Nov", amount: 5297.2, paid: 2000 },
                { kind: "Delivery note", status: "Next: create from the invoice" },
              ] satisfies B2BDoc[]
            }
          />
        </Example>
      </div>
    </>
  );
}

export function AdminMoreSection() {
  return (
    <Section id="admin-more" title="Branches, places and the remaining integrations" description="Where things are and how money and data flow out: branch details and money accounts, locations, shelves and delivery zones, M-Pesa payments nobody claimed, eTIMS items KRA hasn't signed, the online shop, marketing consent and B2B documents.">
      <BranchDemo />
      <PlacesDemo />
      <IntegrationsMoreDemo />
    </Section>
  );
}
