"use client";

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

import { Example } from "@/components/design-system/example";
import { Section } from "@/components/design-system/section";
import { AsyncBadge } from "@/components/medora/async-status";
import { ConfirmDialog } from "@/components/medora/confirm-dialog";
import { FileUpload } from "@/components/medora/file-upload";
import { SecretInput } from "@/components/medora/secret-input";
import {
  AlertRules,
  etimsMissing,
  IntegrationHeader,
  IntegrationLog,
  promoDiscount,
  PromoBadge,
  promoProblems,
  promoStatus,
  ProviderChecks,
  SendLog,
  TemplateEditor,
  type IntegrationEvent,
  type ProviderCheck,
  type SentMessage,
  type AlertRule,
  type EtimsItem,
  type Promo,
} from "@/components/medora/settings-ops";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { Spinner } from "@/components/ui/spinner";
import { toast } from "@/components/ui/toast";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { TODAY } from "@/lib/mock-data";

const n2 = (n: number) => n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const BRANCHES = ["Westlands Main", "Kilimani", "Nyali", "Milimani"];

/* ------------------------------------ Promotions ------------------------------------ */

function PromoDemo() {
  const [p, setP] = React.useState<Promo>({ name: "Vitamins week", kind: "Percent", value: 10, scope: "Category", target: "Vitamins", minBasket: 1000, start: "2026-10-20", end: "2026-10-26", branches: ["Westlands Main", "Kilimani"], active: true });
  const [tried, setTried] = React.useState(false);
  const problems = promoProblems(p);
  const status = promoStatus(p, TODAY);
  const set = (patch: Partial<Promo>) => setP((x) => ({ ...x, ...patch }));
  const off = promoDiscount(p, 1500, 900);
  return (
    <Example title="Promotion" description="Dates, branches and scope; the preview shows the effect in shillings. Try a fixed KES 1,500 off with a KES 1,000 minimum">
      <div className="space-y-4">
        <div className="flex flex-wrap items-center gap-2">
          <PromoBadge status={status} />
          <span className="text-xs text-muted-foreground">Only the best promotion applies to each line; promotions don&apos;t stack.</span>
        </div>
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          <Field>
            <FieldLabel htmlFor="pr-name">Name</FieldLabel>
            <Input id="pr-name" value={p.name} onChange={(e) => set({ name: e.target.value })} />
          </Field>
          <Field>
            <FieldLabel htmlFor="pr-kind">Discount</FieldLabel>
            <div className="flex gap-2">
              <NativeSelect id="pr-kind" value={p.kind} onChange={(e) => set({ kind: e.target.value as Promo["kind"] })}>
                <NativeSelectOption value="Percent">%</NativeSelectOption>
                <NativeSelectOption value="Fixed">KES</NativeSelectOption>
              </NativeSelect>
              <Input aria-label="Discount amount" inputMode="decimal" className="tabular-nums" value={String(p.value)} onChange={(e) => set({ value: Number(e.target.value) || 0 })} />
            </div>
          </Field>
          <Field>
            <FieldLabel htmlFor="pr-scope">Applies to</FieldLabel>
            <div className="flex gap-2">
              <NativeSelect id="pr-scope" value={p.scope} onChange={(e) => set({ scope: e.target.value as Promo["scope"], target: e.target.value === "Basket" ? undefined : p.target })}>
                <NativeSelectOption>Basket</NativeSelectOption>
                <NativeSelectOption>Category</NativeSelectOption>
                <NativeSelectOption>Product</NativeSelectOption>
              </NativeSelect>
              {p.scope !== "Basket" ? (
                <NativeSelect aria-label={p.scope} value={p.target ?? ""} onChange={(e) => set({ target: e.target.value || undefined })}>
                  <NativeSelectOption value="">Choose…</NativeSelectOption>
                  {(p.scope === "Category" ? ["Vitamins", "Dermatology", "Consumables"] : ["Vitamin C 500 mg", "Nivea Soft cream 200 ml"]).map((x) => (
                    <NativeSelectOption key={x}>{x}</NativeSelectOption>
                  ))}
                </NativeSelect>
              ) : null}
            </div>
          </Field>
          <Field>
            <FieldLabel htmlFor="pr-min">Minimum basket (KES)</FieldLabel>
            <Input id="pr-min" inputMode="numeric" className="tabular-nums" value={String(p.minBasket)} onChange={(e) => set({ minBasket: Number(e.target.value.replace(/\D/g, "")) || 0 })} />
          </Field>
          <Field>
            <FieldLabel htmlFor="pr-start">From</FieldLabel>
            <Input id="pr-start" type="date" value={p.start} onChange={(e) => set({ start: e.target.value })} />
          </Field>
          <Field>
            <FieldLabel htmlFor="pr-end">Until</FieldLabel>
            <Input id="pr-end" type="date" value={p.end} onChange={(e) => set({ end: e.target.value })} />
          </Field>
        </div>
        <fieldset className="flex flex-wrap gap-x-4 gap-y-1 text-sm">
          <legend className="mb-1 text-sm font-medium">Branches</legend>
          {BRANCHES.map((b) => (
            <label key={b} className="inline-flex items-center gap-1.5">
              <Checkbox checked={p.branches.includes(b)} onCheckedChange={(v) => set({ branches: v ? [...p.branches, b] : p.branches.filter((x) => x !== b) })} />
              {b}
            </label>
          ))}
        </fieldset>
        <p className="rounded-md border border-[var(--color-border-panel)] px-3 py-2 text-sm">
          On a KES 1,500.00 basket with KES 900.00 of {p.scope === "Basket" ? "items" : (p.target ?? p.scope.toLowerCase())}:{" "}
          <span className="font-semibold">{off ? `KES ${n2(off)} off` : "no discount"}</span>
          {p.minBasket > 1500 ? ` (minimum basket is KES ${n2(p.minBasket)})` : ""}.
        </p>
        {tried && problems.length ? (
          <ul role="alert" className="list-disc rounded-md border border-status-error-border bg-status-error-bg py-2 pr-3 pl-8 text-sm text-status-error-text">
            {problems.map((x) => (
              <li key={x}>{x}</li>
            ))}
          </ul>
        ) : null}
        <div className="flex justify-end">
          <Button
            onClick={() => {
              setTried(true);
              if (!promoProblems(p).length) toast.add({ title: `${p.name} saved`, description: `${promoStatus(p, TODAY)}: ${p.branches.join(", ")}.` });
            }}
          >
            Save promotion
          </Button>
        </div>
      </div>
    </Example>
  );
}

