"use client";

/**
 * 입출고관리 — 하드코딩 페이지
 *
 * inventory_history 테이블 기반 입고+출고 통합 조회
 * 그룹핑, 검색, 엑셀 다운로드 지원
 */

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  Download, Loader2, Inbox, ChevronDown, ChevronRight,
  ArrowDownToLine, ArrowUpFromLine, Package,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { useAuth } from "@/hooks/useAuth";
import { toast } from "sonner";
import { exportToExcel } from "@/lib/utils/excelExport";
import { DynamicSearchFilter, FilterValue } from "@/components/common/DynamicSearchFilter";
import { useCategoryLabelMap, makeParseRemark } from "@/lib/categoryLabel";

const HISTORY_TABLE = "inventory_history";

const fmtNum = (v: any) => {
  const n = Number(v);
  return isNaN(n) ? "0" : n.toLocaleString();
};

const fmtDate = (v: any) => {
  if (!v) return "-";
  const s = String(v);
  const m = s.match(/(\d{4})-(\d{2})-(\d{2})/);
  return m ? `${m[1]}-${m[2]}-${m[3]}` : s.substring(0, 10);
};

/** remark가 JSON이면 사람이 읽을 수 있는 텍스트로 변환 */
const parseRemark = (remark: string | null | undefined): string => {
  if (!remark) return "";
  const trimmed = remark.trim();
  if (!trimmed.startsWith("{")) return trimmed;
  try {
    const d = JSON.parse(trimmed);
    switch (d.type) {
      case "move":
        return `창고이동 (${d.from_warehouse} → ${d.to_warehouse})`;
      case "adjust":
        return `재고조정 (${d.reason || "사유 없음"}, ${d.system_qty}→${d.actual_qty}, 차이:${d.diff >= 0 ? "+" : ""}${d.diff})`;
      case "confirm":
        return `재고확인 (${d.reason || "이상없음"})`;
      case "process_inbound":
        return "공정입고";
      default:
        return d.reason || d.memo || trimmed;
    }
  } catch {
    return trimmed;
  }
};

