"use client";

import { useActionState, useMemo, useState } from "react";
import { useFormStatus } from "react-dom";
import { createOrderAction, updateOrderAction, type OrderFormState } from "../actions";
import { formatVnd } from "@/lib/format";

export type CustomerOption = {
  id: string;
  code: string;
  orgName: string;
  territoryName: string | null;
  contactName: string | null;
  taxCode: string | null;
  phone: string | null;
  email: string | null;
  /** Địa chỉ đầy đủ: số nhà, phường, tỉnh. */
  address: string | null;
  /** Người nhận hàng mặc định trong hồ sơ khách — điền sẵn vào đơn. */
  receiverName: string | null;
  receiverPhone: string | null;
  receiverAddress: string | null;
};
export type ProductOption = {
  id: string;
  code: string;
  name: string;
  unit: string;
  volume: string | null;
  /** Giá đại lý (đã gồm VAT) trong danh mục. */
  unitPrice: number;
  /** Chiết khấu chuẩn (%) — chỉ để tham khảo khi báo giá. */
  discountPercent: number;
};

type Line = { key: number; productId: string; qtySold: number; qtyPromo: number; unitPrice: number };

/** Dữ liệu đơn đang sửa; bỏ trống nghĩa là đang lên đơn mới. */
export type ExistingOrder = {
  id: string;
  code: string;
  customerId: string;
  orderDate: string;
  dueDate: string | null;
  note: string | null;
  vatRequired: boolean;
  receiverName: string | null;
  receiverPhone: string | null;
  receiverAddress: string | null;
  carrierName: string | null;
  carrierPhone: string | null;
  carrierAddress: string | null;
  surchargeAmount: number;
  lines: { productId: string; qtySold: number; qtyPromo: number; unitPrice: number }[];
};

function SubmitButton({ disabled, label }: { disabled: boolean; label: string }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className="btn-primary" disabled={pending || disabled}>
      {pending ? "Đang lưu…" : label}
    </button>
  );
}

