"use client";

import * as React from "react";
import Image from "next/image";
import { DropletIcon, MinusIcon, PackageIcon, PillIcon, PlusIcon, ShoppingBasketIcon, StethoscopeIcon, Trash2Icon, TriangleAlertIcon } from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

import { Money } from "./money";
import { cartTotals, type CartItem } from "./sale";
import { TONE_BOX } from "./tones";

/** A cart line with the extra detail the compact layout shows: pack size, form (for the thumbnail), Rx flag and image. */
export type CartLineItem = CartItem & { pack?: string; form?: string; requiresRx?: boolean; image?: string };

const pad = (n: number) => String(n).padStart(2, "0");

/* ------------------------------------ Pill stepper ------------------------------------ */

/**
 * Compact quantity pill: − 01 +. At the minimum the minus becomes a bin, so taking the last unit off
 * removes the line instead of silently stopping at 1.
 */
export function PillStepper({
  value,
  onChange,
  onRemove,
  max = 999,
  disabled,
  label,
}: {
  value: number;
  onChange: (v: number) => void;
  onRemove?: () => void;
  max?: number;
  disabled?: boolean;
  label: string;
}) {
  const atMin = value <= 1;
  return (
    <div className={cn("inline-flex h-8 items-center rounded-full border border-input bg-background", disabled && "opacity-60")}>
      <Button
        variant="ghost"
        size="icon-xs"
        className="ml-0.5 rounded-full"
        aria-label={atMin && onRemove ? `Remove ${label}` : `Decrease ${label}`}
        disabled={disabled || (atMin && !onRemove)}
        onClick={() => (atMin ? onRemove?.() : onChange(value - 1))}
      >
        {atMin && onRemove ? <Trash2Icon className="text-status-error-text" /> : <MinusIcon />}
      </Button>
      <span className="min-w-7 text-center text-sm font-semibold text-primary tabular-nums" aria-live="polite" aria-label={`${value} of ${label}`}>
        {pad(value)}
      </span>
      <Button variant="ghost" size="icon-xs" className="mr-0.5 rounded-full" aria-label={`Increase ${label}`} disabled={disabled || value >= max} onClick={() => onChange(value + 1)}>
        <PlusIcon />
      </Button>
    </div>
  );
}

/* ------------------------------------ Thumbnail -------------------------------------- */

function FormIcon({ item }: { item: CartLineItem }) {
  const f = (item.form ?? "").toLowerCase();
  const cls = "size-5";
  if (item.type === "Service") return <StethoscopeIcon className={cls} aria-hidden />;
  if (/tablet|capsule/.test(f)) return <PillIcon className={cls} aria-hidden />;
  if (/syrup|suspension|drops|solution|bottle/.test(f)) return <DropletIcon className={cls} aria-hidden />;
  return <PackageIcon className={cls} aria-hidden />;
}

/** Product image when there is one, otherwise a tinted tile with an icon for the dosage form. */
export function CartThumb({ item, className }: { item: CartLineItem; className?: string }) {
  return (
    <span className={cn("relative flex size-11 shrink-0 items-center justify-center overflow-hidden rounded-lg border border-border bg-muted text-muted-foreground", className)}>
      {item.image ? <Image src={item.image} alt="" fill sizes="44px" className="object-contain p-1" /> : <FormIcon item={item} />}
    </span>
  );
}

/* ------------------------------------ Cart line -------------------------------------- */

/**
 * Compact cart line: thumbnail, name on one line, pack and unit price, pill stepper, line total in teal.
 * A per-unit discount shows the original unit price struck through.
 */
export function CartLineCompact({
  item,
  onQtyChange,
  onRemove,
  disabled = false,
}: {
  item: CartLineItem;
  onQtyChange?: (qty: number) => void;
  onRemove?: () => void;
  disabled?: boolean;
}) {
  const unit = item.unitPrice - (item.discount ?? 0);
  const label = `${item.name}${item.pack ? `, ${item.pack}` : ""}`;
  return (
    <div className={cn("flex items-center gap-3 py-3", disabled && "opacity-60")}>
      <CartThumb item={item} />
      <div className="min-w-0 flex-1">
        <div className="flex min-w-0 items-center gap-1.5">
          <p className="truncate text-sm font-medium text-foreground" title={item.name}>
            {item.name}
          </p>
          {item.requiresRx ? (
            <Badge variant="outline" className={cn("h-4.5 shrink-0 rounded px-1 text-[0.6875rem] font-semibold", TONE_BOX.warning)}>
              Rx
            </Badge>
          ) : null}
        </div>
        <p className="mt-0.5 flex flex-wrap items-baseline gap-x-1.5 text-xs text-muted-foreground tabular-nums">
          {item.pack ? (
            <>
              <span>{item.pack}</span>
              <span aria-hidden>·</span>
            </>
          ) : null}
          <span>{unit.toFixed(2)} each</span>
          {item.discount ? <span className="line-through">{item.unitPrice.toFixed(2)}</span> : null}
        </p>
      </div>
      <div className="flex shrink-0 flex-col items-end gap-1">
        <PillStepper
          value={item.qty}
          onChange={(v) => onQtyChange?.(v)}
          onRemove={onRemove}
          max={item.type === "Service" ? 99 : (item.maxQty ?? 999)}
          disabled={disabled}
          label={label}
        />
        <Money amount={unit * item.qty} className="font-semibold text-primary" />
      </div>
    </div>
  );
}

/* ------------------------------------ Bill details ----------------------------------- */

function BillRow({ label, children, className }: { label: React.ReactNode; children: React.ReactNode; className?: string }) {
  return (
    <div className={cn("flex items-baseline justify-between gap-3 text-sm", className)}>
      <span className="text-muted-foreground">{label}</span>
      {children}
    </div>
  );
}