/* ------------------------------------- Alerts ------------------------------------- */

const RULES: AlertRule[] = [
  { id: "a1", name: "Low stock", when: "When a product falls to its reorder level", threshold: 0, unit: "units above reorder level", roles: ["Pharmacist", "Inventory Manager"], channels: { app: true, sms: false, email: true }, on: true },
  { id: "a2", name: "Expiring stock", when: "Batches expiring within", threshold: 60, unit: "days", roles: ["Pharmacist", "Inventory Manager"], channels: { app: true, sms: false, email: true }, on: true },
  { id: "a3", name: "Overdue balance", when: "Customer balance overdue by more than", threshold: 30, unit: "days", roles: ["Admin"], channels: { app: true, sms: false, email: true }, on: true },
  { id: "a4", name: "Cash variance at shift close", when: "Counted cash differs by more than", threshold: 500, unit: "KES", roles: ["Admin"], channels: { app: true, sms: true, email: false }, on: true },
  { id: "a5", name: "eTIMS rejection", when: "KRA rejects a sale or credit note", threshold: 1, unit: "rejection", roles: [], channels: { app: true, sms: false, email: false }, on: true },
];

function AlertsDemo() {
  const [rules, setRules] = React.useState(RULES);
  const [smsOn, setSmsOn] = React.useState(false);
  return (
    <Example title="Alert rules" description="Thresholds, who gets each alert and how. SMS is offered once an SMS provider is connected. The eTIMS rule reaches nobody: it says so" bare>
      <div className="flex items-center gap-2 border-b border-border px-4 py-3 text-sm">
        <Checkbox checked={smsOn} onCheckedChange={(v) => setSmsOn(!!v)} id="sms-connected" />
        <label htmlFor="sms-connected">Demo: SMS provider connected</label>
      </div>
      <div className="p-4">
        <AlertRules rules={rules} roles={["Admin", "Pharmacist", "Inventory Manager"]} connected={{ sms: smsOn, email: true }} onChange={(id, patch) => setRules((xs) => xs.map((x) => (x.id === id ? { ...x, ...patch } : x)))} />
      </div>
    </Example>
  );
}