export default function InboundOutboundPage() {
  const { user } = useAuth();

  // remark의 value_code → value_label 변환용 카테고리 맵 (상위 parseRemark 를 shadow)
  const codeLabelMap = useCategoryLabelMap([
    { table: "inbound_mng", column: "inbound_type" },
    { table: "outbound_mng", column: "outbound_type" },
  ]);
  const parseRemark = useMemo(() => makeParseRemark(codeLabelMap), [codeLabelMap]);

  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [searchFilters, setSearchFilters] = useState<FilterValue[]>([]);
  const [typeFilter, setTypeFilter] = useState("all");
  const [categoryFilter, setCategoryFilter] = useState("all");
  const [groupBy, setGroupBy] = useState("none");
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());
  const [checkedIds, setCheckedIds] = useState<Set<string>>(new Set());

  // 품목명/단위 캐시
  const [itemMap, setItemMap] = useState<Record<string, { item_name: string; unit: string }>>({});
  const [warehouseMap, setWarehouseMap] = useState<Record<string, string>>({});
  const [userMap, setUserMap] = useState<Record<string, string>>({});

  // ════════ 데이터 로드 ════════

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const filters: any[] = [];
      if (typeFilter !== "all") filters.push({ columnName: "transaction_type", operator: "equals", value: typeFilter });

      for (const f of searchFilters) {
        if (f.value) filters.push({ columnName: f.columnName, operator: f.operator, value: f.value });
      }

      const res = await apiClient.post(`/table-management/tables/${HISTORY_TABLE}/data`, {
        page: 1, size: 1000,
        dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
        autoFilter: true,
        sort: { columnName: "transaction_date", order: "desc" },
      });
      const rows = res.data?.data?.data || res.data?.data?.rows || [];
      setData(rows);

      // 품목 정보 조회
      const itemCodes = [...new Set(rows.map((r: any) => r.item_code).filter(Boolean))];
      if (itemCodes.length > 0) {
        try {
          // 재고단위 카테고리 코드→라벨 매핑 로드
          let unitLabelMap: Record<string, string> = {};
          try {
            const catRes = await apiClient.get("/table-categories/item_info/inventory_unit/values");
            if (catRes.data?.success && catRes.data.data?.length > 0) {
              const flatten = (vals: any[]) => {
                for (const v of vals) {
                  unitLabelMap[v.valueCode] = v.valueLabel;
                  if (v.children?.length) flatten(v.children);
                }
              };
              flatten(catRes.data.data);
            }
          } catch { /* skip */ }

          const itemRes = await apiClient.post(`/table-management/tables/item_info/data`, {
            page: 1, size: itemCodes.length + 10,
            dataFilter: { enabled: true, filters: [{ columnName: "item_number", operator: "in", value: itemCodes }] },
            autoFilter: true,
          });
          const items = itemRes.data?.data?.data || itemRes.data?.data?.rows || [];
          const map: Record<string, { item_name: string; unit: string }> = {};
          for (const i of items) {
            const rawUnit = i.inventory_unit || "";
            if (!map[i.item_number]) map[i.item_number] = { item_name: i.item_name || "", unit: unitLabelMap[rawUnit] || rawUnit };
          }
          setItemMap(map);
        } catch { /* skip */ }
      }

      // 창고 정보 조회
      try {
        const whRes = await apiClient.post(`/table-management/tables/warehouse_info/data`, {
          page: 1, size: 100, autoFilter: true,
        });
        const whs = whRes.data?.data?.data || whRes.data?.data?.rows || [];
        const whMap: Record<string, string> = {};
        for (const w of whs) whMap[w.warehouse_code] = w.warehouse_name || w.warehouse_code;
        setWarehouseMap(whMap);
      } catch { /* skip */ }

      // 사용자 정보 조회 (writer → user_name 변환)
      const writerIds = [...new Set(rows.map((r: any) => r.writer).filter(Boolean))];
      if (writerIds.length > 0) {
        try {
          const userRes = await apiClient.post(`/table-management/tables/user_info/data`, {
            page: 1, size: 0, autoFilter: true,
          });
          const users = userRes.data?.data?.data || userRes.data?.data?.rows || [];
          const uMap: Record<string, string> = {};
          for (const u of users) uMap[u.user_id] = u.user_name || u.user_id;
          setUserMap(uMap);
        } catch { /* skip */ }
      }
    } catch {
      toast.error("입출고 내역 조회 실패");
    } finally {
      setLoading(false);
    }
  }, [searchFilters, typeFilter]);

  useEffect(() => { fetchData(); }, [fetchData]);

  // ════════ 카테고리 목록 (remark에서 추출) ════════

  const categoryOptions = useMemo(() => {
    const set = new Set<string>();
    data.forEach((r) => { if (r.remark) set.add(parseRemark(r.remark)); });
    return Array.from(set).sort();
  }, [data]);

  // ════════ 그룹핑 ════════

  // 카테고리 필터 (클라이언트)
  const filteredData = useMemo(() => {
    if (categoryFilter === "all") return data;
    return data.filter((r) => parseRemark(r.remark) === categoryFilter);
  }, [data, categoryFilter]);

  const groupedData = useMemo(() => {
    if (groupBy === "none") return filteredData;
    const groups = new Map<string, any[]>();
    for (const row of filteredData) {
      let key: string;
      switch (groupBy) {
        case "transaction_type": key = row.transaction_type || "미지정"; break;
        case "remark": key = parseRemark(row.remark) || "미지정"; break;
        case "warehouse_code": key = warehouseMap[row.warehouse_code] || row.warehouse_code || "미지정"; break;
        case "item_code": key = `${row.item_code} ${itemMap[row.item_code]?.item_name || ""}`.trim() || "미지정"; break;
        default: key = row[groupBy] || "미지정";
      }
      if (!groups.has(key)) groups.set(key, []);
      groups.get(key)!.push(row);
    }
    const result: any[] = [];
    groups.forEach((items, gk) => {
      const totalQty = items.reduce((s, r) => s + (Number(r.quantity) || 0), 0);
      result.push({ _group: true, _key: gk, _count: items.length, _totalQty: totalQty });
      result.push(...items);
    });
    if (expandedGroups.size === 0) setExpandedGroups(new Set(Array.from(groups.keys())));
    return result;
  }, [data, groupBy, itemMap, warehouseMap]);

  const toggleGroup = (key: string) => {
    setExpandedGroups((prev) => {
      const next = new Set(prev);
      if (next.has(key)) next.delete(key); else next.add(key);
      return next;
    });
  };

  // ════════ 체크박스 ════════

  const allIds = data.map((r) => r.id);
  const allChecked = allIds.length > 0 && allIds.every((id) => checkedIds.has(id));
  const toggleAll = (checked: boolean) => setCheckedIds(checked ? new Set(allIds) : new Set());
  const toggleOne = (id: string) => {
    setCheckedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  // ════════ 엑셀 ════════

  const handleExcel = async () => {
    if (data.length === 0) { toast.error("다운로드할 데이터가 없습니다."); return; }
    const rows = data.map((r, i) => ({
      No: i + 1,
      입출고구분: r.transaction_type || "",
      카테고리: parseRemark(r.remark),
      처리일자: fmtDate(r.transaction_date),
      창고: warehouseMap[r.warehouse_code] || r.warehouse_code || "",
      위치: r.location_code || "",
      품목코드: r.item_code || "",
      품목명: itemMap[r.item_code]?.item_name || "",
      수량: Number(r.quantity) || 0,
      단위: itemMap[r.item_code]?.unit || "",
      로트번호: r.lot_number || "",
      참조번호: r.reference_number || "",
      담당자: r.manager_name || userMap[r.writer] || r.writer || "",
    }));
    const _n = new Date();
    await exportToExcel(rows, `입출고관리_${_n.getFullYear()}${String(_n.getMonth() + 1).padStart(2, "0")}${String(_n.getDate()).padStart(2, "0")}.xlsx`, "입출고내역");
    toast.success("다운로드 완료");
  };

  // ════════ 렌더 ════════

  return (
    <div className="flex h-full flex-col gap-3 p-3">
      {/* 검색 */}
      <div className="flex items-center gap-2 flex-wrap">
        <Select value={typeFilter} onValueChange={setTypeFilter}>
          <SelectTrigger className="h-9 w-[130px] text-xs">
            <SelectValue placeholder="입출고구분" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">전체</SelectItem>
            <SelectItem value="입고">입고</SelectItem>
            <SelectItem value="출고">출고</SelectItem>
          </SelectContent>
        </Select>

        <Select value={categoryFilter} onValueChange={setCategoryFilter}>
          <SelectTrigger className="h-9 w-[140px] text-xs">
            <SelectValue placeholder="카테고리" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">전체</SelectItem>
            {categoryOptions.map((c) => <SelectItem key={c} value={c}>{c}</SelectItem>)}
          </SelectContent>
        </Select>

        <div className="flex-1">
          <DynamicSearchFilter
            tableName={HISTORY_TABLE}
            filterId="c16-inbound-outbound"
            onFilterChange={setSearchFilters}
            dataCount={data.length}
          />
        </div>
      </div>

      {/* 데이터 테이블 */}
      <div className="flex-1 overflow-hidden rounded-lg border border-border bg-card flex flex-col">
        {/* 헤더 */}
        <div className="flex items-center justify-between px-4 py-3 border-b bg-muted/30 shrink-0">
          <div className="flex items-center gap-2">
            <Package className="w-4 h-4 text-muted-foreground" />
            <span className="text-sm font-semibold">입출고 내역</span>
            <Badge variant="secondary" className="font-mono text-xs">{filteredData.length}건</Badge>
          </div>
          <div className="flex items-center gap-2">
            <Select value={groupBy} onValueChange={(v) => { setGroupBy(v); setExpandedGroups(new Set()); }}>
              <SelectTrigger className="h-8 w-[130px] text-xs">
                <SelectValue placeholder="그룹없음" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="none">그룹없음</SelectItem>
                <SelectItem value="transaction_type">입출고구분별</SelectItem>
                <SelectItem value="remark">카테고리별</SelectItem>
                <SelectItem value="warehouse_code">창고별</SelectItem>
                <SelectItem value="item_code">품목코드별</SelectItem>
              </SelectContent>
            </Select>
            <Button variant="outline" size="sm" onClick={handleExcel} disabled={data.length === 0}>
              <Download className="w-3.5 h-3.5 mr-1" /> 엑셀 다운로드
            </Button>
          </div>
        </div>

        {/* 테이블 */}
        <div className="flex-1 overflow-auto">
          {loading ? (
            <div className="flex items-center justify-center h-full"><Loader2 className="w-6 h-6 animate-spin text-muted-foreground" /></div>
          ) : data.length === 0 ? (
            <div className="flex flex-col items-center justify-center h-full text-muted-foreground gap-2">
              <Inbox className="w-10 h-10 opacity-30" />
              <span className="text-sm">조회된 데이터가 없습니다</span>
            </div>
          ) : (
            <Table>
              <TableHeader className="sticky top-0 z-10">
                <TableRow className="bg-muted hover:bg-muted">
                  <TableHead className="w-[40px] text-center">
                    <Checkbox checked={allChecked} onCheckedChange={(c) => toggleAll(!!c)} />
                  </TableHead>
                  <TableHead className="w-[90px] text-center text-[11px]">입출고구분</TableHead>
                  <TableHead className="w-[100px] text-center text-[11px]">카테고리</TableHead>
                  <TableHead className="w-[95px] text-center text-[11px]">처리일자</TableHead>
                  <TableHead className="w-[100px] text-[11px]">창고</TableHead>
                  <TableHead className="w-[80px] text-center text-[11px]">위치</TableHead>
                  <TableHead className="w-[110px] text-[11px]">품목코드</TableHead>
                  <TableHead className="w-[160px] text-[11px]">품목명</TableHead>
                  <TableHead className="w-[80px] text-right text-[11px]">수량</TableHead>
                  <TableHead className="w-[50px] text-center text-[11px]">단위</TableHead>
                  <TableHead className="w-[110px] text-[11px]">로트번호</TableHead>
                  <TableHead className="w-[100px] text-[11px]">참조번호</TableHead>
                  <TableHead className="w-[80px] text-center text-[11px]">담당자</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {groupedData.map((row, idx) => {
                  if (row._group) {
                    const expanded = expandedGroups.has(row._key);
                    return (
                      <TableRow key={`g-${row._key}`} className="bg-muted/60 cursor-pointer hover:bg-muted" onClick={() => toggleGroup(row._key)}>
                        <TableCell colSpan={8} className="py-2 px-4">
                          <div className="flex items-center gap-2 text-sm font-semibold">
                            {expanded ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
                            {row._key}
                            <Badge variant="outline" className="text-[10px]">{row._count}건</Badge>
                          </div>
                        </TableCell>
                        <TableCell className="text-right font-mono font-bold text-primary text-[13px]">
                          {fmtNum(row._totalQty)}
                        </TableCell>
                        <TableCell colSpan={4} />
                      </TableRow>
                    );
                  }
                  // 그룹 접힘 체크
                  if (groupBy !== "none") {
                    let gk: string;
                    switch (groupBy) {
                      case "warehouse_code": gk = warehouseMap[row.warehouse_code] || row.warehouse_code || "미지정"; break;
                      case "item_code": gk = `${row.item_code} ${itemMap[row.item_code]?.item_name || ""}`.trim() || "미지정"; break;
                      default: gk = row[groupBy] || "미지정";
                    }
                    if (!expandedGroups.has(gk)) return null;
                  }

                  const isIn = row.transaction_type === "입고";
                  const qty = Number(row.quantity) || 0;
                  const checked = checkedIds.has(row.id);
                  const info = itemMap[row.item_code];

                  return (
                    <TableRow key={row.id || idx} className={cn("hover:bg-accent/50", checked && "bg-primary/5")}>
                      <TableCell className="text-center">
                        <Checkbox checked={checked} onCheckedChange={() => toggleOne(row.id)} />
                      </TableCell>
                      <TableCell className="text-center">
                        <span className={cn(
                          "inline-flex items-center gap-1 text-[11px] font-semibold px-2 py-0.5 rounded-full",
                          isIn ? "bg-emerald-100 text-emerald-700" : "bg-amber-100 text-amber-700"
                        )}>
                          {isIn ? <ArrowDownToLine className="w-3 h-3" /> : <ArrowUpFromLine className="w-3 h-3" />}
                          {row.transaction_type}
                        </span>
                      </TableCell>
                      <TableCell className="text-center text-[12px]">{parseRemark(row.remark) || "-"}</TableCell>
                      <TableCell className="text-center text-[12px]">{fmtDate(row.transaction_date)}</TableCell>
                      <TableCell className="text-[12px]">{warehouseMap[row.warehouse_code] || row.warehouse_code || "-"}</TableCell>
                      <TableCell className="text-center text-[12px]">{row.location_code || "-"}</TableCell>
                      <TableCell className="text-[12px] font-mono">{row.item_code || "-"}</TableCell>
                      <TableCell className="text-[13px]">{info?.item_name || "-"}</TableCell>
                      <TableCell className={cn("text-right font-mono font-semibold text-[13px]", isIn ? "text-emerald-600" : "text-amber-600")}>
                        {isIn ? "+" : ""}{fmtNum(qty)}
                      </TableCell>
                      <TableCell className="text-center text-[12px]">{info?.unit || "-"}</TableCell>
                      <TableCell className="text-[12px]">{row.lot_number || "-"}</TableCell>
                      <TableCell className="text-[12px] text-muted-foreground">{row.reference_number || "-"}</TableCell>
                      <TableCell className="text-center text-[12px]">{row.manager_name || userMap[row.writer] || row.writer || "-"}</TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          )}
        </div>
      </div>
    </div>
  );
}
