"use client";

/**
 * Shared by the Receivables views (plan H): the item list priced from the API's products, the lines editor (the
 * design's `QuotationForm` table, used for invoices, where the customer must be registered) and small helpers.
 */

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

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { DocLineIn } from "@/lib/api";
import { formatKES } from "@/lib/format";

export type Item = { id: number; code: string; name: string; unit: string | null; price: number; vat: 0 | 16; taxCode: string | null };
export type Customer = { id: number; name: string; phone: string };
export type EditLine = { id: number; product: string; qty: string; price: string; vat: 0 | 16 };

export const kes = (n: number) => formatKES(n, { decimals: true });
export const pad = (x: number) => String(x).padStart(2, "0");
export const today = () => {
  const d = new Date();
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
};
export const monthStart = () => `${today().slice(0, 8)}01`;
export const localStamp = (d: Date) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
export const apiError = (e: unknown, fallback: string): string => {
  const m = (e as { response?: { data?: { message?: string | string[] } } })?.response?.data?.message;
  return Array.isArray(m) ? m.join(" ") : m || fallback;
};
const num = (s: string) => Number(String(s).replace(/,/g, ""));

/** Lines as the API takes them; problems in the design's words. */
export function linesOut(lines: EditLine[], items: Item[]): { out: DocLineIn[]; problems: string[] } {
  const byName = new Map(items.map((i) => [i.name, i]));
  const problems: string[] = [];
  if (!lines.length) problems.push("Add at least one item.");
  const out = lines.map((l, i) => {
    const it = byName.get(l.product.trim());
    if (!it) problems.push(`Line ${i + 1}: choose the item from the list.`);
    if (!/^[1-9]\d*$/.test(l.qty)) problems.push(`Line ${i + 1}: quantity is a whole number above 0.`);
    if (!(num(l.price) > 0)) problems.push(`Line ${i + 1}: enter the price.`);
    return { productId: it?.id ?? 0, quantity: Number(l.qty), unitPrice: num(l.price) };
  });
  return { out, problems };
}

/** VAT-exclusive totals, as the till and the API charge them. */
export function linesTotal(lines: EditLine[]) {
  const subtotal = lines.reduce((s, l) => s + (Number(l.qty) || 0) * (num(l.price) || 0), 0);
  const vat = lines.reduce((s, l) => s + ((Number(l.qty) || 0) * (num(l.price) || 0) * l.vat) / 100, 0);
  return { subtotal: Math.round(subtotal * 100) / 100, vat: Math.round(vat * 100) / 100, total: Math.round((subtotal + vat) * 100) / 100 };
}

/** The design's quotation line table (`QuotationForm`), on its own for the invoice form. */
export function LinesEditor({ lines, onChange, items, idPrefix }: { lines: EditLine[]; onChange: (l: EditLine[]) => void; items: Item[]; idPrefix: string }) {
  const byName = React.useMemo(() => new Map(items.map((i) => [i.name, i])), [items]);
  const setLine = (id: number, patch: Partial<EditLine>) => onChange(lines.map((l) => (l.id === id ? { ...l, ...patch } : l)));
  const t = linesTotal(lines);
  return (
    <div className="overflow-x-auto rounded-md border border-[var(--color-border-panel)] bg-card">
      <table className="w-full min-w-[600px] text-sm">
        <thead className="bg-[var(--color-bg-surface-subtle)] text-left text-xs text-muted-foreground">
          <tr>
            <th className="px-2 py-2 font-medium">Item</th>
            <th className="w-20 px-2 py-2 text-right font-medium">Qty</th>
            <th className="w-28 px-2 py-2 text-right font-medium">Price</th>
            <th className="w-20 px-2 py-2 font-medium">VAT</th>
            <th className="w-28 px-2 py-2 text-right font-medium">Total</th>
            <th className="w-10" />
          </tr>
        </thead>
        <tbody className="divide-y divide-[var(--color-border-subtle)]">
          {lines.map((l, i) => (
            <tr key={l.id}>
              <td className="px-2 py-1.5">
                <Input
                  aria-label={`Line ${i + 1} item`}
                  list={`${idPrefix}-items`}
                  value={l.product}
                  onChange={(e) => {
                    const known = byName.get(e.target.value);
                    setLine(l.id, known ? { product: e.target.value, price: String(known.price), vat: known.vat } : { product: e.target.value });
                  }}
                />
              </td>
              <td className="px-2 py-1.5">
                <Input aria-label={`Line ${i + 1} quantity`} className="text-right tabular-nums" inputMode="numeric" value={l.qty} onChange={(e) => setLine(l.id, { qty: e.target.value })} />
              </td>
              <td className="px-2 py-1.5">
                <Input aria-label={`Line ${i + 1} price`} className="text-right tabular-nums" inputMode="decimal" value={l.price} onChange={(e) => setLine(l.id, { price: e.target.value })} />
              </td>
              <td className="px-2 py-2 text-xs">{l.vat ? `${l.vat}%` : "Exempt"}</td>
              <td className="px-2 py-2 text-right tabular-nums">{kes((Number(l.qty) || 0) * (num(l.price) || 0) * (1 + l.vat / 100))}</td>
              <td className="px-1 py-1.5">
                <Button size="icon-sm" variant="ghost" aria-label={`Remove line ${i + 1}`} onClick={() => onChange(lines.filter((x) => x.id !== l.id))}>
                  <Trash2Icon />
                </Button>
              </td>
            </tr>
          ))}
        </tbody>
        <tfoot className="border-t-2 border-[var(--color-border-panel)]">
          <tr>
            <td colSpan={2} className="px-2 py-1.5">
              <Button size="sm" variant="ghost" onClick={() => onChange([...lines, { id: Math.max(0, ...lines.map((x) => x.id)) + 1, product: "", qty: "1", price: "", vat: 0 }])}>
                <PlusIcon data-icon="inline-start" />
                Add item
              </Button>
            </td>
            <td colSpan={2} className="px-2 py-1.5 text-right text-xs text-muted-foreground">
              Before VAT {kes(t.subtotal)} · VAT {kes(t.vat)}
            </td>
            <td className="px-2 py-1.5 text-right font-semibold tabular-nums">{kes(t.total)}</td>
            <td />
          </tr>
        </tfoot>
      </table>
      <datalist id={`${idPrefix}-items`}>
        {items.map((p) => (
          <option key={p.id} value={p.name} />
        ))}
      </datalist>
    </div>
  );
}
