"use client";

import React, { useEffect, useState } from "react";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Loader2, Plus, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { toast } from "sonner";

export interface ItemRow {
  objid?: string | number;
  id?: string | number;
  item_number?: string;
  item_code?: string;
  item_name?: string;
  size?: string;
  spec?: string;
  standard?: string;
  unit?: string;
  unit_label?: string;
  selling_price?: number | string;
  standard_price?: number | string;
  [key: string]: any;
}

interface ItemSearchDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSelect: (items: ItemRow[]) => void;
  multiSelect?: boolean;
  title?: string;
  description?: string;
}

const PAGE_SIZE = 20;

const fmt = (val: string | number) => {
  const num = String(val).replace(/[^\d.-]/g, "");
  if (!num) return "0";
  const parts = num.split(".");
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  return parts.join(".");
};

export function ItemSearchDialog({
  open, onOpenChange, onSelect,
  multiSelect = true,
  title = "품목 검색",
  description = "추가할 품목을 검색하여 선택하세요.",
}: ItemSearchDialogProps) {
  const [keyword, setKeyword] = useState("");
  const [results, setResults] = useState<ItemRow[]>([]);
  const [loading, setLoading] = useState(false);
  const [selectedMap, setSelectedMap] = useState<Map<string, ItemRow>>(new Map());
  const [page, setPage] = useState(1);
  const [total, setTotal] = useState(0);
  const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));

  const [unitMap, setUnitMap] = useState<Record<string, string>>({});
  useEffect(() => {
    (async () => {
      try {
        const res = await apiClient.get(`/table-categories/item_info/unit/values`);
        if (res.data?.success && res.data.data?.length > 0) {
          const map: Record<string, string> = {};
          const flatten = (arr: any[]) => {
            for (const v of arr) {
              map[v.valueCode] = v.valueLabel;
              if (v.children?.length) flatten(v.children);
            }
          };
          flatten(res.data.data);
          setUnitMap(map);
        }
      } catch { /* skip */ }
    })();
  }, []);
  const resolveUnit = (code: string) => unitMap[code] || code || "EA";

  useEffect(() => {
    if (open) {
      setKeyword("");
      setSelectedMap(new Map());
      setPage(1);
      void search(1, "");
    }
  }, [open]);

  const search = async (p: number, kw?: string) => {
    const k = kw ?? keyword;
    setLoading(true);
    try {
      const filters: any[] = [];
      if (k) filters.push({ columnName: "item_name", operator: "contains", value: k });
      const res = await apiClient.post("/table-management/tables/item_info/data", {
        page: p, size: PAGE_SIZE,
        dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
        autoFilter: true,
      });
      const resData = res.data?.data;
      setResults(resData?.data || resData?.rows || []);
      setTotal(resData?.total || resData?.totalCount || 0);
    } catch {
      toast.error("품목 조회 실패");
    } finally {
      setLoading(false);
    }
  };

  const rowKey = (row: ItemRow) =>
    String(row.item_number || row.objid || row.id || "");

  const enrich = (row: ItemRow): ItemRow => ({
    ...row,
    unit_label: resolveUnit(row.unit ?? ""),
  });

  const toggleSelect = (row: ItemRow) => {
    const key = rowKey(row);
    if (!multiSelect) {
      onSelect([enrich(row)]);
      onOpenChange(false);
      return;
    }
    setSelectedMap((prev) => {
      const next = new Map(prev);
      if (next.has(key)) next.delete(key); else next.set(key, row);
      return next;
    });
  };

  const handleApply = () => {
    const arr = Array.from(selectedMap.values()).map(enrich);
    if (arr.length === 0) {
      toast.info("품목을 선택하세요.");
      return;
    }
    onSelect(arr);
    onOpenChange(false);
  };

  const goPage = (p: number) => {
    if (p < 1 || p > totalPages) return;
    setPage(p);
    void search(p);
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="flex max-h-[80vh] max-w-3xl flex-col overflow-hidden">
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>
        <div className="flex gap-2">
          <Input
            placeholder="품명/품목코드 검색"
            value={keyword}
            onChange={(e) => setKeyword(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") { setPage(1); void search(1); } }}
            className="text-sm"
          />
          <Button
            onClick={() => { setPage(1); void search(1); }}
            disabled={loading}
            className="shrink-0 gap-1"
          >
            {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : "검색"}
          </Button>
        </div>
        <div className="flex-1 overflow-auto rounded border">
          <table className="w-full text-xs">
            <thead className="sticky top-0 z-10 bg-gray-50">
              <tr>
                {multiSelect && <th className="w-10 px-2 py-2 text-center">선택</th>}
                <th className="px-2 py-2 text-left">품목코드</th>
                <th className="px-2 py-2 text-left">품명</th>
                <th className="px-2 py-2 text-left">규격</th>
                <th className="w-16 px-2 py-2 text-center">단위</th>
                <th className="w-24 px-2 py-2 text-right">단가</th>
              </tr>
            </thead>
            <tbody>
              {results.length === 0 ? (
                <tr>
                  <td colSpan={multiSelect ? 6 : 5} className="px-4 py-8 text-center text-gray-400">
                    {loading ? "검색 중..." : "검색 결과가 없습니다."}
                  </td>
                </tr>
              ) : results.map((row, i) => {
                const key = rowKey(row) || String(i);
                const checked = selectedMap.has(key);
                return (
                  <tr
                    key={key}
                    className={cn(
                      "cursor-pointer border-t",
                      checked ? "bg-blue-50" : "hover:bg-gray-50",
                    )}
                    onClick={() => toggleSelect(row)}
                  >
                    {multiSelect && (
                      <td className="px-2 py-1.5 text-center">
                        <input type="checkbox" checked={checked} readOnly className="accent-blue-500" />
                      </td>
                    )}
                    <td className="px-2 py-1.5">{row.item_number || row.item_code || "-"}</td>
                    <td className="px-2 py-1.5">{row.item_name || "-"}</td>
                    <td className="px-2 py-1.5">{row.size || row.spec || row.standard || "-"}</td>
                    <td className="px-2 py-1.5 text-center">{resolveUnit(row.unit ?? "")}</td>
                    <td className="px-2 py-1.5 text-right">
                      {fmt(String(row.selling_price ?? row.standard_price ?? 0))}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
        <div className="shrink-0 flex items-center justify-between border-t px-2 py-2 text-xs text-muted-foreground">
          <div className="flex items-center gap-3">
            <div className="flex items-center gap-1">
              <span>전체</span>
              <span className="font-medium text-foreground">{total.toLocaleString()}</span>
              <span>건{multiSelect ? ` · 선택 ${selectedMap.size}건` : ""}</span>
            </div>
          </div>
          <div className="flex items-center gap-0.5">
            <button
              onClick={() => goPage(1)}
              disabled={page <= 1}
              className="h-7 w-7 flex items-center justify-center rounded hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed"
            >
              <ChevronsLeft className="h-3.5 w-3.5" />
            </button>
            <button
              onClick={() => goPage(page - 1)}
              disabled={page <= 1}
              className="h-7 w-7 flex items-center justify-center rounded hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed"
            >
              <ChevronLeft className="h-3.5 w-3.5" />
            </button>
            {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
              const start = Math.max(1, Math.min(page - 2, totalPages - 4));
              const p = start + i;
              if (p > totalPages) return null;
              return (
                <button
                  key={p}
                  onClick={() => goPage(p)}
                  className={cn(
                    "h-7 w-7 flex items-center justify-center rounded text-xs",
                    p === page ? "bg-primary text-primary-foreground font-medium" : "hover:bg-muted",
                  )}
                >
                  {p}
                </button>
              );
            })}
            <button
              onClick={() => goPage(page + 1)}
              disabled={page >= totalPages}
              className="h-7 w-7 flex items-center justify-center rounded hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed"
            >
              <ChevronRight className="h-3.5 w-3.5" />
            </button>
            <button
              onClick={() => goPage(totalPages)}
              disabled={page >= totalPages}
              className="h-7 w-7 flex items-center justify-center rounded hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed"
            >
              <ChevronsRight className="h-3.5 w-3.5" />
            </button>
          </div>
        </div>
        <DialogFooter className="shrink-0 flex items-center justify-end gap-2">
          <Button variant="outline" onClick={() => onOpenChange(false)}>취소</Button>
          {multiSelect && (
            <Button onClick={handleApply} disabled={selectedMap.size === 0} className="gap-1">
              <Plus className="h-4 w-4" /> 선택 품목 추가
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

export { fmt as fmtItemPrice };