/* ---------------------------------- Integration page ---------------------------------- */

function IntegrationDemo() {
  const [env, setEnv] = React.useState<"Sandbox" | "Live">("Sandbox");
  const [goingLive, setGoingLive] = React.useState(false);
  const [test, setTest] = React.useState<"idle" | "testing" | "ok" | "failed">("idle");
  return (
    <Example title="Integration page: M-Pesa (Daraja)" description="Status, environment, test connection and the event log in one place. Switching to Live confirms first; credentials are never shown" bare>
      <div className="space-y-4 p-4">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <IntegrationHeader name="M-Pesa (Daraja)" status={test === "failed" ? "Failing" : "Connected"} environment={env} lastOk="14:20 today" />
          <div className="flex flex-wrap items-center gap-2">
            <ToggleGroup variant="outline" size="sm" spacing={0} aria-label="Environment" value={[env]} onValueChange={(v: string[]) => v[0] && (v[0] === "Live" ? setGoingLive(true) : setEnv("Sandbox"))}>
              <ToggleGroupItem value="Sandbox">Sandbox</ToggleGroupItem>
              <ToggleGroupItem value="Live">Live</ToggleGroupItem>
            </ToggleGroup>
            <Button
              size="sm"
              variant="outline"
              disabled={test === "testing"}
              onClick={() => {
                setTest("testing");
                setTimeout(() => setTest(env === "Live" ? "failed" : "ok"), 1000);
              }}
            >
              {test === "testing" ? <Spinner /> : null}
              {test === "testing" ? "Testing…" : "Test connection"}
            </Button>
          </div>
        </div>
        {test === "ok" ? <AsyncBadge state="done" label="Test passed: token received, shortcode 247247 found" /> : null}
        {test === "failed" ? <AsyncBadge state="failed" label="Test failed: Live credentials not accepted. Replace the consumer key and secret" /> : null}
        <div className="grid gap-4 lg:grid-cols-2">
          <div className="space-y-3">
            <h4 className="text-sm font-semibold">Credentials</h4>
            <SecretInput fields={[{ name: "ck", label: "Consumer key" }, { name: "cs", label: "Consumer secret" }]} status={{ set: true, lastChanged: { at: "12 Sep 2026", by: "Grace Wanjiru" } }} onReplace={() => {}} />
            <SecretInput fields={[{ name: "pk", label: "Passkey" }]} status={{ set: true, lastChanged: { at: "12 Sep 2026", by: "Grace Wanjiru" } }} onReplace={() => {}} />
          </div>
          <div className="space-y-2">
            <h4 className="text-sm font-semibold">Recent events</h4>
            <IntegrationLog
              events={[
                { id: "e1", at: "14:20", event: "STK push confirmed", ref: "QJK7XYZ12", ok: true },
                { id: "e2", at: "14:02", event: "STK push", ref: "ws_CO_2010…", ok: false, detail: "Customer cancelled on the phone" },
                { id: "e3", at: "13:41", event: "C2B payment, paybill", ref: "QJK6ABC90", ok: true, detail: "Matched to INV-2026-00783" },
                { id: "e4", at: "11:15", event: "C2B payment, till", ref: "QJK5QWE33", ok: false, detail: "No sale or account matched: listed under unmatched payments" },
                { id: "e5", at: "10:52", event: "Callback ignored", ref: "ws_CO_1910…", ok: false, ignored: true, detail: "Amount 1,000.00 didn't match the request for 1,189.00; logged, sale not marked paid" },
                { id: "e6", at: "10:48", event: "Duplicate callback ignored", ref: "QJK4MNB71", ok: false, ignored: true, detail: "Same receipt already applied to SALE-005188" },
              ]}
            />
          </div>
        </div>
      </div>
      <ConfirmDialog
        open={goingLive}
        onOpenChange={setGoingLive}
        level="B"
        title="Switch M-Pesa to Live?"
        consequences={["Customers will be charged real money from the next payment.", "Test the connection straight after switching."]}
        reasons={["Going live after testing", "Switching back after a sandbox test", "Other"]}
        actionLabel="Switch to Live"
        onConfirm={() => {
          setEnv("Live");
          setTest("idle");
        }}
      />
    </Example>
  );
}