export function OrderForm({
  customers,
  products,
  today,
  order,
}: {
  customers: CustomerOption[];
  products: ProductOption[];
  today: string;
  order?: ExistingOrder;
}) {
  const isEditing = Boolean(order);
  const [state, formAction] = useActionState<OrderFormState, FormData>(
    isEditing ? updateOrderAction : createOrderAction,
    {},
  );
  const [customerId, setCustomerId] = useState(order?.customerId ?? "");
  const [vat, setVat] = useState(order?.vatRequired ?? false);
  const [surcharge, setSurcharge] = useState(order?.surchargeAmount ?? 0);
  const [lines, setLines] = useState<Line[]>(
    order && order.lines.length > 0
      ? order.lines.map((line, index) => ({ key: index + 1, ...line }))
      : [{ key: 1, productId: "", qtySold: 1, qtyPromo: 0, unitPrice: 0 }],
  );

  // Sau mỗi lần gửi React xoá trắng các ô nhập không kiểm soát; khi lỗi, máy chủ trả lại giá trị đã nhập để điền lại
  // (khách, VAT, phụ thu và các dòng hàng nằm trong state nên không bị mất).
  const v = (name: keyof NonNullable<OrderFormState["values"]>, fallback: string | null | undefined): string =>
    state.values?.[name] ?? fallback ?? "";

  const productMap = useMemo(() => new Map(products.map((p) => [p.id, p])), [products]);
  const customerMap = useMemo(() => new Map(customers.map((c) => [c.id, c])), [customers]);
  const customer = customerMap.get(customerId);

  const addLine = () =>
    setLines((current) => [
      ...current,
      { key: Math.max(0, ...current.map((l) => l.key)) + 1, productId: "", qtySold: 1, qtyPromo: 0, unitPrice: 0 },
    ]);

  const removeLine = (key: number) =>
    setLines((current) => (current.length === 1 ? current : current.filter((l) => l.key !== key)));

  const updateLine = (key: number, patch: Partial<Line>) =>
    setLines((current) => current.map((line) => (line.key === key ? { ...line, ...patch } : line)));

  /** Chọn sản phẩm thì lấy đơn giá từ danh mục, người dùng vẫn sửa được nếu có giá riêng. */
  const chooseProduct = (key: number, productId: string) => {
    const product = productMap.get(productId);
    updateLine(key, { productId, unitPrice: product ? product.unitPrice : 0 });
  };

  /** Chọn khách: điền sẵn người nhận hàng mặc định của khách vào các ô còn trống (không ghi đè những gì đã gõ). */
  const chooseCustomer = (id: string) => {
    setCustomerId(id);
    const chosen = customerMap.get(id);
    if (!chosen) return;
    const prefill: [string, string | null][] = [
      ["receiverName", chosen.receiverName],
      ["receiverPhone", chosen.receiverPhone],
      ["receiverAddress", chosen.receiverAddress],
    ];
    for (const [fieldId, value] of prefill) {
      const input = document.getElementById(fieldId) as HTMLInputElement | null;
      if (input && !input.value && value) input.value = value;
    }
  };

  const filledLines = lines.filter((line) => line.productId && (line.qtySold > 0 || line.qtyPromo > 0));
  const totalAmount = filledLines.reduce((sum, line) => sum + line.qtySold * line.unitPrice, 0);
  const promoValue = filledLines.reduce((sum, line) => sum + line.qtyPromo * line.unitPrice, 0);
  // Xuất hoá đơn VAT cần ít nhất mã số thuế và địa chỉ bên mua.
  const vatGaps = customer ? [!customer.taxCode && "mã số thuế", !customer.address && "địa chỉ"].filter(Boolean) : [];

  return (
    <form
      key={state.values ? JSON.stringify(state.values) : "moi"}
      action={formAction}
      className="flex flex-col gap-5"
    >
      {order && <input type="hidden" name="id" value={order.id} />}
      {/* Dữ liệu dòng hàng gửi kèm dạng JSON để giữ được cấu trúc lồng nhau */}
      {filledLines.map((line) => (
        <input
          key={line.key}
          type="hidden"
          name="line"
          value={JSON.stringify({
            productId: line.productId,
            qtySold: line.qtySold,
            qtyPromo: line.qtyPromo,
            unitPrice: line.unitPrice,
          })}
        />
      ))}

      <div className="card grid gap-4 p-4 lg:grid-cols-4">
        <div className="lg:col-span-2">
          <label htmlFor="customerId" className="label-caps mb-1.5 block">
            Khách hàng <span className="text-red-600">*</span>
          </label>
          <select
            id="customerId"
            name="customerId"
            required
            className="input"
            value={customerId}
            onChange={(event) => chooseCustomer(event.target.value)}
          >
            <option value="" disabled>
              — Chọn khách hàng —
            </option>
            {customers.map((c) => (
              <option key={c.id} value={c.id}>
                {c.orgName} · {c.code}
                {c.territoryName ? ` · ${c.territoryName}` : ""}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor="orderDate" className="label-caps mb-1.5 block">
            Ngày đặt hàng
          </label>
          <input
            id="orderDate"
            name="orderDate"
            type="date"
            required
            defaultValue={v("orderDate", order?.orderDate ?? today)}
            max={today}
            className="input"
          />
        </div>
        <div>
          <label htmlFor="dueDate" className="label-caps mb-1.5 block">
            Hạn thanh toán
          </label>
          <input id="dueDate" name="dueDate" type="date" defaultValue={v("dueDate", order?.dueDate)} className="input" />
          <p className="mt-1 text-[11px] text-ink-400">Bỏ trống nghĩa là thu ngay.</p>
        </div>

        {/* Thông tin khách hàng của đơn (lấy từ hồ sơ khách) — để soát trước khi gửi, nhất là khi cần xuất VAT */}
        {customer && (
          <dl className="grid gap-x-6 gap-y-1 rounded-lg bg-ink-50 px-3 py-2.5 text-sm lg:col-span-4 lg:grid-cols-3">
            <div className="flex gap-2">
              <dt className="text-ink-400">Mã KH:</dt>
              <dd className="font-semibold text-ink-700">{customer.code}</dd>
            </div>
            <div className="flex gap-2">
              <dt className="text-ink-400">Tên cơ sở:</dt>
              <dd className="font-semibold text-ink-700">{customer.orgName}</dd>
            </div>
            <div className="flex gap-2">
              <dt className="text-ink-400">Người đại diện:</dt>
              <dd className="text-ink-700">{customer.contactName ?? "—"}</dd>
            </div>
            <div className="flex gap-2">
              <dt className="text-ink-400">Mã số thuế:</dt>
              <dd className="tnum text-ink-700">{customer.taxCode ?? "—"}</dd>
            </div>
            <div className="flex gap-2">
              <dt className="text-ink-400">Điện thoại:</dt>
              <dd className="tnum text-ink-700">{customer.phone ?? "—"}</dd>
            </div>
            <div className="flex gap-2">
              <dt className="text-ink-400">Email:</dt>
              <dd className="text-ink-700">{customer.email ?? "—"}</dd>
            </div>
            <div className="flex gap-2 lg:col-span-3">
              <dt className="text-ink-400">Địa chỉ:</dt>
              <dd className="text-ink-700">{customer.address ?? "—"}</dd>
            </div>
          </dl>
        )}
      </div>

      {/* Dòng hàng */}
      <div className="card overflow-hidden">
        <div className="flex items-center justify-between border-b border-[var(--color-line)] px-4 py-3">
          <span className="text-sm font-bold text-ink-700">Chi tiết mặt hàng</span>
          <button type="button" onClick={addLine} className="btn-ghost text-xs">
            + Thêm dòng
          </button>
        </div>

        <div className="flex flex-col divide-y divide-[var(--color-line)]">
          {lines.map((line) => {
            const product = productMap.get(line.productId);
            const amount = line.qtySold * line.unitPrice;
            const offCatalog = !!product && line.unitPrice !== product.unitPrice;
            return (
              <div key={line.key} className="grid gap-3 p-4 lg:grid-cols-12 lg:items-end">
                <div className="lg:col-span-5">
                  <label className="label-caps mb-1.5 block">Sản phẩm</label>
                  <select value={line.productId} onChange={(event) => chooseProduct(line.key, event.target.value)} className="input">
                    <option value="">— Chọn sản phẩm —</option>
                    {products.map((p) => (
                      <option key={p.id} value={p.id}>
                        {p.code} · {p.name}
                      </option>
                    ))}
                  </select>
                  {product && (
                    <p className="mt-1 text-[11px] text-ink-400">
                      ĐVT {product.unit}
                      {product.volume ? ` · ${product.volume}` : ""} · giá đại lý (có VAT) {formatVnd(product.unitPrice)}
                      {product.discountPercent > 0 ? ` · CK chuẩn ${product.discountPercent}%` : ""}
                    </p>
                  )}
                </div>

                <div className="lg:col-span-1">
                  <label className="label-caps mb-1.5 block">SL bán</label>
                  <input
                    type="number"
                    min={0}
                    value={line.qtySold}
                    onChange={(event) => updateLine(line.key, { qtySold: Number(event.target.value) })}
                    className="input tnum"
                  />
                </div>

                <div className="lg:col-span-1">
                  <label className="label-caps mb-1.5 block">SL KM</label>
                  <input
                    type="number"
                    min={0}
                    value={line.qtyPromo}
                    onChange={(event) => updateLine(line.key, { qtyPromo: Number(event.target.value) })}
                    className="input tnum"
                  />
                </div>

                <div className="lg:col-span-2">
                  <label className="label-caps mb-1.5 block">Đơn giá</label>
                  <input
                    type="number"
                    min={0}
                    value={line.unitPrice}
                    onChange={(event) => updateLine(line.key, { unitPrice: Number(event.target.value) })}
                    className="input tnum"
                  />
                  {offCatalog && <p className="mt-1 text-[11px] font-semibold text-red-600">Khác giá đại lý trong danh mục — người duyệt sẽ thấy cảnh báo.</p>}
                </div>

                <div className="lg:col-span-2 lg:text-right">
                  <label className="label-caps mb-1.5 block lg:hidden">Thành tiền</label>
                  <div className="tnum py-2 text-sm font-semibold text-ink-700">{formatVnd(amount)}</div>
                </div>

                <div className="lg:col-span-1 lg:text-right">
                  <button
                    type="button"
                    onClick={() => removeLine(line.key)}
                    disabled={lines.length === 1}
                    className="btn-ghost w-full text-xs disabled:opacity-40 lg:w-auto"
                    aria-label="Xoá dòng"
                  >
                    Xoá
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* VAT & giao hàng */}
      <div className={`card p-4 ${vat ? "border-2 border-brand-500" : ""}`}>
        <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
          <span className="text-sm font-bold text-ink-700">VAT &amp; giao hàng</span>
          <label className={`flex items-center gap-2 rounded-md px-2 py-1 text-sm ${vat ? "bg-brand-500 font-bold text-white" : "text-ink-600"}`}>
            <input
              type="checkbox"
              name="vatRequired"
              checked={vat}
              onChange={(event) => setVat(event.target.checked)}
              className="h-4 w-4 accent-brand-500"
            />
            Đơn cần xuất VAT
          </label>
        </div>
        {vat && vatGaps.length > 0 && (
          <p role="alert" className="mb-3 rounded-lg bg-red-50 px-3 py-2 text-sm font-semibold text-red-700">
            Hồ sơ khách còn thiếu {vatGaps.join(", ")} — bổ sung ở Sửa hồ sơ khách trước khi xuất hoá đơn.
          </p>
        )}
        <div className="grid gap-3 lg:grid-cols-3">
          <div>
            <label htmlFor="receiverName" className="label-caps mb-1.5 block">
              Người nhận hàng
            </label>
            <input id="receiverName" name="receiverName" defaultValue={v("receiverName", order?.receiverName)} className="input" />
          </div>
          <div>
            <label htmlFor="receiverPhone" className="label-caps mb-1.5 block">
              Điện thoại người nhận
            </label>
            <input id="receiverPhone" name="receiverPhone" defaultValue={v("receiverPhone", order?.receiverPhone)} className="input" />
          </div>
          <div>
            <label htmlFor="receiverAddress" className="label-caps mb-1.5 block">
              Địa chỉ nhận hàng
            </label>
            <input id="receiverAddress" name="receiverAddress" defaultValue={v("receiverAddress", order?.receiverAddress)} className="input" />
          </div>
          <div>
            <label htmlFor="carrierName" className="label-caps mb-1.5 block">
              Tên nhà xe
            </label>
            <input id="carrierName" name="carrierName" defaultValue={v("carrierName", order?.carrierName)} className="input" />
          </div>
          <div>
            <label htmlFor="carrierPhone" className="label-caps mb-1.5 block">
              Điện thoại nhà xe
            </label>
            <input id="carrierPhone" name="carrierPhone" defaultValue={v("carrierPhone", order?.carrierPhone)} className="input" />
          </div>
          <div>
            <label htmlFor="carrierAddress" className="label-caps mb-1.5 block">
              Địa chỉ nhà xe
            </label>
            <input id="carrierAddress" name="carrierAddress" defaultValue={v("carrierAddress", order?.carrierAddress)} className="input" />
          </div>
          <div>
            <label htmlFor="surchargeAmount" className="label-caps mb-1.5 block">
              Phụ thu phí
            </label>
            <input
              id="surchargeAmount"
              name="surchargeAmount"
              type="number"
              min={0}
              value={surcharge}
              onChange={(event) => setSurcharge(Number(event.target.value))}
              className="input tnum"
            />
            <p className="mt-1 text-[11px] text-ink-400">Cộng ngoài tiền hàng, không tính vào doanh thu sản phẩm nhưng khách phải trả.</p>
          </div>
        </div>
      </div>

      {/* Tổng kết */}
      <div className="card flex flex-wrap items-end justify-between gap-4 p-4">
        <div className="min-w-56 flex-1">
          <label htmlFor="note" className="label-caps mb-1.5 block">
            Ghi chú thêm
          </label>
          <input id="note" name="note" defaultValue={v("note", order?.note)} className="input" placeholder="Ghi chú giao hàng, công nợ…" />
        </div>
        <div className="text-right">
          <div className="label-caps">Giá trị hàng khuyến mãi</div>
          <div className="tnum text-sm text-ink-500">{formatVnd(promoValue)}</div>
          <div className="label-caps mt-2">Tổng tiền hàng bán</div>
          <div className="tnum text-2xl font-bold text-ink-700">{formatVnd(totalAmount)}</div>
          {surcharge > 0 && (
            <>
              <div className="label-caps mt-2">Tổng phải thu (gồm phụ thu)</div>
              <div className="tnum text-base font-semibold text-ink-600">{formatVnd(totalAmount + surcharge)}</div>
            </>
          )}
        </div>
      </div>

      {state.error && (
        <p role="alert" className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
          {state.error}
        </p>
      )}

      <div className="flex flex-wrap items-center gap-3">
        <SubmitButton disabled={filledLines.length === 0} label={isEditing ? "Lưu thay đổi" : "Lưu đơn hàng"} />
        <a href={order ? `/don-hang/${order.id}` : "/don-hang"} className="btn-ghost">
          Huỷ
        </a>
        <span className="text-xs text-ink-400">Hàng khuyến mãi không tính vào doanh thu, nhưng vẫn được theo dõi riêng ở báo cáo.</span>
      </div>
    </form>
  );
}
