"use client";

import * as React from "react";
import { ArrowRightIcon, DownloadIcon } from "lucide-react";

import { MedoraPageHeader } from "@/components/medora/page-header";
import { SettingsLayout, type SettingsSection } from "@/components/medora/settings-layout";
import { Button } from "@/components/ui/button";
import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import { toast } from "@/components/ui/toast";
import { Frame } from "./frame";

/*
 * General Settings (ST-16): store info, regional formats, receipts, tax, delivery, security, data and
 * backup, and the hardware guide. M-Pesa keys are not here any more (ST-18): they live with the other
 * credentials under Integrations, and this page points there.
 */

type Values = {
  storeName: string;
  phone: string;
  kraPin: string;
  timezone: string;
  dateFormat: "d MMM yyyy" | "dd/MM/yyyy" | "yyyy-MM-dd";
  receiptFooter: string;
  printLogo: boolean;
  etims: boolean;
  delivery: boolean;
  freeAbove: string;
  timeout: string;
  lock: boolean;
  minPassword: string;
  needNumber: boolean;
  failedLimit: string;
  autoBackup: boolean;
  backupAt: string;
};

const SAVED: Values = {
  storeName: "Medora Pharmacy Westlands",
  phone: "0712 345 678",
  kraPin: "P051924221B",
  timezone: "Africa/Nairobi",
  dateFormat: "d MMM yyyy",
  receiptFooter: "Goods once sold are not returnable without this receipt.",
  printLogo: true,
  etims: true,
  delivery: true,
  freeAbove: "3000",
  timeout: "15",
  lock: true,
  minPassword: "8",
  needNumber: true,
  failedLimit: "5",
  autoBackup: true,
  backupAt: "23:30",
};

/** Which section each setting belongs to, so the save bar can name the changed sections. */
const OWNER: Record<keyof Values, string> = {
  storeName: "Store info",
  phone: "Store info",
  kraPin: "Store info",
  timezone: "Regional",
  dateFormat: "Regional",
  receiptFooter: "Receipts",
  printLogo: "Receipts",
  etims: "Tax and eTIMS",
  delivery: "Delivery",
  freeAbove: "Delivery",
  timeout: "Security",
  lock: "Security",
  minPassword: "Security",
  needNumber: "Security",
  failedLimit: "Security",
  autoBackup: "Data and backup",
  backupAt: "Data and backup",
};

const SAMPLE = { d: 20, m: 10, y: 2026 };
const MON = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const p2 = (n: number) => String(n).padStart(2, "0");
const sampleDate = (f: Values["dateFormat"]) => (f === "d MMM yyyy" ? `${SAMPLE.d} ${MON[SAMPLE.m - 1]} ${SAMPLE.y}` : f === "dd/MM/yyyy" ? `${p2(SAMPLE.d)}/${p2(SAMPLE.m)}/${SAMPLE.y}` : `${SAMPLE.y}-${p2(SAMPLE.m)}-${p2(SAMPLE.d)}`);

const HARDWARE: { device: string; works: string; setup: string }[] = [
  { device: "Receipt printer, 80 mm or 58 mm thermal", works: "Any ESC/POS printer (Epson TM-T20, Xprinter XP-80)", setup: "Install the maker's driver, set it as the default printer, print a test receipt from Receipts." },
  { device: "Barcode scanner", works: "USB or Bluetooth scanners that type like a keyboard (HID)", setup: "Plug in; nothing to install. Scan into the till's search box to test. Set the scanner to add Enter after each code." },
  { device: "Cash drawer", works: "Drawers with an RJ11 cable to the receipt printer", setup: "Connect the drawer to the printer's DK port; it opens when a cash sale completes." },
  { device: "Label printer", works: "Zebra, Brother or TSC label printers, 38 × 25 mm and up", setup: "Install the driver, then save the label size under Documents and print." },
  { device: "Card terminal", works: "Bank-supplied terminals (standalone)", setup: "No connection to Medora: enter the approval code at the till, and the batch total when closing the shift." },
];

function Toggle({ id, label, hint, checked, onChange }: { id: string; label: string; hint: string; checked: boolean; onChange: (v: boolean) => void }) {
  return (
    <Field orientation="horizontal" className="items-start justify-between">
      <div className="space-y-0.5">
        <FieldLabel htmlFor={id}>{label}</FieldLabel>
        <FieldDescription>{hint}</FieldDescription>
      </div>
      <Switch id={id} checked={checked} onCheckedChange={onChange} />
    </Field>
  );
}

