"use client";

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

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

/*
 * Barcode label printing (IN-06): saved label sizes, and a print plan of which products and how many.
 * Sizes are saved once (the roll or sheet the pharmacy buys) and chosen by name, so nobody types
 * millimetres at the counter.
 */

export type LabelSize = { id: string; name: string; width: number; height: number; perSheet: number };

export function labelSizeProblems(s: { name: string; width: string; height: string; perSheet: string }, sizes: LabelSize[]) {
  const p: string[] = [];
  if (!s.name.trim()) p.push("Name the size, e.g. “Shelf roll 38 × 25”.");
  else if (sizes.some((x) => x.name.toLowerCase() === s.name.trim().toLowerCase())) p.push("A size with this name is already saved.");
  const w = Number(s.width);
  const h = Number(s.height);
  if (!(w >= 20 && w <= 110)) p.push("Width is 20 to 110 mm.");
  if (!(h >= 10 && h <= 80)) p.push("Height is 10 to 80 mm.");
  if (!/^[1-9]\d*$/.test(s.perSheet) || Number(s.perSheet) > 80) p.push("Labels per sheet: 1 for a roll, up to 80 on A4.");
  if (w && h && w < 30 && h < 20) p.push("Under 30 × 20 mm a barcode won't scan reliably.");
  return p;
}

export function LabelSizes({ sizes, onChange }: { sizes: LabelSize[]; onChange: (s: LabelSize[]) => void }) {
  const [d, setD] = React.useState({ name: "", width: "", height: "", perSheet: "1" });
  const [tried, setTried] = React.useState(false);
  const p = labelSizeProblems(d, sizes);
  return (
    <div className="space-y-3">
      <ul className="divide-y divide-[var(--color-border-subtle)] rounded-md border border-[var(--color-border-panel)] bg-card">
        {sizes.map((s) => (
          <li key={s.id} className="flex items-center gap-3 px-3 py-2 text-sm">
            <span className="grid shrink-0 place-items-center rounded-[2px] border border-foreground/40 bg-background" style={{ width: s.width / 2, height: s.height / 2 }} aria-hidden />
            <span className="flex-1">
              <span className="font-medium">{s.name}</span>
              <span className="block text-xs text-muted-foreground tabular-nums">
                {s.width} × {s.height} mm · {s.perSheet === 1 ? "roll" : `${s.perSheet} per A4 sheet`}
              </span>
            </span>
            <Button size="icon-sm" variant="ghost" aria-label={`Delete ${s.name}`} disabled={sizes.length === 1} onClick={() => onChange(sizes.filter((x) => x.id !== s.id))}>
              <Trash2Icon />
            </Button>
          </li>
        ))}
      </ul>
      <div className="flex flex-wrap items-end gap-2">
        <Input aria-label="Size name" placeholder="Name" className="min-w-40 flex-1" value={d.name} onChange={(e) => setD({ ...d, name: e.target.value })} />
        <Input aria-label="Width in mm" placeholder="W mm" className="w-20 tabular-nums" inputMode="numeric" value={d.width} onChange={(e) => setD({ ...d, width: e.target.value })} />
        <Input aria-label="Height in mm" placeholder="H mm" className="w-20 tabular-nums" inputMode="numeric" value={d.height} onChange={(e) => setD({ ...d, height: e.target.value })} />
        <Input aria-label="Labels per sheet" placeholder="Per sheet" className="w-24 tabular-nums" inputMode="numeric" value={d.perSheet} onChange={(e) => setD({ ...d, perSheet: e.target.value })} />
        <Button
          size="sm"
          onClick={() => {
            setTried(true);
            if (p.length) return;
            onChange([...sizes, { id: `s${Date.now()}`, name: d.name.trim(), width: Number(d.width), height: Number(d.height), perSheet: Number(d.perSheet) }]);
            setD({ name: "", width: "", height: "", perSheet: "1" });
            setTried(false);
          }}
        >
          Save size
        </Button>
      </div>
      {tried && p.length ? (
        <ul className="list-disc pl-5 text-xs text-status-error-text">
          {p.map((x) => (
            <li key={x}>{x}</li>
          ))}
        </ul>
      ) : null}
    </div>
  );
}

export type LabelItem = { id: number; name: string; barcode: string; suggested: number; why: string };

/** Choose a saved size and a quantity per product; the plan says how many labels and sheets that is. */
export function LabelPrintPlan({ items, sizes, onPrint }: { items: LabelItem[]; sizes: LabelSize[]; onPrint: (p: { size: LabelSize; labels: number; sheets: number; quantities: Record<number, number> }) => void }) {
  const [sizeId, setSizeId] = React.useState(sizes[0]?.id ?? "");
  const [qty, setQty] = React.useState<Record<number, string>>(() => Object.fromEntries(items.map((i) => [i.id, String(i.suggested)])));
  const size = sizes.find((s) => s.id === sizeId) ?? sizes[0];
  const labels = items.reduce((s, i) => s + (Number(qty[i.id]) || 0), 0);
  const sheets = size ? Math.ceil(labels / size.perSheet) : 0;
  const bad = items.filter((i) => !/^\d*$/.test(qty[i.id] ?? "") || Number(qty[i.id]) > 500);
  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center gap-2 text-sm">
        <label htmlFor="lp-size" className="font-medium">
          Label size
        </label>
        <NativeSelect id="lp-size" value={size?.id} onChange={(e) => setSizeId(e.target.value)}>
          {sizes.map((s) => (
            <NativeSelectOption key={s.id} value={s.id}>
              {s.name}
            </NativeSelectOption>
          ))}
        </NativeSelect>
      </div>
      <ul className="divide-y divide-[var(--color-border-subtle)] rounded-md border border-[var(--color-border-panel)] bg-card">
        {items.map((i) => (
          <li key={i.id} className="flex items-center gap-3 px-3 py-2 text-sm">
            <span className="flex-1">
              {i.name}
              <span className="block font-mono text-xs text-muted-foreground">
                {i.barcode} · {i.why}
              </span>
            </span>
            <Input aria-label={`Labels for ${i.name}`} className="w-20 text-right tabular-nums" inputMode="numeric" value={qty[i.id] ?? ""} onChange={(e) => setQty({ ...qty, [i.id]: e.target.value })} aria-invalid={bad.includes(i)} />
          </li>
        ))}
      </ul>
      {bad.length ? <p className="text-xs text-status-error-text">Quantities are whole numbers, up to 500 per product.</p> : null}
      <div className="flex flex-wrap items-center justify-between gap-2">
        <p className="text-sm tabular-nums">
          {labels} labels{size && size.perSheet > 1 ? ` on ${sheets} A4 sheet${sheets === 1 ? "" : "s"}` : " on the roll"}
        </p>
        <Button size="sm" disabled={!labels || !!bad.length || !size} onClick={() => size && onPrint({ size, labels, sheets, quantities: Object.fromEntries(items.map((i) => [i.id, Number(qty[i.id]) || 0])) })}>
          Print {labels} labels
        </Button>
      </div>
    </div>
  );
}
