"use client";

import * as React from "react";
import { FlaskConicalIcon, HeartPulseIcon, NotebookPenIcon, ShieldAlertIcon, StethoscopeIcon } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { cn } from "@/lib/utils";

import { TONE_BOX, TONE_TEXT } from "./tones";

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

/* ------------------------------- 12. Insurance scheme ------------------------------- */

export type SchemeMember = {
  scheme: string;
  memberNo: string;
  relation: "Principal" | "Spouse" | "Child";
  principal?: string;
  /** Annual outpatient pharmacy cover. */
  limit: number;
  used: number;
  /** Customer pays this share of each bill. */
  copayPct: number;
  validUntil: string;
  status: "Active" | "Suspended" | "Expired";
};

/** How a bill splits between the scheme and the customer: co-pay first, then the scheme up to what's left of the cover. */
export function schemeSplit(total: number, m: SchemeMember) {
  if (m.status !== "Active") return { scheme: 0, customer: total, capped: false };
  const remaining = Math.max(0, m.limit - m.used);
  const wanted = Math.round(total * (1 - m.copayPct / 100) * 100) / 100;
  const scheme = Math.min(wanted, remaining);
  return { scheme, customer: Math.round((total - scheme) * 100) / 100, capped: scheme < wanted };
}

/**
 * Scheme membership card (PRD 4.5): scheme, member number, cover used and left, co-pay, validity. The status
 * is a word; a suspended or expired member pays in full. At the till, `bill` shows the split.
 */
export function SchemeCard({ member, bill, formatDate }: { member: SchemeMember; bill?: number; formatDate: (iso: string) => string }) {
  const remaining = Math.max(0, member.limit - member.used);
  const pct = Math.min(100, (member.used / member.limit) * 100);
  const split = bill != null ? schemeSplit(bill, member) : null;
  const active = member.status === "Active";
  return (
    <div className="space-y-3 rounded-lg border border-[var(--color-border-panel)] bg-card p-4">
      <div className="flex flex-wrap items-start justify-between gap-2">
        <div>
          <p className="font-semibold">{member.scheme}</p>
          <p className="text-sm text-muted-foreground">
            Member <span className="font-mono">{member.memberNo}</span> · {member.relation}
            {member.principal ? ` of ${member.principal}` : ""}
          </p>
        </div>
        <span className={cn("rounded-full border px-2 py-0.5 text-xs font-medium", active ? TONE_BOX.success : TONE_BOX.error)}>{member.status}</span>
      </div>
      <div>
        <div className="flex justify-between text-sm">
          <span>Outpatient cover</span>
          <span className="tabular-nums">
            {kes(remaining)} left of {kes(member.limit)}
          </span>
        </div>
        <div className="mt-1 h-2 overflow-hidden rounded-full bg-muted" role="meter" aria-label="Cover used" aria-valuemin={0} aria-valuemax={member.limit} aria-valuenow={member.used}>
          <div className={cn("h-full rounded-full", pct >= 90 ? "bg-status-error-text" : "bg-primary")} style={{ width: `${pct}%` }} />
        </div>
        <p className="mt-1 text-xs text-muted-foreground">
          {member.copayPct}% co-pay · valid until {formatDate(member.validUntil)}
          {pct >= 90 && active ? <span className="font-medium text-status-error-text"> · cover nearly used up</span> : null}
        </p>
      </div>
      {split ? (
        <dl className="grid grid-cols-2 gap-px overflow-hidden rounded-md border border-[var(--color-border-panel)] bg-[var(--color-border-panel)] text-sm">
          <div className="bg-card px-3 py-2">
            <dt className="text-xs text-muted-foreground">Scheme pays (claim)</dt>
            <dd className="font-semibold tabular-nums">{kes(split.scheme)}</dd>
          </div>
          <div className="bg-card px-3 py-2">
            <dt className="text-xs text-muted-foreground">Customer pays now</dt>
            <dd className="font-semibold tabular-nums">{kes(split.customer)}</dd>
          </div>
          {!active || split.capped ? (
            <p className="col-span-2 bg-card px-3 py-2 text-xs text-status-warning-text">{!active ? `The membership is ${member.status.toLowerCase()}: the customer pays in full.` : "The cover runs out on this bill, so the customer pays the rest."}</p>
          ) : null}
        </dl>
      ) : null}
    </div>
  );
}