export function SettingsFormPattern() {
  const [saved, setSaved] = React.useState(SAVED);
  const [v, setV] = React.useState(SAVED);
  const [saving, setSaving] = React.useState(false);
  const scrollRef = React.useRef<HTMLDivElement>(null);
  const set = <K extends keyof Values>(k: K) => (value: Values[K]) => setV((x) => ({ ...x, [k]: value }));
  const changed = [...new Set((Object.keys(v) as (keyof Values)[]).filter((k) => v[k] !== saved[k]).map((k) => OWNER[k]))];
  const digits = (k: keyof Values) => (e: React.ChangeEvent<HTMLInputElement>) => set(k)(e.target.value.replace(/\D/g, "") as never);

  const sections: SettingsSection[] = [
    {
      id: "store",
      title: "Store info",
      description: "Printed on receipts, invoices and statements.",
      keywords: ["name", "phone", "KRA PIN", "address"],
      content: (
        <FieldGroup className="gap-4">
          <Field>
            <FieldLabel htmlFor="st-name">Store name</FieldLabel>
            <Input id="st-name" value={v.storeName} onChange={(e) => set("storeName")(e.target.value)} />
          </Field>
          <div className="grid gap-4 sm:grid-cols-2">
            <Field>
              <FieldLabel htmlFor="st-phone">Phone</FieldLabel>
              <Input id="st-phone" value={v.phone} onChange={(e) => set("phone")(e.target.value)} />
            </Field>
            <Field>
              <FieldLabel htmlFor="st-pin">KRA PIN</FieldLabel>
              <Input id="st-pin" value={v.kraPin} onChange={(e) => set("kraPin")(e.target.value.toUpperCase())} />
            </Field>
          </div>
        </FieldGroup>
      ),
    },
    {
      id: "regional",
      title: "Regional",
      description: "How money, dates and times are shown everywhere, including printouts.",
      keywords: ["currency", "timezone", "date format", "KES"],
      content: (
        <FieldGroup className="gap-4">
          <div className="grid gap-4 sm:grid-cols-3">
            <Field>
              <FieldLabel htmlFor="st-cur">Currency</FieldLabel>
              <Input id="st-cur" value="KES, Kenya shilling" disabled />
              <FieldDescription>Fixed: M-Pesa, eTIMS and the ledger are in shillings.</FieldDescription>
            </Field>
            <Field>
              <FieldLabel htmlFor="st-tz">Timezone</FieldLabel>
              <NativeSelect id="st-tz" value={v.timezone} onChange={(e) => set("timezone")(e.target.value)}>
                <NativeSelectOption value="Africa/Nairobi">East Africa (Nairobi), UTC+3</NativeSelectOption>
                <NativeSelectOption value="Africa/Kampala">East Africa (Kampala), UTC+3</NativeSelectOption>
                <NativeSelectOption value="Africa/Dar_es_Salaam">East Africa (Dar es Salaam), UTC+3</NativeSelectOption>
              </NativeSelect>
              <FieldDescription>Sales by day and hour are grouped in this time.</FieldDescription>
            </Field>
            <Field>
              <FieldLabel htmlFor="st-df">Date format</FieldLabel>
              <NativeSelect id="st-df" value={v.dateFormat} onChange={(e) => set("dateFormat")(e.target.value as Values["dateFormat"])}>
                <NativeSelectOption value="d MMM yyyy">20 Oct 2026</NativeSelectOption>
                <NativeSelectOption value="dd/MM/yyyy">20/10/2026</NativeSelectOption>
                <NativeSelectOption value="yyyy-MM-dd">2026-10-20</NativeSelectOption>
              </NativeSelect>
              <FieldDescription>Shows as {sampleDate(v.dateFormat)}. Exports always use 2026-10-20.</FieldDescription>
            </Field>
          </div>
        </FieldGroup>
      ),
    },
    {
      id: "receipts",
      title: "Receipts",
      keywords: ["footer", "logo", "print", "thermal"],
      content: (
        <FieldGroup className="gap-4">
          <Field>
            <FieldLabel htmlFor="st-footer">Receipt footer</FieldLabel>
            <Textarea id="st-footer" value={v.receiptFooter} onChange={(e) => set("receiptFooter")(e.target.value)} rows={2} />
            <FieldDescription>One or two short lines, printed under the totals.</FieldDescription>
          </Field>
          <Toggle id="st-logo" label="Print the logo" hint="Black only; thermal printers can't print colour." checked={v.printLogo} onChange={set("printLogo")} />
        </FieldGroup>
      ),
    },
    {
      id: "tax",
      title: "Tax and eTIMS",
      keywords: ["VAT", "KRA", "eTIMS", "invoice", "M-Pesa", "paybill", "keys"],
      content: (
        <FieldGroup className="gap-4">
          <Toggle id="st-etims" label="Send sales to KRA eTIMS" hint="Sales are signed by KRA after they complete; the till never waits." checked={v.etims} onChange={set("etims")} />
          <p className="rounded-md border border-[var(--color-border-panel)] bg-muted/40 px-3 py-2 text-sm">
            eTIMS device setup, and the M-Pesa, SMS, email and bank connections, are under <span className="font-medium">Integrations</span>, where their keys are stored encrypted.{" "}
            <button type="button" className="inline-flex cursor-pointer items-center gap-1 font-medium text-primary underline-offset-4 hover:underline" onClick={() => toast.add({ title: "Opens Integrations → M-Pesa" })}>
              Go to Integrations <ArrowRightIcon className="size-3.5" aria-hidden />
            </button>
          </p>
        </FieldGroup>
      ),
    },
    {
      id: "delivery",
      title: "Delivery",
      keywords: ["zones", "rider", "free delivery", "fee"],
      content: (
        <FieldGroup className="gap-4">
          <Toggle id="st-del" label="Offer delivery" hint="Adds a delivery panel to the payment screen." checked={v.delivery} onChange={set("delivery")} />
          <Field>
            <FieldLabel htmlFor="st-free">Free delivery above (KES)</FieldLabel>
            <Input id="st-free" className="w-40 tabular-nums" inputMode="numeric" value={v.freeAbove} onChange={digits("freeAbove")} disabled={!v.delivery} />
            <FieldDescription>Beats any zone fee. Leave empty for no free delivery.</FieldDescription>
          </Field>
        </FieldGroup>
      ),
    },
    {
      id: "security",
      title: "Security",
      keywords: ["session", "timeout", "lock", "password", "sign out", "failed login", "lockout"],
      content: (
        <FieldGroup className="gap-4">
          <Toggle id="st-lock" label="Sign out after inactivity" hint="Protects the till when it's left unattended." checked={v.lock} onChange={set("lock")} />
          <div className="grid gap-4 sm:grid-cols-3">
            <Field>
              <FieldLabel htmlFor="st-timeout">Sign out after (minutes)</FieldLabel>
              <Input id="st-timeout" className="w-32 tabular-nums" inputMode="numeric" value={v.timeout} onChange={digits("timeout")} disabled={!v.lock} />
            </Field>
            <Field>
              <FieldLabel htmlFor="st-minpw">Shortest password</FieldLabel>
              <Input id="st-minpw" className="w-32 tabular-nums" inputMode="numeric" value={v.minPassword} onChange={digits("minPassword")} />
              <FieldDescription>Characters. 8 or more is recommended.</FieldDescription>
            </Field>
            <Field>
              <FieldLabel htmlFor="st-fail">Lock after failed sign-ins</FieldLabel>
              <Input id="st-fail" className="w-32 tabular-nums" inputMode="numeric" value={v.failedLimit} onChange={digits("failedLimit")} />
              <FieldDescription>An Admin unlocks the account.</FieldDescription>
            </Field>
          </div>
          <Toggle id="st-num" label="Passwords need a number" hint="Passcodes for till staff are set per user and aren't affected." checked={v.needNumber} onChange={set("needNumber")} />
        </FieldGroup>
      ),
    },
    {
      id: "backup",
      title: "Data and backup",
      description: "Backups are kept on the server for 30 days. Restoring one is done by Medora support, never from this page.",
      keywords: ["backup", "export", "data", "restore"],
      content: (
        <FieldGroup className="gap-4">
          <Toggle id="st-bk" label="Back up every night" hint="Everything: sales, stock, accounts and settings." checked={v.autoBackup} onChange={set("autoBackup")} />
          <Field>
            <FieldLabel htmlFor="st-bkat">Back up at</FieldLabel>
            <Input id="st-bkat" type="time" className="w-32 tabular-nums" value={v.backupAt} onChange={(e) => set("backupAt")(e.target.value)} disabled={!v.autoBackup} />
            <FieldDescription>Pick a time after closing. Last backup: 19 Oct 2026, 23:30, completed (412 MB).</FieldDescription>
          </Field>
          <div className="flex flex-wrap items-center gap-2">
            <Button variant="outline" size="sm" onClick={() => toast.add({ title: "Preparing your data export", description: "You'll get an email with a download link when it's ready." })}>
              <DownloadIcon data-icon="inline-start" />
              Export all data
            </Button>
            <span className="text-xs text-muted-foreground">CSV files in a zip, for your own records or moving to another system.</span>
          </div>
        </FieldGroup>
      ),
    },
    {
      id: "hardware",
      title: "Hardware guide",
      description: "Devices that work with Medora and how to set each one up. Nothing to change here.",
      keywords: ["printer", "scanner", "cash drawer", "label", "card terminal"],
      content: (
        <ul className="divide-y divide-[var(--color-border-subtle)] rounded-md border border-[var(--color-border-panel)]">
          {HARDWARE.map((h) => (
            <li key={h.device} className="px-3 py-2 text-sm">
              <p className="font-medium">{h.device}</p>
              <p className="text-xs text-muted-foreground">Works with: {h.works}</p>
              <p className="mt-0.5 text-xs">{h.setup}</p>
            </li>
          ))}
        </ul>
      ),
    },
  ];

  return (
    <Frame>
      <div ref={scrollRef} className="h-full overflow-y-auto px-6 pt-6">
        <MedoraPageHeader title="General settings" description="How this pharmacy's receipts, formats, tax, delivery, security and backups work." className="mb-6" />
        <SettingsLayout
          sections={sections}
          scrollRoot={scrollRef}
          changedSections={changed}
          saving={saving}
          onDiscard={() => setV(saved)}
          onSave={() => {
            setSaving(true);
            setTimeout(() => {
              setSaving(false);
              setSaved(v);
              toast.add({ title: "Settings saved", description: changed.join(", ") });
            }, 900);
          }}
        />
        <div className="h-6" />
      </div>
    </Frame>
  );
}