/**
 * Bill details card: item total, savings, delivery (Free in green when waived), VAT, and To pay.
 * Uses the same maths as CartSummary: per-unit discounts, delivery folded into the taxable subtotal.
 */
export function BillDetails({
  items,
  delivery,
  vatApplies = true,
  className,
}: {
  items: CartLineItem[];
  /** Omit for collection at the counter. `fee: 0` shows Free. */
  delivery?: { fee: number; note?: string };
  vatApplies?: boolean;
  className?: string;
}) {
  const fee = delivery?.fee ?? 0;
  const t = cartTotals(items, fee, vatApplies);
  const list = items.reduce((s, l) => s + l.unitPrice * l.qty, 0);
  const saved = list - t.goods;
  const count = items.reduce((s, l) => s + l.qty, 0);
  return (
    <section aria-label="Bill details" className={cn("rounded-xl border border-border bg-card p-4", className)}>
      <h3 className="mb-3 text-xs font-semibold tracking-[0.06em] text-muted-foreground uppercase">Bill details</h3>
      <div className="space-y-2">
        <BillRow label={`Item total (${count} ${count === 1 ? "unit" : "units"})`}>
          <Money amount={list} />
        </BillRow>
        {saved > 0 ? (
          <BillRow label="Discount">
            <Money amount={saved} negative className="text-status-success-text" />
          </BillRow>
        ) : null}
        {delivery ? (
          <BillRow label={delivery.note ? `Delivery (${delivery.note})` : "Delivery fee"}>
            {fee === 0 ? <span className="font-medium text-status-success-text">Free</span> : <Money amount={fee} />}
          </BillRow>
        ) : null}
        <BillRow label={vatApplies ? "VAT 16%" : "VAT (not applied)"}>
          <Money amount={t.vat} />
        </BillRow>
      </div>
      <div className="mt-3 flex items-baseline justify-between border-t border-border pt-3">
        <span className="text-base font-semibold text-foreground">To pay</span>
        <Money amount={t.total} size="lg" className="text-foreground" />
      </div>
    </section>
  );
}

/* ------------------------------------ Rx notice -------------------------------------- */

export function RxNotice({ count, className }: { count: number; className?: string }) {
  return (
    <div role="note" className={cn("flex gap-2 rounded-lg border px-3 py-2.5 text-sm", TONE_BOX.warning, className)}>
      <TriangleAlertIcon className="mt-0.5 size-4 shrink-0" aria-hidden />
      <p>
        {count === 1 ? "1 item needs" : `${count} items need`} a prescription. Check it, or record the prescriber, before taking payment.
      </p>
    </div>
  );
}

/* ------------------------------------ Cart panel ------------------------------------- */

/**
 * Side-panel cart: header with count and clear, lines that scroll, and a pinned footer with bill details,
 * the Rx notice when needed, and one full-width action.
 */
export function CartPanel({
  initialItems,
  delivery,
  vatApplies = true,
  actionLabel = "Proceed to payment",
  onAction,
  className,
}: {
  initialItems: CartLineItem[];
  delivery?: { fee: number; note?: string };
  vatApplies?: boolean;
  actionLabel?: string;
  onAction?: (items: CartLineItem[]) => void;
  className?: string;
}) {
  const [items, setItems] = React.useState(initialItems);
  const setQty = (id: number, qty: number) => setItems((xs) => xs.map((x) => (x.id === id ? { ...x, qty } : x)));
  const remove = (id: number) => setItems((xs) => xs.filter((x) => x.id !== id));
  const units = items.reduce((s, l) => s + l.qty, 0);
  const rx = items.filter((i) => i.requiresRx).length;

  return (
    <aside aria-label="Cart" className={cn("flex h-full min-h-0 flex-col bg-card", className)}>
      <header className="flex shrink-0 items-center justify-between border-b border-border px-4 py-3">
        <h2 className="text-base font-semibold">
          Cart <span className="font-normal text-muted-foreground">· {items.length} {items.length === 1 ? "line" : "lines"}, {units} {units === 1 ? "unit" : "units"}</span>
        </h2>
        {items.length ? (
          <Button variant="ghost" size="sm" onClick={() => setItems([])}>
            Clear
          </Button>
        ) : null}
      </header>

      {items.length ? (
        <div className="min-h-0 flex-1 divide-y divide-border overflow-y-auto px-4">
          {items.map((it) => (
            <CartLineCompact key={it.id} item={it} onQtyChange={(q) => setQty(it.id, q)} onRemove={() => remove(it.id)} />
          ))}
        </div>
      ) : (
        <div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-2 px-6 text-center">
          <span className="flex size-12 items-center justify-center rounded-full bg-muted text-muted-foreground">
            <ShoppingBasketIcon className="size-6" aria-hidden />
          </span>
          <p className="text-sm font-medium">The cart is empty</p>
          <p className="text-xs text-muted-foreground">Scan a barcode or search to add items.</p>
          <Button variant="outline" size="sm" className="mt-1" onClick={() => setItems(initialItems)}>
            Restore demo items
          </Button>
        </div>
      )}

      <footer className="shrink-0 space-y-3 border-t border-border bg-muted/40 p-4">
        {items.length ? <BillDetails items={items} delivery={delivery} vatApplies={vatApplies} /> : null}
        {rx ? <RxNotice count={rx} /> : null}
        <Button size="lg" className="h-11 w-full text-base" disabled={!items.length} onClick={() => onAction?.(items)}>
          {actionLabel}
        </Button>
      </footer>
    </aside>
  );
}