/* --------------------------------- eTIMS items --------------------------------- */

const ITEMS: EtimsItem[] = [
  { id: 1, name: "Panadol 500 mg, strip of 10", itemClass: "5112150300", itemType: "Finished product", origin: "KE", packaging: "Box", quantityUnit: "Strip", taxCode: "A", status: "Registered", code: "KE2NTBX0000001" },
  { id: 2, name: "Amoxil 500 mg capsules, 21s", itemClass: "5110150000", itemType: "Finished product", origin: "IN", packaging: "Box", quantityUnit: "Pack", taxCode: "A", status: "Not registered" },
  { id: 3, name: "Nivea Soft cream 200 ml", itemClass: "", itemType: "Finished product", origin: "DE", packaging: "Tube", quantityUnit: "", taxCode: "B", status: "Not registered" },
  { id: 4, name: "Pharmacist consultation", itemClass: "8510160000", itemType: "Service", origin: "KE", packaging: "None", quantityUnit: "Visit", taxCode: "A", status: "Rejected", reason: "Item class 8510160000 doesn't allow tax code A: use B." },
];

function EtimsDemo() {
  const [items, setItems] = React.useState(ITEMS);
  const [busy, setBusy] = React.useState(false);
  const ready = items.filter((i) => i.status !== "Registered" && !etimsMissing(i).length);
  return (
    <Example title="KRA eTIMS item registration" description="Every product is registered with KRA before it can be sold on eTIMS. Missing details are listed; KRA's rejection reason is shown in words" bare>
      <div className="space-y-3 p-4">
        <div className="overflow-x-auto rounded-lg border border-[var(--color-border-panel)]">
          <table className="w-full border-collapse text-sm">
            <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
              <tr>
                {["Product", "Item class", "Type · origin · units", "Tax", "Status"].map((h) => (
                  <th key={h} scope="col" className="px-3 py-2 font-medium">
                    {h}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody className="divide-y divide-[var(--color-border-subtle)]">
              {items.map((i) => {
                const missing = etimsMissing(i);
                return (
                  <tr key={i.id}>
                    <th scope="row" className="px-3 py-2 text-left font-medium">
                      {i.name}
                      {i.code ? <span className="block font-mono text-xs font-normal text-muted-foreground">{i.code}</span> : null}
                    </th>
                    <td className="px-3 py-2 font-mono text-xs">{i.itemClass || <span className="font-sans text-status-warning-text">Missing</span>}</td>
                    <td className="px-3 py-2 text-xs">
                      {i.itemType} · {i.origin} · {i.packaging}/{i.quantityUnit || "?"}
                    </td>
                    <td className="px-3 py-2 font-mono text-xs">{i.taxCode}</td>
                    <td className="px-3 py-2">
                      <AsyncBadge state={i.status === "Registered" ? "done" : i.status === "Rejected" ? "attention" : "queued"} severe={i.status === "Rejected"} label={i.status} />
                      {i.reason ? <span className="mt-0.5 block text-xs text-muted-foreground">{i.reason}</span> : null}
                      {missing.length && i.status !== "Registered" ? <span className="mt-0.5 block text-xs text-status-warning-text">Needs {missing.join(", ")}</span> : null}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
        <div className="flex items-center justify-end gap-3">
          <span className="text-sm text-muted-foreground">{ready.length} ready to send</span>
          <Button
            disabled={!ready.length || busy}
            onClick={() => {
              setBusy(true);
              setTimeout(() => {
                setBusy(false);
                setItems((xs) => xs.map((x) => (ready.some((r) => r.id === x.id) ? (x.id === 4 ? x : { ...x, status: "Registered", code: `KE2NTBX00000${x.id}`, reason: undefined }) : x)));
                toast.add({ title: "Sent to KRA", description: "1 registered; 1 still rejected: fix its tax code." });
              }, 1000);
            }}
          >
            {busy ? <Spinner /> : <SendIcon data-icon="inline-start" />}
            {busy ? "Sending…" : "Register with KRA"}
          </Button>
        </div>
      </div>
    </Example>
  );
}

/* ---------------------------------- Templates ---------------------------------- */

const PLACEHOLDERS = [
  { key: "customer_name", label: "Customer's first name" },
  { key: "amount", label: "Amount, e.g. KES 1,250.00" },
  { key: "balance", label: "Balance after" },
  { key: "pharmacy", label: "Branch name" },
  { key: "phone", label: "Branch phone" },
  { key: "due_date", label: "Due date" },
];
const SAMPLE = { customer_name: "Mary", amount: "KES 2,000.00", balance: "KES 3,297.20", pharmacy: "Medora Westlands", phone: "0712 345 678", due_date: "19 Nov" };

function TemplatesDemo() {
  const [channel, setChannel] = React.useState<"SMS" | "Email">("SMS");
  const [sms, setSms] = React.useState("Hi {customer_name}, we received {amount}. Your balance is {balance}, due {due_date}. {pharmacy}, {phone}");
  const [log, setLog] = React.useState(SENT);
  const [email, setEmail] = React.useState("Dear {customer_name},\n\nThank you for your payment of {amount}. Your balance is now {balance}.\n\nKind regards,\n{pharmacy}");
  return (
    <Example title="Message templates: payment received" description="Placeholders come from the list. Type a curly apostrophe (’) in the SMS to see it switch to Unicode and the parts jump" bare>
      <div className="space-y-3 p-4">
        <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>
        {channel === "SMS" ? <TemplateEditor channel="SMS" value={sms} onChange={setSms} placeholders={PLACEHOLDERS} sample={SAMPLE} costPerPart={0.8} /> : <TemplateEditor channel="Email" value={email} onChange={setEmail} placeholders={PLACEHOLDERS} sample={SAMPLE} />}
        <h4 className="pt-2 text-sm font-semibold">Sent today</h4>
        <SendLog
          messages={log}
          onResend={(id) => {
            setLog((xs) => xs.map((m) => (m.id === id ? { ...m, status: "Sent", reason: undefined, at: "14:35" } : m)));
            toast.add({ title: "Sent again" });
          }}
        />
      </div>
    </Example>
  );
}

const SENT: SentMessage[] = [
  { id: "s1", at: "14:02", channel: "SMS", to: "07•• ••• 678", template: "Payment received", status: "Delivered", parts: 1, cost: 0.8 },
  { id: "s2", at: "13:40", channel: "SMS", to: "07•• ••• 214", template: "Refill reminder", status: "Failed", parts: 1, cost: 0, reason: "Number unreachable for 24 hours" },
  { id: "s3", at: "12:15", channel: "Email", to: "acc•••@agakhan.org", template: "Statement, October", status: "Bounced", reason: "Mailbox full" },
  { id: "s4", at: "11:58", channel: "SMS", to: "07•• ••• 333", template: "Preorder arrived", status: "Sent", parts: 2, cost: 1.6 },
  { id: "s5", at: "09:30", channel: "Email", to: "mar•••@example.com", template: "Receipt RCP-005188", status: "Delivered" },
];

type Provider = "eTIMS" | "SMS" | "Email" | "Banks";

function OtherIntegrationsDemo() {
  const [p, setP] = React.useState<Provider>("eTIMS");
  const views: Record<Provider, { name: string; status: "Connected" | "Not connected" | "Failing"; env: "Sandbox" | "Live"; last?: string; checks: ProviderCheck[]; events: IntegrationEvent[] }> = {
    eTIMS: {
      name: "KRA eTIMS (OSCU), Westlands Main",
      status: "Connected",
      env: "Live",
      last: "14:04",
      checks: [
        { label: "Device initialised", ok: true, detail: "SCU KRACU0300001234, branch 00, initialised 1 Sep 2026" },
        { label: "Items registered", ok: false, detail: "2 products not registered: they're queued, not sent, until they are. See eTIMS items" },
        { label: "Queue", ok: true, detail: "Nothing waiting to send" },
      ],
      events: [
        { id: "k1", at: "14:04", event: "Sale signed", ref: "SALE-005200", ok: true },
        { id: "k2", at: "11:48", event: "Sale rejected", ref: "SALE-005188", ok: false, detail: "Buyer PIN not valid" },
      ],
    },
    SMS: {
      name: "SMS, Africa's Talking",
      status: "Connected",
      env: "Live",
      last: "14:02",
      checks: [
        { label: "Sender ID MEDORA approved", ok: true, detail: "Approved by Safaricom and Airtel on 2 Oct 2026" },
        { label: "Balance", ok: false, detail: "KES 182.40 left, about 228 messages. Top up before reminders go out tomorrow" },
      ],
      events: [
        { id: "m1", at: "14:02", event: "SMS delivered", ref: "ATXid_8812", ok: true },
        { id: "m2", at: "13:40", event: "SMS failed", ref: "ATXid_8807", ok: false, detail: "Number unreachable" },
      ],
    },
    Email: {
      name: "Email, medora.co.ke",
      status: "Failing",
      env: "Live",
      checks: [
        { label: "SPF record", ok: true, detail: "Found and includes the mail provider" },
        { label: "DKIM signature", ok: false, detail: "Not found. Add the TXT record mail._domainkey to medora.co.ke, or emails may land in spam" },
        { label: "From address", ok: true, detail: "westlands@medora.co.ke verified" },
      ],
      events: [{ id: "e1", at: "12:15", event: "Email bounced", ref: "msg-44a1", ok: false, detail: "Mailbox full" }],
    },
    Banks: {
      name: "Banks: Equity 1040, KCB 1041",
      status: "Connected",
      env: "Live",
      last: "yesterday",
      checks: [
        { label: "Equity Bank statement", ok: true, detail: "Imported to 19 Oct 2026; 6 lines, 5 matched" },
        { label: "KCB payroll account", ok: false, detail: "No statement since 30 Sep. Import October's CSV" },
        { label: "Card terminal settlements", ok: true, detail: "Settlement report to 19 Oct imported" },
      ],
      events: [{ id: "b1", at: "19 Oct", event: "Statement imported", ref: "equity-oct.csv", ok: true, detail: "6 lines" }],
    },
  };
  const v = views[p];
  return (
    <Example title="Other integrations" description="The same page shape for every provider: status and environment, the checks that decide whether it works (each says what to do when it fails), and the event log" bare>
      <div className="border-b border-border px-4 py-3">
        <ToggleGroup variant="outline" size="sm" spacing={0} aria-label="Integration" value={[p]} onValueChange={(x: string[]) => x[0] && setP(x[0] as Provider)}>
          {(["eTIMS", "SMS", "Email", "Banks"] as const).map((x) => (
            <ToggleGroupItem key={x} value={x}>
              {x}
            </ToggleGroupItem>
          ))}
        </ToggleGroup>
      </div>
      <div className="space-y-4 p-4">
        <IntegrationHeader name={v.name} status={v.status} environment={v.env} lastOk={v.last} />
        <div className="grid gap-4 lg:grid-cols-2">
          <div className="space-y-3">
            <h4 className="text-sm font-semibold">Checks</h4>
            <ProviderChecks checks={v.checks} />
            {p === "Banks" ? (
              <FileUpload label="Import a statement (CSV)" hint="CSV from your bank's online banking, up to 2 MB" kind="csv" accept={[".csv"]} maxBytes={2 * 1024 * 1024} upload={async (_f, prog) => { for (const x of [30, 70, 100]) { await new Promise((r) => setTimeout(r, 200)); prog(x); } return "12 lines found"; }} />
            ) : null}
          </div>
          <div className="space-y-3">
            <h4 className="text-sm font-semibold">Recent events</h4>
            <IntegrationLog events={v.events} />
          </div>
        </div>
      </div>
    </Example>
  );
}

export function SettingsOpsSection() {
  return (
    <Section
      id="settings-ops"
      title="Promotions, alerts, integrations and templates"
      description="Settings that change what Medora does on its own. Each shows its effect before saving: the shillings a promotion takes off, who an alert reaches, whether an integration's test passes, what KRA still needs for an item, and how long an SMS will be."
    >
      <PromoDemo />
      <AlertsDemo />
      <IntegrationDemo />
      <OtherIntegrationsDemo />
      <EtimsDemo />
      <TemplatesDemo />
    </Section>
  );
}
