"use client";

import { useState } from "react";
import type { OrderItemData } from "@/lib/types";

// 6 color presets for customer grouping
const CUSTOMER_COLORS = [
  { border: "border-l-blue-500", bg: "bg-blue-50", text: "text-blue-800" },
  {
    border: "border-l-emerald-500",
    bg: "bg-emerald-50",
    text: "text-emerald-800",
  },
  {
    border: "border-l-violet-500",
    bg: "bg-violet-50",
    text: "text-violet-800",
  },
  {
    border: "border-l-orange-500",
    bg: "bg-orange-50",
    text: "text-orange-800",
  },
  { border: "border-l-teal-500", bg: "bg-teal-50", text: "text-teal-800" },
  { border: "border-l-pink-500", bg: "bg-pink-50", text: "text-pink-800" },
];

function getColor(index: number) {
  return CUSTOMER_COLORS[index % CUSTOMER_COLORS.length];
}

// Build a color map from customer list
function buildColorMap(customers: { id: string; name: string }[]) {
  const map: Record<string, number> = {};
  customers.forEach((c, i) => {
    map[c.id] = i;
  });
  return map;
}

// Group items by customerId
function groupItems(items: OrderItemData[]) {
  const groups: Record<string, OrderItemData[]> = {};
  const ungrouped: OrderItemData[] = [];

  for (const item of items) {
    if (item.customerId) {
      if (!groups[item.customerId]) groups[item.customerId] = [];
      groups[item.customerId].push(item);
    } else {
      ungrouped.push(item);
    }
  }

  return { groups, ungrouped };
}