/* --------------------------------- 13. Loyalty account --------------------------------- */

export type PointsEntry = { id: string; date: string; kind: "Earned" | "Redeemed" | "Expired" | "Adjusted"; points: number; ref: string; note?: string };

/** Loyalty ledger (PRD 4.6): every earn and redeem with a running balance, and points about to expire. */
export function LoyaltyLedger({ entries, rule, expiring, formatDate }: { entries: PointsEntry[]; rule: string; expiring?: { points: number; on: string }; formatDate: (iso: string) => string }) {
  const running = entries.reduce<number[]>((acc, e) => [...acc, (acc.at(-1) ?? 0) + e.points], []);
  const balance = running.at(-1) ?? 0;
  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-baseline justify-between gap-2">
        <p>
          <span className="text-2xl font-semibold tabular-nums">{balance.toLocaleString("en-US")}</span> <span className="text-sm text-muted-foreground">points</span>
        </p>
        <p className="text-xs text-muted-foreground">{rule}</p>
      </div>
      {expiring?.points ? <p className={cn("rounded-md border px-3 py-2 text-sm", TONE_BOX.warning)}>{expiring.points.toLocaleString("en-US")} points expire on {formatDate(expiring.on)} unless used.</p> : null}
      <div className="overflow-x-auto rounded-lg border border-[var(--color-border-panel)] bg-card">
        <table className="w-full border-collapse text-sm tabular-nums">
          <caption className="sr-only">Points history</caption>
          <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
            <tr>
              {["Date", "What", "Reference", "Points", "Balance"].map((h) => (
                <th key={h} scope="col" className={cn("px-3 py-2 font-medium", (h === "Points" || h === "Balance") && "text-right")}>
                  {h}
                </th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-[var(--color-border-subtle)]">
            {entries.map((e, i) => (
              <tr key={e.id}>
                <td className="px-3 py-2 whitespace-nowrap">{formatDate(e.date)}</td>
                <td className="px-3 py-2">
                  {e.kind}
                  {e.note ? <span className="block text-xs text-muted-foreground">{e.note}</span> : null}
                </td>
                <td className="px-3 py-2 font-mono text-xs">{e.ref}</td>
                <td className="px-3 py-2 text-right">{e.points > 0 ? `+${e.points}` : `−${-e.points}`}</td>
                <td className="px-3 py-2 text-right font-medium">{running[i].toLocaleString("en-US")}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* --------------------------------- 14. Medical records --------------------------------- */

export type LabValue = { test: string; value: number; unit: string; low: number; high: number };
/** Customers API Part 1, Q4: entries are never edited or deleted; a mistake is marked entered in error and stays in the history. */
type EnteredInError = { error?: { reason: string; by: string; at: string } };
export type MedicalEntry = EnteredInError &
  (
    | { id: string; kind: "Diagnosis"; date: string; by: string; text: string }
    | { id: string; kind: "Allergy"; date: string; by: string; text: string; severity: "Mild" | "Severe" }
    | { id: string; kind: "Lab result"; date: string; by: string; lab: string; values: LabValue[] }
    | { id: string; kind: "Sick-off note"; date: string; by: string; from: string; to: string; reason: string }
  );

const ICON = { Diagnosis: StethoscopeIcon, Allergy: ShieldAlertIcon, "Lab result": FlaskConicalIcon, "Sick-off note": NotebookPenIcon } as const;

/** Flag a lab value against its reference range as a word (never colour alone). */
export const labFlag = (v: LabValue) => (v.value < v.low ? "Low" : v.value > v.high ? "High" : "Normal");

/**
 * Medical record timeline (PRD 4.4, CU-08): diagnoses, allergies, lab results and sick-off notes, newest
 * first, each with who recorded it. Lab values show the reference range and High / Low as words. Allergies
 * marked Severe are also shown at the till. Render only for permitted roles, under the sensitive-data notice.
 */
export function MedicalTimeline({ entries, formatDate, onMarkError }: { entries: MedicalEntry[]; formatDate: (iso: string) => string; /** Offers "Entered in error" on each entry not already marked. */ onMarkError?: (id: string) => void }) {
  const sorted = [...entries].sort((a, b) => b.date.localeCompare(a.date));
  return (
    <ol className="space-y-3">
      {sorted.map((e) => {
        const Icon = ICON[e.kind];
        const severe = e.kind === "Allergy" && e.severity === "Severe" && !e.error;
        return (
          <li key={e.id} className="flex gap-3">
            <span className={cn("mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full border", severe ? TONE_BOX.error : "border-[var(--color-border-panel)] bg-muted text-muted-foreground")} aria-hidden>
              <Icon className="size-4" />
            </span>
            <div className={cn("min-w-0 flex-1 rounded-lg border border-[var(--color-border-panel)] bg-card px-3 py-2", e.error && "bg-muted/40")}>
              {e.error ? (
                <p className="mb-1 text-xs font-medium text-status-warning-text">
                  Entered in error: {e.error.reason} ({e.error.by}, {e.error.at})
                </p>
              ) : null}
              <div className={cn(e.error && "text-muted-foreground line-through")}>
              <p className="flex flex-wrap items-baseline justify-between gap-2 text-sm">
                <span className="font-semibold">
                  {e.kind}
                  {severe ? <span className="ml-1.5 text-xs font-semibold text-status-error-text">Severe</span> : null}
                </span>
                <span className="text-xs text-muted-foreground">
                  {formatDate(e.date)} · {e.by}
                </span>
              </p>
              {e.kind === "Diagnosis" || e.kind === "Allergy" ? <p className="mt-0.5 text-sm">{e.text}</p> : null}
              {e.kind === "Sick-off note" ? (
                <p className="mt-0.5 text-sm">
                  Off work {formatDate(e.from)} to {formatDate(e.to)}: {e.reason}
                </p>
              ) : null}
              {e.kind === "Lab result" ? (
                <table className="mt-1 w-full text-sm tabular-nums">
                  <caption className="sr-only">
                    {e.lab} results, {formatDate(e.date)}
                  </caption>
                  <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
                    <tr>
                      <th scope="col" className="py-0.5 font-medium">
                        {e.lab}
                      </th>
                      <th scope="col" className="py-0.5 text-right font-medium">
                        Result
                      </th>
                      <th scope="col" className="py-0.5 text-right font-medium">
                        Normal range
                      </th>
                      <th scope="col" className="py-0.5 pl-3 font-medium">
                        <span className="sr-only">Flag</span>
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    {e.values.map((v) => {
                      const f = labFlag(v);
                      return (
                        <tr key={v.test} className="border-t border-[var(--color-border-subtle)]">
                          <th scope="row" className="py-1 text-left font-normal">
                            {v.test}
                          </th>
                          <td className={cn("py-1 text-right", f !== "Normal" && "font-semibold")}>
                            {v.value} {v.unit}
                          </td>
                          <td className="py-1 text-right text-muted-foreground">
                            {v.low}–{v.high}
                          </td>
                          <td className={cn("py-1 pl-3 text-xs font-medium", f === "Normal" ? "text-muted-foreground" : TONE_TEXT.error)}>{f}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              ) : null}
              </div>
              {onMarkError && !e.error ? (
                <button type="button" className="mt-1 cursor-pointer text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline" onClick={() => onMarkError(e.id)}>
                  Entered in error…
                </button>
              ) : null}
            </div>
          </li>
        );
      })}
      {!sorted.length ? (
        <li className="flex items-center gap-2 text-sm text-muted-foreground">
          <HeartPulseIcon className="size-4" aria-hidden /> No medical records yet.
        </li>
      ) : null}
    </ol>
  );
}

/* --------------------------------- 15. Complaint case --------------------------------- */

export type CaseStatus = "Open" | "In progress" | "Resolved" | "Closed";
export type CaseNote = { id: string; at: string; by: string; text: string; kind?: "note" | "status" };
export type ComplaintCase = { ref: string; title: string; customer: string; sale?: string; category: string; opened: string; due: string; status: CaseStatus; assignee?: string; resolution?: string; notes: CaseNote[] };

/** "Overdue" when still open past its due date; the word sits beside the date, so it isn't colour alone. */
export const caseOverdue = (c: ComplaintCase, today: string) => (c.status === "Open" || c.status === "In progress") && c.due < today;

/* -------------------------------- 16. Supplier price list -------------------------------- */

export type SupplierPrice = { supplier: string; cost: number; lastReceived: string; leadDays: number | null };

/**
 * Supplier price comparison (PRD 5.2): each supplier's last cost for a product, filled from goods received.
 * The cheapest current price is marked in words; a price older than 90 days is "Stale" because it may no
 * longer hold. Differences show against the cheapest.
 */
export function SupplierPrices({ product, prices, today, formatDate }: { product: string; prices: SupplierPrice[]; today: string; formatDate: (iso: string) => string }) {
  const age = (iso: string) => Math.round((new Date(today).getTime() - new Date(iso).getTime()) / 86400000);
  const fresh = prices.filter((p) => age(p.lastReceived) <= 90);
  const best = (fresh.length ? fresh : prices).reduce((a, b) => (b.cost < a.cost ? b : a));
  const sorted = [...prices].sort((a, b) => a.cost - b.cost);
  return (
    <div className="overflow-x-auto rounded-lg border border-[var(--color-border-panel)] bg-card">
      <table className="w-full border-collapse text-sm tabular-nums">
        <caption className="sr-only">Supplier prices for {product}</caption>
        <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
          <tr>
            {["Supplier", "Last cost", "vs cheapest", "Last received", "Lead time"].map((h) => (
              <th key={h} scope="col" className={cn("px-3 py-2 font-medium", (h === "Last cost" || h === "vs cheapest") && "text-right")}>
                {h}
              </th>
            ))}
          </tr>
        </thead>
        <tbody className="divide-y divide-[var(--color-border-subtle)]">
          {sorted.map((p) => {
            const stale = age(p.lastReceived) > 90;
            const diff = p === best ? 0 : ((p.cost - best.cost) / best.cost) * 100;
            return (
              <tr key={p.supplier} className={cn(p === best && "bg-[var(--color-bg-selected)]")}>
                <th scope="row" className="px-3 py-2 text-left font-medium">
                  {p.supplier}
                  {p === best ? <span className="ml-1.5 text-xs font-semibold text-status-success-text">Cheapest</span> : null}
                </th>
                <td className="px-3 py-2 text-right">{n2(p.cost)}</td>
                <td className="px-3 py-2 text-right text-muted-foreground">{p === best ? "–" : `${diff > 0 ? "+" : "−"}${Math.abs(diff).toFixed(1)}%`}</td>
                <td className="px-3 py-2">
                  {formatDate(p.lastReceived)}
                  {stale ? <span className="ml-1.5 text-xs font-medium text-status-warning-text">Stale, {age(p.lastReceived)} days</span> : null}
                </td>
                <td className="px-3 py-2">{p.leadDays != null ? `${p.leadDays} days` : <span className="text-muted-foreground">Not recorded</span>}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

/**
 * Complaint or feedback case (PRD 4.7): who it's about, linked sale, who owns it and by when. Notes and
 * status changes form one thread, oldest first. Resolving needs a resolution in words; a case past its due
 * date says "Overdue". Closing happens after the customer confirms.
 */
export function ComplaintThread({ c, today, formatDate }: { c: ComplaintCase; today: string; formatDate: (iso: string) => string }) {
  const overdue = caseOverdue(c, today);
  return (
    <div className="space-y-3">
      <dl className="grid grid-cols-2 gap-x-6 gap-y-2 text-sm sm:grid-cols-4">
        {[
          ["Customer", c.customer],
          ["Sale", c.sale ?? "None"],
          ["Category", c.category],
          ["Owner", c.assignee ?? "Not assigned"],
        ].map(([k, v]) => (
          <div key={k}>
            <dt className="text-xs text-muted-foreground">{k}</dt>
            <dd className={cn("font-medium", v === "Not assigned" && "text-status-warning-text")}>{v}</dd>
          </div>
        ))}
        <div>
          <dt className="text-xs text-muted-foreground">Due</dt>
          <dd className="font-medium">
            {formatDate(c.due)}
            {overdue ? <span className="ml-1.5 text-xs font-semibold text-status-error-text">Overdue</span> : null}
          </dd>
        </div>
      </dl>
      {c.resolution ? <p className={cn("rounded-md border px-3 py-2 text-sm", TONE_BOX.success)}>Resolution: {c.resolution}</p> : null}
      <ol className="space-y-2 border-l-2 border-[var(--color-border-panel)] pl-4">
        {c.notes.map((n) => (
          <li key={n.id} className="text-sm">
            <p className="text-xs text-muted-foreground">
              {n.at} · {n.by}
            </p>
            <p className={cn(n.kind === "status" && "font-medium")}>{n.text}</p>
          </li>
        ))}
      </ol>
    </div>
  );
}
/* ------------------------------ 14b. Add a medical entry ------------------------------ */

/**
 * Add to a customer's medical record (PRD 4.4): the fields follow the kind of entry. A sick-off note can't
 * end before it starts or run past 30 days without a doctor; lab values need a range so they can be flagged.
 */
export function MedicalEntryForm({ by, today, onSave }: { by: string; today: string; onSave: (e: MedicalEntry) => void }) {
  const [kind, setKind] = React.useState<MedicalEntry["kind"]>("Allergy");
  const [text, setText] = React.useState("");
  const [severity, setSeverity] = React.useState<"Mild" | "Severe">("Mild");
  const [from, setFrom] = React.useState(today);
  const [to, setTo] = React.useState(today);
  const [lab, setLab] = React.useState({ test: "", value: "", unit: "", low: "", high: "" });
  const [tried, setTried] = React.useState(false);
  const days = Math.round((new Date(to).getTime() - new Date(from).getTime()) / 86400000) + 1;
  const err =
    kind === "Lab result"
      ? !lab.test.trim() || lab.value === "" || lab.low === "" || lab.high === ""
        ? "Enter the test, the result and its normal range."
        : Number(lab.low) > Number(lab.high)
          ? "The low end of the range is above the high end."
          : undefined
      : kind === "Sick-off note"
        ? to < from
          ? "The note ends before it starts."
          : days > 30
            ? "Over 30 days needs a doctor's note, not a pharmacy one."
            : !text.trim()
              ? "Enter the reason."
              : undefined
        : !text.trim()
          ? "Describe it."
          : undefined;
  const input = "w-full";
  return (
    <div className="space-y-3 text-sm">
      <label className="block max-w-56 space-y-1">
        <span className="font-medium">Kind of entry</span>
        <NativeSelect className={input} value={kind} onChange={(e) => setKind(e.target.value as MedicalEntry["kind"])}>
          {["Allergy", "Diagnosis", "Lab result", "Sick-off note"].map((k) => (
            <NativeSelectOption key={k}>{k}</NativeSelectOption>
          ))}
        </NativeSelect>
      </label>
      {kind === "Lab result" ? (
        <div className="grid grid-cols-2 gap-2 sm:grid-cols-5">
          {(["test", "value", "unit", "low", "high"] as const).map((k) => (
            <label key={k} className="space-y-1">
              <span className="font-medium capitalize">{k === "low" ? "Range low" : k === "high" ? "Range high" : k}</span>
              <Input className={input} inputMode={k === "value" || k === "low" || k === "high" ? "decimal" : undefined} value={lab[k]} onChange={(e) => setLab({ ...lab, [k]: e.target.value })} />
            </label>
          ))}
        </div>
      ) : (
        <>
          {kind === "Sick-off note" ? (
            <div className="grid max-w-md grid-cols-2 gap-2">
              <label className="space-y-1">
                <span className="font-medium">From</span>
                <Input className={input} type="date" value={from} onChange={(e) => setFrom(e.target.value)} />
              </label>
              <label className="space-y-1">
                <span className="font-medium">To</span>
                <Input className={input} type="date" value={to} onChange={(e) => setTo(e.target.value)} />
              </label>
            </div>
          ) : null}
          <label className="block space-y-1">
            <span className="font-medium">{kind === "Sick-off note" ? "Reason" : kind === "Allergy" ? "What and what happens" : "Diagnosis"}</span>
            <Input className={input} value={text} onChange={(e) => setText(e.target.value)} />
          </label>
          {kind === "Allergy" ? (
            <label className="flex items-center gap-2">
              <Checkbox checked={severity === "Severe"} onCheckedChange={(v) => setSeverity(v ? "Severe" : "Mild")} /> Severe: warn at the till whenever this customer buys a related medicine
            </label>
          ) : null}
        </>
      )}
      {tried && err ? <p className="text-xs text-status-error-text">{err}</p> : null}
      <div className="flex justify-end">
        <Button
          onClick={() => {
            setTried(true);
            if (err) return;
            const id = `m${Date.now()}`;
            const entry: MedicalEntry =
              kind === "Lab result"
                ? { id, kind, date: today, by, lab: lab.test, values: [{ test: lab.test, value: Number(lab.value), unit: lab.unit, low: Number(lab.low), high: Number(lab.high) }] }
                : kind === "Sick-off note"
                  ? { id, kind, date: today, by, from, to, reason: text.trim() }
                  : kind === "Allergy"
                    ? { id, kind, date: today, by, text: text.trim(), severity }
                    : { id, kind, date: today, by, text: text.trim() };
            onSave(entry);
            setText("");
            setTried(false);
          }}
        >
          Add to record
        </Button>
      </div>
    </div>
  );
}

/* ------------------------------ 13b. Loyalty earning rule ------------------------------ */

export type LoyaltyRule = { kesPerPoint: number; pointValue: number; block: number; expiryMonths: number; excludeRx: boolean };

/** The loyalty rule in one place, with what it means for a typical basket, so the cost is visible. */
export function LoyaltyRuleForm({ rule, onChange }: { rule: LoyaltyRule; onChange: (r: LoyaltyRule) => void }) {
  const basket = 2000;
  const earned = Math.floor(basket / rule.kesPerPoint);
  const costPct = rule.kesPerPoint > 0 ? (rule.pointValue / rule.kesPerPoint) * 100 : 0;
  const input = "w-24 tabular-nums";
  const num = (k: keyof LoyaltyRule) => (e: React.ChangeEvent<HTMLInputElement>) => onChange({ ...rule, [k]: Math.max(0, Number(e.target.value) || 0) });
  return (
    <div className="space-y-3 text-sm">
      <div className="flex flex-wrap items-center gap-x-6 gap-y-3">
        <label className="flex items-center gap-2">
          1 point per KES <Input className={input} inputMode="numeric" value={rule.kesPerPoint} onChange={num("kesPerPoint")} aria-label="Shillings spent per point" />
        </label>
        <label className="flex items-center gap-2">
          1 point = KES <Input className={input} inputMode="decimal" value={rule.pointValue} onChange={num("pointValue")} aria-label="Value of a point in shillings" />
        </label>
        <label className="flex items-center gap-2">
          Used in blocks of <Input className={input} inputMode="numeric" value={rule.block} onChange={num("block")} aria-label="Redemption block" />
        </label>
        <label className="flex items-center gap-2">
          Expire after <Input className={input} inputMode="numeric" value={rule.expiryMonths} onChange={num("expiryMonths")} aria-label="Months before points expire" /> months
        </label>
        <label className="flex items-center gap-2">
          <Checkbox checked={rule.excludeRx} onCheckedChange={(v) => onChange({ ...rule, excludeRx: !!v })} /> No points on prescription medicines
        </label>
      </div>
      <p className={cn("rounded-md border px-3 py-2", costPct > 3 ? TONE_BOX.warning : "border-[var(--color-border-panel)]")}>
        A KES {n2(basket)} basket earns {earned} points, worth KES {n2(earned * rule.pointValue)}: a {costPct.toFixed(1)}% discount when redeemed
        {costPct > 3 ? ", more than most pharmacies give" : ""}.
      </p>
    </div>
  );
}