// Inline edit form for an item
function ItemEditForm({
  item,
  customers,
  onSave,
  onCancel,
}: {
  item: OrderItemData;
  customers: { id: string; name: string }[];
  onSave: (item: OrderItemData) => void;
  onCancel: () => void;
}) {
  const [form, setForm] = useState({ ...item });

  function update(field: string, value: string | number) {
    const next = { ...form, [field]: value };
    // Recompute prices
    next.netPrice =
      (next.initPrice + next.initPrice * next.taxRatio) * next.quantity;
    next.myNetPrice =
      (next.myPrice + next.myPrice * next.taxRatio) * next.quantity;
    next.finalPrice = next.netPrice;
    setForm(next);
  }

  const inputClass =
    "border-2 border-border rounded-lg px-2 py-1.5 text-sm bg-bg text-fg focus:outline-none focus:border-accent w-full";
  const labelClass = "text-xs text-muted font-medium mb-0.5 block";

  return (
    <div className="bg-surface border-2 border-border rounded-xl p-4 mt-2">
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        <div>
          <label className={labelClass}>Customer</label>
          <select
            value={form.customerId ?? ""}
            onChange={(e) => update("customerId", e.target.value)}
            className={inputClass}
          >
            <option value="">None</option>
            {customers.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label className={labelClass}>Item Name</label>
          <input
            type="text"
            value={form.itemName}
            onChange={(e) => update("itemName", e.target.value)}
            className={inputClass}
          />
        </div>
        <div>
          <label className={labelClass}>Init Price</label>
          <input
            type="number"
            step="0.01"
            min="0"
            value={form.initPrice}
            onChange={(e) =>
              update("initPrice", parseFloat(e.target.value) || 0)
            }
            className={inputClass}
          />
        </div>
        <div>
          <label className={labelClass}>My Price</label>
          <input
            type="number"
            step="0.01"
            min="0"
            value={form.myPrice}
            onChange={(e) => update("myPrice", parseFloat(e.target.value) || 0)}
            className={inputClass}
          />
        </div>
        <div>
          <label className={labelClass}>Tax Ratio</label>
          <input
            type="number"
            step="0.01"
            min="0"
            value={form.taxRatio}
            onChange={(e) =>
              update("taxRatio", parseFloat(e.target.value) || 0)
            }
            className={inputClass}
          />
        </div>
        <div>
          <label className={labelClass}>Quantity</label>
          <input
            type="number"
            min="1"
            value={form.quantity}
            onChange={(e) => update("quantity", parseInt(e.target.value) || 1)}
            className={inputClass}
          />
        </div>
      </div>
      <div className="flex gap-2 mt-3">
        <button
          type="button"
          onClick={() => onSave(form)}
          className="bg-accent text-accent-on px-4 py-1.5 rounded-lg text-sm font-bold hover:bg-accent-hover cursor-pointer"
        >
          Save
        </button>
        <button
          type="button"
          onClick={onCancel}
          className="bg-surface border-2 border-border px-4 py-1.5 rounded-lg text-sm font-medium text-muted hover:text-fg cursor-pointer"
        >
          Cancel
        </button>
      </div>
    </div>
  );
}

// Add item form
function AddItemForm({
  customers,
  onAdd,
  disabled,
}: {
  customers: { id: string; name: string }[];
  onAdd: (item: OrderItemData) => void;
  disabled: boolean;
}) {
  const [form, setForm] = useState({
    customerId: customers[0]?.id ?? "",
    itemName: "",
    initPrice: 0,
    myPrice: 0,
    taxRatio: 0.16,
    quantity: 1,
  });

  function update(field: string, value: string | number) {
    setForm((prev) => ({ ...prev, [field]: value }));
  }

  function handleAdd() {
    if (!form.itemName.trim()) return;
    const netPrice =
      (form.initPrice + form.initPrice * form.taxRatio) * form.quantity;
    const myNetPrice =
      (form.myPrice + form.myPrice * form.taxRatio) * form.quantity;
    onAdd({
      id: crypto.randomUUID(),
      orderId: "",
      customerId: form.customerId || null,
      customerName:
        customers.find((c) => c.id === form.customerId)?.name ?? null,
      itemName: form.itemName,
      initPrice: form.initPrice,
      myPrice: form.myPrice,
      taxRatio: form.taxRatio,
      quantity: form.quantity,
      netPrice,
      myNetPrice,
      finalPrice: netPrice,
    });
    setForm({
      customerId: customers[0]?.id ?? "",
      itemName: "",
      initPrice: 0,
      myPrice: 0,
      taxRatio: 0.16,
      quantity: 1,
    });
  }

  const inputClass =
    "border-2 border-border rounded-lg px-2 py-1.5 text-sm bg-bg text-fg focus:outline-none focus:border-accent w-full";
  const labelClass = "text-xs text-muted font-medium mb-0.5 block";

  return (
    <div className="bg-surface border-2 border-border rounded-xl p-4">
      <h4 className="text-sm font-bold text-fg mb-3">Add New Item</h4>
      <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3">
        <div>
          <label className={labelClass}>Customer</label>
          <select
            value={form.customerId}
            onChange={(e) => update("customerId", e.target.value)}
            className={inputClass}
            disabled={disabled}
          >
            <option value="">None</option>
            {customers.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label className={labelClass}>Item Name</label>
          <input
            type="text"
            value={form.itemName}
            onChange={(e) => update("itemName", e.target.value)}
            placeholder="Product name"
            className={inputClass}
            disabled={disabled}
          />
        </div>
        <div>
          <label className={labelClass}>Init Price</label>
          <input
            type="number"
            step="0.01"
            min="0"
            value={form.initPrice}
            onChange={(e) =>
              update("initPrice", parseFloat(e.target.value) || 0)
            }
            className={inputClass}
            disabled={disabled}
          />
        </div>
        <div>
          <label className={labelClass}>My Price</label>
          <input
            type="number"
            step="0.01"
            min="0"
            value={form.myPrice}
            onChange={(e) => update("myPrice", parseFloat(e.target.value) || 0)}
            className={inputClass}
            disabled={disabled}
          />
        </div>
        <div>
          <label className={labelClass}>Tax / Qty</label>
          <div className="flex gap-1">
            <input
              type="number"
              step="0.01"
              min="0"
              value={form.taxRatio}
              onChange={(e) =>
                update("taxRatio", parseFloat(e.target.value) || 0)
              }
              className={inputClass}
              disabled={disabled}
            />
            <input
              type="number"
              min="1"
              value={form.quantity}
              onChange={(e) =>
                update("quantity", parseInt(e.target.value) || 1)
              }
              className={inputClass}
              disabled={disabled}
            />
          </div>
        </div>
        <div className="flex items-end">
          <button
            type="button"
            onClick={handleAdd}
            disabled={disabled || !form.itemName.trim()}
            className="bg-accent text-accent-on px-4 py-1.5 rounded-lg text-sm font-bold hover:bg-accent-hover disabled:opacity-50 cursor-pointer w-full"
          >
            + Add
          </button>
        </div>
      </div>
    </div>
  );
}

// Main ItemTable component
export function ItemTable({
  items,
  customers,
  onItemsChange,
  disabled = false,
}: {
  items: OrderItemData[];
  customers: { id: string; name: string }[];
  onItemsChange: (items: OrderItemData[]) => void;
  disabled?: boolean;
}) {
  const [editingId, setEditingId] = useState<string | null>(null);
  const colorMap = buildColorMap(customers);
  const { groups, ungrouped } = groupItems(items);

  function handleAdd(newItem: OrderItemData) {
    onItemsChange([...items, newItem]);
  }

  function handleRemove(id: string) {
    onItemsChange(items.filter((i) => i.id !== id));
    if (editingId === id) setEditingId(null);
  }

  function handleEditSave(updated: OrderItemData) {
    onItemsChange(items.map((i) => (i.id === updated.id ? updated : i)));
    setEditingId(null);
  }

  // Get customer name by id
  function getCustomerName(id: string) {
    return customers.find((c) => c.id === id)?.name ?? "Unknown";
  }

  // Render a single item row (desktop table row)
  function TableRow({
    item,
    colorIndex,
  }: {
    item: OrderItemData;
    colorIndex: number | null;
  }) {
    const color = colorIndex !== null ? getColor(colorIndex) : null;
    const isEditing = editingId === item.id;

    return (
      <>
        <tr
          className={`border-b border-border/50 hover:bg-surface/30 transition-colors ${color ? `border-l-4 ${color.border} ${color.bg}` : ""}`}
        >
          <td className="px-3 py-2 text-sm font-medium text-fg">
            {item.itemName || "—"}
          </td>
          <td className="px-3 py-2 text-sm font-mono text-right">
            ${item.initPrice.toFixed(2)}
          </td>
          <td className="px-3 py-2 text-sm font-mono text-right">
            ${item.myPrice.toFixed(2)}
          </td>
          <td className="px-3 py-2 text-sm font-mono text-center">
            {item.quantity}
          </td>
          <td className="px-3 py-2 text-sm font-mono text-right font-medium">
            ${item.myNetPrice.toFixed(2)}
          </td>
          <td className="px-3 py-2 text-sm font-mono text-right font-bold">
            ${item.finalPrice.toFixed(2)}
          </td>
          <td className="px-3 py-2 text-right">
            {!disabled && (
              <div className="flex gap-1 justify-end">
                <button
                  type="button"
                  onClick={() => setEditingId(isEditing ? null : item.id)}
                  className="text-xs text-accent hover:text-accent-hover font-medium px-2 py-1 rounded cursor-pointer"
                >
                  {isEditing ? "Cancel" : "Edit"}
                </button>
                <button
                  type="button"
                  onClick={() => handleRemove(item.id)}
                  className="text-xs text-danger hover:text-red-700 font-medium px-2 py-1 rounded cursor-pointer"
                >
                  Remove
                </button>
              </div>
            )}
          </td>
        </tr>
        {isEditing && (
          <tr>
            <td colSpan={7} className="px-3 py-0">
              <ItemEditForm
                item={item}
                customers={customers}
                onSave={handleEditSave}
                onCancel={() => setEditingId(null)}
              />
            </td>
          </tr>
        )}
      </>
    );
  }

  // Render a single item card (mobile)
  function MobileCard({
    item,
    colorIndex,
  }: {
    item: OrderItemData;
    colorIndex: number | null;
  }) {
    const color = colorIndex !== null ? getColor(colorIndex) : null;
    const isEditing = editingId === item.id;

    return (
      <div
        className={`border-2 border-border rounded-xl overflow-hidden ${color ? `border-l-4 ${color.border}` : ""}`}
      >
        <div className={`p-3 ${color?.bg ?? "bg-white"}`}>
          <div className="flex items-start justify-between gap-2">
            <div className="flex-1 min-w-0">
              <p className="text-sm font-bold text-fg truncate">
                {item.itemName || "—"}
              </p>
              {colorIndex !== null && (
                <p
                  className={`text-xs font-medium ${color?.text ?? "text-muted"}`}
                >
                  {getCustomerName(item.customerId!)}
                </p>
              )}
            </div>
            <p className="text-sm font-bold font-mono text-fg whitespace-nowrap">
              ${item.finalPrice.toFixed(2)}
            </p>
          </div>
          <div className="grid grid-cols-3 gap-2 mt-2 text-xs">
            <div>
              <span className="text-muted">Init: </span>
              <span className="font-mono">${item.initPrice.toFixed(2)}</span>
            </div>
            <div>
              <span className="text-muted">My: </span>
              <span className="font-mono">${item.myPrice.toFixed(2)}</span>
            </div>
            <div>
              <span className="text-muted">Qty: </span>
              <span className="font-mono">{item.quantity}</span>
            </div>
          </div>
          {!disabled && (
            <div className="flex gap-2 mt-2">
              <button
                type="button"
                onClick={() => setEditingId(isEditing ? null : item.id)}
                className="text-xs text-accent hover:text-accent-hover font-medium cursor-pointer"
              >
                {isEditing ? "Cancel" : "Edit"}
              </button>
              <button
                type="button"
                onClick={() => handleRemove(item.id)}
                className="text-xs text-danger hover:text-red-700 font-medium cursor-pointer"
              >
                Remove
              </button>
            </div>
          )}
        </div>
        {isEditing && (
          <div className="p-3 border-t border-border">
            <ItemEditForm
              item={item}
              customers={customers}
              onSave={handleEditSave}
              onCancel={() => setEditingId(null)}
            />
          </div>
        )}
      </div>
    );
  }

  // Render items for a customer group
  function CustomerGroup({
    customerId,
    groupItems: gi,
  }: {
    customerId: string;
    groupItems: OrderItemData[];
  }) {
    const colorIndex = colorMap[customerId] ?? 0;
    const color = getColor(colorIndex);
    const name = getCustomerName(customerId);
    const totalQty = gi.reduce((s, i) => s + i.quantity, 0);
    const totalNet = gi.reduce((s, i) => s + i.myNetPrice, 0);
    const totalFinal = gi.reduce((s, i) => s + i.finalPrice, 0);

    return (
      <div className="mb-4">
        <div
          className={`flex flex-wrap items-center gap-x-3 gap-y-1 px-3 py-1.5 rounded-t-lg ${color.bg} border-l-4 ${color.border}`}
        >
          <span className={`text-sm font-bold ${color.text}`}>{name}</span>
          <span className="text-xs text-muted">
            {totalQty} unit{totalQty !== 1 ? "s" : ""} ({gi.length} line{gi.length !== 1 ? "s" : ""})
          </span>
          <span className="text-xs font-mono text-muted">
            Net: <span className="font-medium text-fg">${totalNet.toFixed(2)}</span>
          </span>
          <span className="text-xs font-mono text-muted">
            Final: <span className="font-bold text-fg">${totalFinal.toFixed(2)}</span>
          </span>
        </div>
        {/* Desktop table */}
        <div className="hidden sm:block border-x border-b border-border rounded-b-lg overflow-hidden">
          <table className="w-full">
            <thead>
              <tr className="bg-surface/50">
                <th className="text-left px-3 py-1.5 text-xs font-medium text-muted">
                  Item
                </th>
                <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                  Init Price
                </th>
                <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                  My Price
                </th>
                <th className="text-center px-3 py-1.5 text-xs font-medium text-muted">
                  Qty
                </th>
                <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                  Net
                </th>
                <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                  Final
                </th>
                <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                  Actions
                </th>
              </tr>
            </thead>
            <tbody>
              {gi.map((item) => (
                <TableRow key={item.id} item={item} colorIndex={colorIndex} />
              ))}
            </tbody>
          </table>
        </div>
        {/* Mobile cards */}
        <div className="sm:hidden flex flex-col gap-2 mt-1">
          {gi.map((item) => (
            <MobileCard key={item.id} item={item} colorIndex={colorIndex} />
          ))}
        </div>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      {/* Add item form */}
      {!disabled && (
        <AddItemForm
          customers={customers}
          onAdd={handleAdd}
          disabled={disabled}
        />
      )}

      {/* Items grouped by customer */}
      {items.length === 0 ? (
        <div className="text-center py-8 text-muted text-sm border-2 border-dashed border-border rounded-xl">
          No items yet. Add one above.
        </div>
      ) : (
        <>
          {/* Customer groups */}
          {Object.entries(groups).map(([customerId, gi]) => (
            <CustomerGroup
              key={customerId}
              customerId={customerId}
              groupItems={gi}
            />
          ))}

          {/* Ungrouped items */}
          {ungrouped.length > 0 && (() => {
            const uQty = ungrouped.reduce((s, i) => s + i.quantity, 0);
            const uNet = ungrouped.reduce((s, i) => s + i.netPrice, 0);
            const uFinal = ungrouped.reduce((s, i) => s + i.finalPrice, 0);
            return (
            <div className="mb-4">
              <div className="flex flex-wrap items-center gap-x-3 gap-y-1 px-3 py-1.5 rounded-t-lg bg-gray-50 border-l-4 border-l-gray-400">
                <span className="text-sm font-bold text-gray-700">
                  Unassigned
                </span>
                <span className="text-xs text-muted">
                  {uQty} unit{uQty !== 1 ? "s" : ""} ({ungrouped.length} line{ungrouped.length !== 1 ? "s" : ""})
                </span>
                <span className="text-xs font-mono text-muted">
                  Net: <span className="font-medium text-fg">${uNet.toFixed(2)}</span>
                </span>
                <span className="text-xs font-mono text-muted">
                  Final: <span className="font-bold text-fg">${uFinal.toFixed(2)}</span>
                </span>
              </div>
              <div className="hidden sm:block border-x border-b border-border rounded-b-lg overflow-hidden">
                <table className="w-full">
                  <thead>
                    <tr className="bg-surface/50">
                      <th className="text-left px-3 py-1.5 text-xs font-medium text-muted">
                        Item
                      </th>
                      <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                        Init Price
                      </th>
                      <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                        My Price
                      </th>
                      <th className="text-center px-3 py-1.5 text-xs font-medium text-muted">
                        Qty
                      </th>
                      <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                        Net
                      </th>
                      <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                        Final
                      </th>
                      <th className="text-right px-3 py-1.5 text-xs font-medium text-muted">
                        Actions
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    {ungrouped.map((item) => (
                      <TableRow key={item.id} item={item} colorIndex={null} />
                    ))}
                  </tbody>
                </table>
              </div>
              <div className="sm:hidden flex flex-col gap-2 mt-1">
                {ungrouped.map((item) => (
                  <MobileCard key={item.id} item={item} colorIndex={null} />
                ))}
              </div>
            </div>
          ); })()}
        </>
      )}
    </div>
  );
}
