"use client";

/**
 * 재고현황 — 하드코딩 페이지 (Type B 마스터-디테일)
 *
 * 좌측: 재고 목록 (inventory_stock, item_info JOIN)
 * 우측: 선택 품목의 재고 이동 이력 (inventory_history)
 *
 * ★ 재고 직접 등록/삭제 불가 — 입출고를 통해서만 변동, 조정만 가능
 */

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable";
import {
  Package,
  Loader2,
  Download,
  ClipboardEdit,
  History,
  AlertTriangle,
  RefreshCw,
  Settings2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { useAuth } from "@/hooks/useAuth";
import { useTableSettings } from "@/hooks/useTableSettings";
import { TableSettingsModal } from "@/components/common/TableSettingsModal";
import { DynamicSearchFilter, FilterValue } from "@/components/common/DynamicSearchFilter";
import { EDataTable, EDataTableColumn } from "@/components/common/EDataTable";
import { toast } from "sonner";
import { useCategoryLabelMap, makeParseRemark } from "@/lib/categoryLabel";
import { exportToExcel } from "@/lib/utils/excelExport";

const STOCK_TABLE = "inventory_stock";

const STOCK_COLUMNS = [
  { key: "item_code", label: "품목코드" },
  { key: "item_name", label: "품명" },
  { key: "spec", label: "규격" },
  { key: "warehouse_code", label: "창고" },
  { key: "location_code", label: "위치" },
  { key: "current_qty", label: "현재수량", align: "right" as const },
  { key: "safety_qty", label: "안전재고", align: "right" as const },
  { key: "unit", label: "단위" },
  { key: "status", label: "상태" },
];
const HISTORY_TABLE = "inventory_history";

const getStatusVariant = (
  status: string
): "default" | "secondary" | "outline" | "destructive" => {
  switch (status) {
    case "정상":
      return "default";
    case "부족":
      return "destructive";
    case "과잉":
      return "secondary";
    case "미등록":
      return "outline";
    default:
      return "outline";
  }
};

const getHistoryTypeVariant = (
  type: string
): "default" | "secondary" | "outline" | "destructive" => {
  switch (type) {
    case "입고":
      return "default";
    case "출고":
      return "secondary";
    case "조정":
      return "outline";
    case "입고취소":
    case "이동":
      return "destructive";
    default:
      return "outline";
  }
};

export default function InventoryStatusPage() {
  const { user } = useAuth();
  const ts = useTableSettings("c16-inventory", STOCK_TABLE, STOCK_COLUMNS);

  // remark의 value_code → value_label 변환 파서
  const codeLabelMap = useCategoryLabelMap([
    { table: "inbound_mng", column: "inbound_type" },
    { table: "outbound_mng", column: "outbound_type" },
  ]);
  const parseRemark = useMemo(() => makeParseRemark(codeLabelMap), [codeLabelMap]);

  // 좌측: 재고 목록
  const [stockItems, setStockItems] = useState<any[]>([]);
  const [stockLoading, setStockLoading] = useState(false);
  const [selectedStockId, setSelectedStockId] = useState<string | null>(null);

  // 재고 없는 품목 표시 여부
  const [showMissingItems, setShowMissingItems] = useState(false);

  // 창고 목록 (조정 모달에서 사용)
  const [warehouseList, setWarehouseList] = useState<{ code: string; name: string }[]>([]);

  // 선택된 창고의 위치 목록 (조정 모달에서 사용)
  const [locationList, setLocationList] = useState<{ code: string; name: string }[]>([]);

  // 검색 필터
  const [searchFilters, setSearchFilters] = useState<FilterValue[]>([]);

  // 우측: 이동 이력
  const [historyItems, setHistoryItems] = useState<any[]>([]);
  const [historyLoading, setHistoryLoading] = useState(false);

  // 조정 모달
  const [adjustModalOpen, setAdjustModalOpen] = useState(false);
  const [adjustForm, setAdjustForm] = useState<{
    adjust_type: string;
    adjust_qty: string;
    reason: string;
    warehouse_code: string;
    location_code: string;
  }>({ adjust_type: "증가", adjust_qty: "", reason: "", warehouse_code: "", location_code: "" });
  const [adjustSaving, setAdjustSaving] = useState(false);

  // 카테고리 옵션
  const [categoryOptions, setCategoryOptions] = useState<
    Record<string, { code: string; label: string }[]>
  >({});

  // 사용자 맵 (writer → 이름)
  const [userMap, setUserMap] = useState<Record<string, string>>({});

  // 카테고리 + 사용자 로드
  useEffect(() => {
    const load = async () => {
      const optMap: Record<string, { code: string; label: string }[]> = {};
      const flatten = (vals: any[]): { code: string; label: string }[] => {
        const result: { code: string; label: string }[] = [];
        for (const v of vals) {
          result.push({ code: v.valueCode || v.value_code || v.code, label: v.valueLabel || v.value_label || v.label });
          if (v.children?.length) result.push(...flatten(v.children));
        }
        return result;
      };
      // inventory_stock 카테고리
      for (const col of ["status"]) {
        try {
          const res = await apiClient.get(`/table-categories/${STOCK_TABLE}/${col}/values`);
          if (res.data?.success) optMap[col] = flatten(res.data.data || []);
        } catch { /* skip */ }
      }
      // item_info 단위 카테고리
      try {
        const res = await apiClient.get("/table-categories/item_info/inventory_unit/values?filterCompanyCode=COMPANY_16");
        if (res.data?.success) optMap["item_inventory_unit"] = flatten(res.data.data || []);
      } catch { /* skip */ }
      setCategoryOptions(optMap);
    };
    load();
    // 사용자 목록 로드
    apiClient.get("/admin/users/name-map").then((res) => {
      const users = res.data?.data || [];
      const map: Record<string, string> = {};
      for (const u of users) {
        const id = u.user_id;
        const name = u.user_name || id;
        if (id) map[id] = name;
      }
      setUserMap(map);
    }).catch(() => {});
  }, []);

  // 재고 목록 조회
  const fetchStock = useCallback(async () => {
    setStockLoading(true);
    try {
      const filters = searchFilters.map((f) => ({ columnName: f.columnName, operator: f.operator, value: f.value }));
      const [stockRes, itemRes, whRes] = await Promise.all([
        apiClient.post(`/table-management/tables/${STOCK_TABLE}/data`, {
          page: 1, size: 0,
          dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
          autoFilter: true,
          sort: { columnName: "item_code", order: "asc" },
        }),
        apiClient.post(`/table-management/tables/item_info/data`, { page: 1, size: 0, autoFilter: true }),
        apiClient.post(`/table-management/tables/warehouse_info/data`, { page: 1, size: 0, autoFilter: true }),
      ]);
      const raw = stockRes.data?.data?.data || stockRes.data?.data?.rows || [];
      const items = itemRes.data?.data?.data || itemRes.data?.data?.rows || [];
      const warehouses = whRes.data?.data?.data || whRes.data?.data?.rows || [];
      const itemMap = new Map(items.map((i: any) => [i.item_number || i.item_code, { name: i.item_name || "", unit: i.inventory_unit || "", spec: i.size || "" }]));
      const whMap = new Map(warehouses.map((w: any) => [w.warehouse_code, w.warehouse_name || w.warehouse_code]));
      setWarehouseList(warehouses.map((w: any) => ({ code: w.warehouse_code, name: w.warehouse_name || w.warehouse_code })));
      const resolve = (col: string, code: string) => {
        if (!code) return "";
        return categoryOptions[col]?.find((o) => o.code === code)?.label || code;
      };
      const data = raw.map((r: any) => {
        const itemInfo = itemMap.get(r.item_code) as any;
        const rawUnit = itemInfo?.unit || r.unit || "";
        return {
          ...r,
          item_name: itemInfo?.name || "",
          spec: itemInfo?.spec || "",
          unit: resolve("item_inventory_unit", rawUnit) || rawUnit,
          warehouse_name: whMap.get(r.warehouse_code) || r.warehouse_code || "",
          status: resolve("status", r.status),
          _isLow: r.safety_qty && Number(r.current_qty) < Number(r.safety_qty),
        };
      });

      // 재고 없는 품목 표시: inventory_stock에 없는 item_info 품목을 미등록 가상 행으로 추가
      if (showMissingItems) {
        const existingCodes = new Set(raw.map((r: any) => r.item_code).filter(Boolean));
        const missingRows = items
          .filter((i: any) => {
            const code = i.item_number || i.item_code;
            return code && !existingCodes.has(code);
          })
          .map((i: any) => {
            const code = i.item_number || i.item_code;
            const rawUnit = i.inventory_unit || "";
            return {
              id: `missing-${code}`,
              item_code: code,
              item_name: i.item_name || "",
              spec: i.size || "",
              warehouse_code: "",
              warehouse_name: "",
              location_code: "",
              current_qty: "0",
              safety_qty: "",
              unit: resolve("item_inventory_unit", rawUnit) || rawUnit,
              status: "미등록",
              _isLow: false,
              _isMissing: true,
            };
          });
        setStockItems([...data, ...missingRows]);
      } else {
        setStockItems(data);
      }
    } catch {
      toast.error("재고 목록을 불러오지 못했어요");
    } finally {
      setStockLoading(false);
    }
  }, [categoryOptions, searchFilters, showMissingItems]);

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

  // 선택된 재고
  const selectedStock = stockItems.find((s) => s.id === selectedStockId);

  // 이력 조회
  const fetchHistory = useCallback(async () => {
    if (!selectedStock?.item_code) {
      setHistoryItems([]);
      return;
    }
    setHistoryLoading(true);
    try {
      const historyFilters: any[] = [
        {
          columnName: "item_code",
          operator: "equals",
          value: selectedStock.item_code,
        },
      ];
      if (selectedStock.warehouse_code) {
        historyFilters.push({
          columnName: "warehouse_code",
          operator: "equals",
          value: selectedStock.warehouse_code,
        });
      }
      const res = await apiClient.post(
        `/table-management/tables/${HISTORY_TABLE}/data`,
        {
          page: 1,
          size: 0,
          dataFilter: { enabled: true, filters: historyFilters },
          autoFilter: true,
          sort: { columnName: "transaction_date", order: "desc" },
        }
      );
      const raw = res.data?.data?.data || res.data?.data?.rows || [];
      setHistoryItems(raw);
    } catch {
      toast.error("재고 이력을 불러오지 못했어요");
    } finally {
      setHistoryLoading(false);
    }
  }, [selectedStock?.item_code, selectedStock?.warehouse_code]);

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

  // 창고 선택 시 해당 창고의 위치 목록 조회 (조정 모달용)
  useEffect(() => {
    const whCode = adjustForm.warehouse_code;
    if (!whCode) {
      setLocationList([]);
      return;
    }
    (async () => {
      try {
        const res = await apiClient.post(`/table-management/tables/warehouse_location/data`, {
          page: 1,
          size: 0,
          dataFilter: {
            enabled: true,
            filters: [{ columnName: "warehouse_code", operator: "equals", value: whCode }],
          },
          autoFilter: true,
        });
        const rows = res.data?.data?.data || res.data?.data?.rows || [];
        setLocationList(
          rows
            .filter((r: any) => r.location_code)
            .map((r: any) => ({ code: r.location_code, name: r.location_name || r.location_code }))
        );
      } catch {
        setLocationList([]);
      }
    })();
  }, [adjustForm.warehouse_code]);

  // 재고 조정 저장
  const handleAdjustSave = async () => {
    if (!selectedStock) return;
    const qty = Number(adjustForm.adjust_qty);
    if (!qty || qty <= 0) {
      toast.error("조정 수량을 입력해주세요");
      return;
    }
    if (!adjustForm.reason.trim()) {
      toast.error("조정 사유를 입력해주세요");
      return;
    }

    const isMissing = !!selectedStock._isMissing;
    const targetWhCode = isMissing ? adjustForm.warehouse_code : (selectedStock.warehouse_code || "");
    const targetLocCode = isMissing ? adjustForm.location_code : (selectedStock.location_code || "");

    if (isMissing && !targetWhCode) {
      toast.error("창고를 선택해주세요");
      return;
    }
    if (isMissing && adjustForm.adjust_type === "감소") {
      toast.error("미등록 품목은 감소 조정이 불가해요");
      return;
    }

    setAdjustSaving(true);
    try {
      const changeQty = adjustForm.adjust_type === "증가" ? qty : -qty;
      const afterQty = Number(selectedStock.current_qty || 0) + changeQty;

      await apiClient.post(
        `/table-management/tables/${HISTORY_TABLE}/add`,
        {
          id: crypto.randomUUID(),
          item_code: selectedStock.item_code,
          warehouse_code: targetWhCode,
          location_code: targetLocCode,
          transaction_type: "조정",
          transaction_date: new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().replace("Z", "+09:00"),
          quantity: String(changeQty),
          balance_qty: String(afterQty),
          remark: adjustForm.reason.trim(),
        }
      );

      if (isMissing) {
        // 새 재고 레코드 생성
        await apiClient.post(
          `/table-management/tables/${STOCK_TABLE}/add`,
          {
            id: crypto.randomUUID(),
            item_code: selectedStock.item_code,
            warehouse_code: targetWhCode,
            location_code: targetLocCode,
            current_qty: String(afterQty),
            safety_qty: "0",
            last_in_date: new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().replace("Z", "+09:00"),
          }
        );
      } else {
        await apiClient.put(
          `/table-management/tables/${STOCK_TABLE}/edit`,
          {
            originalData: { id: selectedStock.id },
            updatedData: { current_qty: afterQty },
          }
        );
      }

      toast.success("재고가 조정되었어요");
      setAdjustModalOpen(false);
      setAdjustForm({ adjust_type: "증가", adjust_qty: "", reason: "", warehouse_code: "", location_code: "" });
      setSelectedStockId(null);
      fetchStock();
    } catch {
      toast.error("재고 조정에 실패했어요");
    } finally {
      setAdjustSaving(false);
    }
  };

  // EDataTable 컬럼 정의
  const stockColumns: EDataTableColumn[] = ts.visibleColumns.map((col) => {
    const base: EDataTableColumn = { key: col.key, label: col.label, align: col.align };
    if (col.key === "current_qty") {
      return {
        ...base,
        align: "right" as const,
        render: (val: any, row: any) => (
          <span className="font-mono">
            <span className={cn(row._isLow && "text-destructive font-bold")}>
              {Number(row.current_qty || 0).toLocaleString()}
            </span>
            {row._isLow && (
              <AlertTriangle className="inline h-3 w-3 text-destructive ml-1" />
            )}
          </span>
        ),
      };
    }
    if (col.key === "warehouse_code") {
      return {
        ...base,
        render: (_val: any, row: any) => row.warehouse_name || row.warehouse_code || "",
      };
    }
    if (col.key === "safety_qty") {
      return {
        ...base,
        align: "right" as const,
        formatNumber: true,
      };
    }
    if (col.key === "status") {
      return {
        ...base,
        render: (val: any) => (
          <Badge variant={getStatusVariant(val)} className="text-[10px]">
            {val}
          </Badge>
        ),
      };
    }
    return base;
  });

  // 엑셀 내보내기
  const handleExcelExport = () => {
    if (stockItems.length === 0) {
      toast.error("내보낼 데이터가 없어요");
      return;
    }
    exportToExcel(
      stockItems.map((r) => ({
        품목코드: r.item_code,
        품명: r.item_name,
        규격: r.spec || "",
        창고: r.warehouse_name || r.warehouse_code,
        위치: r.location_code,
        현재수량: r.current_qty,
        안전재고: r.safety_qty,
        단위: r.unit,
        상태: r.status,
      })),
      "재고현황"
    );
  };

  return (
    <div className="flex flex-col h-full gap-3 p-3">
      {/* 검색 바 */}
      <DynamicSearchFilter
        tableName={STOCK_TABLE}
        filterId="c16-inventory"
        onFilterChange={setSearchFilters}
        externalFilterConfig={ts.filterConfig}
        dataCount={stockItems.length}
        extraActions={
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              className="h-8 gap-1 text-xs"
              onClick={handleExcelExport}
            >
              <Download className="h-3.5 w-3.5" />
              엑셀
            </Button>
            <Button variant="ghost" size="sm" className="h-8 px-2" onClick={() => ts.setOpen(true)} title="테이블 설정">
              <Settings2 className="h-3.5 w-3.5" />
            </Button>
          </div>
        }
      />

      {/* 마스터-디테일 패널 */}
      <ResizablePanelGroup
        direction="horizontal"
        className="flex-1 rounded-lg border bg-card"
      >
        {/* 좌측: 재고 목록 */}
        <ResizablePanel defaultSize={55} minSize={30}>
          <div className="flex flex-col h-full">
            <div className="flex items-center justify-between px-4 py-2.5 border-b bg-muted/50">
              <div className="flex items-center gap-2">
                <span className="text-[13px] font-bold">재고 목록</span>
                <Badge variant="default" className="rounded-full text-[11px]">
                  {stockItems.length}건
                </Badge>
              </div>
              <label className="flex items-center gap-1.5 cursor-pointer text-xs">
                <Checkbox
                  checked={showMissingItems}
                  onCheckedChange={(v) => setShowMissingItems(!!v)}
                />
                <span>재고 없는 품목 표시</span>
              </label>
            </div>

            <EDataTable
              columns={stockColumns}
              data={ts.groupData(stockItems)}
              rowKey={(row) => row.id}
              loading={stockLoading}
              emptyMessage="등록된 재고가 없어요"
              selectedId={selectedStockId}
              onSelect={(id) => setSelectedStockId(id)}
              showRowNumber
              showPagination={false}
              draggableColumns={false}
              columnOrderKey="c16-inventory"
            />
          </div>
        </ResizablePanel>

        <ResizableHandle withHandle />

        {/* 우측: 상세 이력 */}
        <ResizablePanel defaultSize={45} minSize={25}>
          <div className="flex flex-col h-full">
            {!selectedStock ? (
              <div className="flex flex-col items-center justify-center flex-1 m-5 border-2 border-dashed rounded-lg border-border">
                <Package className="h-12 w-12 text-muted-foreground/40 mb-4" />
                <p className="text-sm font-semibold text-muted-foreground">
                  품목을 선택해주세요
                </p>
                <p className="text-xs text-muted-foreground/70 mt-1">
                  좌측에서 품목을 선택하면 재고 이력이 표시돼요
                </p>
              </div>
            ) : (
              <>
                {/* 패널 헤더 */}
                <div className="flex items-center justify-between px-4 py-2.5 border-b bg-muted/50">
                  <div className="flex items-center gap-2">
                    <History className="h-4 w-4 text-muted-foreground" />
                    <span className="text-[13px] font-bold">
                      {selectedStock.item_name || selectedStock.item_code}
                    </span>
                    <Badge
                      variant="outline"
                      className="rounded-full text-[11px] font-mono"
                    >
                      {selectedStock.item_code}
                    </Badge>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="flex items-center gap-1.5 text-xs">
                      <span className="text-muted-foreground">현재:</span>
                      <span
                        className={cn(
                          "font-bold font-mono",
                          selectedStock._isLow
                            ? "text-destructive"
                            : "text-foreground"
                        )}
                      >
                        {Number(selectedStock.current_qty || 0).toLocaleString()}
                      </span>
                      {selectedStock._isLow && (
                        <AlertTriangle className="h-3.5 w-3.5 text-destructive" />
                      )}
                    </div>
                    <Button
                      variant="outline"
                      size="sm"
                      className="h-7 gap-1 text-xs"
                      onClick={() => {
                        setAdjustForm({
                          adjust_type: "증가",
                          adjust_qty: "",
                          reason: "",
                          warehouse_code: selectedStock._isMissing ? "" : (selectedStock.warehouse_code || ""),
                          location_code: selectedStock._isMissing ? "" : (selectedStock.location_code || ""),
                        });
                        setAdjustModalOpen(true);
                      }}
                    >
                      <ClipboardEdit className="h-3.5 w-3.5" />
                      재고 조정
                    </Button>
                  </div>
                </div>

                {/* 재고 요약 카드 */}
                <div className="grid grid-cols-4 gap-2 px-4 py-3 border-b">
                  <div className="flex flex-col items-center p-2 rounded-md bg-muted/50">
                    <span className="text-[10px] text-muted-foreground">현재수량</span>
                    <span className="text-sm font-bold font-mono">
                      {Number(selectedStock.current_qty || 0).toLocaleString()}
                    </span>
                  </div>
                  <div className="flex flex-col items-center p-2 rounded-md bg-muted/50">
                    <span className="text-[10px] text-muted-foreground">안전재고</span>
                    <span className="text-sm font-bold font-mono">
                      {Number(selectedStock.safety_qty || 0).toLocaleString()}
                    </span>
                  </div>
                  <div className="flex flex-col items-center p-2 rounded-md bg-muted/50">
                    <span className="text-[10px] text-muted-foreground">창고</span>
                    <span className="text-sm font-bold truncate max-w-full">
                      {selectedStock.warehouse_name || "-"}
                    </span>
                  </div>
                  <div className="flex flex-col items-center p-2 rounded-md bg-muted/50">
                    <span className="text-[10px] text-muted-foreground">상태</span>
                    <Badge
                      variant={getStatusVariant(selectedStock.status)}
                      className="text-[10px] mt-0.5"
                    >
                      {selectedStock.status || "-"}
                    </Badge>
                  </div>
                </div>

                {/* 이력 서브헤더 */}
                <div className="flex items-center justify-between px-4 py-2 border-b">
                  <div className="flex items-center gap-2">
                    <span className="text-xs font-semibold text-muted-foreground">
                      재고 이동 이력
                    </span>
                    <Badge variant="secondary" className="rounded-full text-[10px]">
                      {historyItems.length}건
                    </Badge>
                  </div>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="h-7 gap-1 text-xs"
                    onClick={fetchHistory}
                  >
                    <RefreshCw className="h-3 w-3" />
                    새로고침
                  </Button>
                </div>

                {/* 이력 테이블 */}
                <div className="flex-1 overflow-auto">
                  {historyLoading ? (
                    <div className="flex items-center justify-center h-20">
                      <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
                    </div>
                  ) : historyItems.length === 0 ? (
                    <div className="flex items-center justify-center h-20 text-xs text-muted-foreground">
                      재고 이동 이력이 없어요
                    </div>
                  ) : (
                    <Table>
                      <TableHeader className="sticky top-0 z-10">
                        <TableRow className="bg-muted hover:bg-muted">
                          <TableHead className="w-8 text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">#</TableHead>
                          <TableHead className="w-[110px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">일자</TableHead>
                          <TableHead className="w-[80px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">유형</TableHead>
                          <TableHead className="w-[90px] text-right text-[11px] font-bold uppercase tracking-wide text-muted-foreground">변동수량</TableHead>
                          <TableHead className="w-[90px] text-right text-[11px] font-bold uppercase tracking-wide text-muted-foreground">이후수량</TableHead>
                          <TableHead className="w-[120px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">참조번호</TableHead>
                          <TableHead className="text-[11px] font-bold uppercase tracking-wide text-muted-foreground">사유</TableHead>
                          <TableHead className="w-[80px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">처리자</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {historyItems.map((h, idx) => (
                          <TableRow key={h.id || idx} className="text-xs">
                            <TableCell className="text-center text-muted-foreground">
                              {idx + 1}
                            </TableCell>
                            <TableCell className="font-mono">
                              {h.transaction_date ? String(h.transaction_date).slice(0, 10) : h.history_date || ""}
                            </TableCell>
                            <TableCell>
                              <Badge
                                variant={getHistoryTypeVariant(h.transaction_type || h.history_type)}
                                className="text-[10px]"
                              >
                                {h.transaction_type || h.history_type}
                              </Badge>
                            </TableCell>
                            <TableCell
                              className={cn(
                                "text-right font-mono",
                                Number(h.quantity ?? h.change_qty) > 0
                                  ? "text-primary"
                                  : "text-destructive"
                              )}
                            >
                              {Number(h.quantity ?? h.change_qty) > 0 ? "+" : ""}
                              {Number(h.quantity ?? h.change_qty ?? 0).toLocaleString()}
                            </TableCell>
                            <TableCell className="text-right font-mono">
                              {Number(h.balance_qty ?? h.after_qty ?? 0).toLocaleString()}
                            </TableCell>
                            <TableCell className="font-mono truncate max-w-[120px]">
                              {h.reference_number || h.reference_no || ""}
                            </TableCell>
                            <TableCell className="truncate max-w-[150px]">
                              {parseRemark(h.remark) || h.reason || ""}
                            </TableCell>
                            <TableCell>{userMap[h.writer] || userMap[h.created_by] || h.writer || h.created_by || ""}</TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  )}
                </div>
              </>
            )}
          </div>
        </ResizablePanel>
      </ResizablePanelGroup>

      {/* 테이블 설정 모달 */}
      <TableSettingsModal
        open={ts.open}
        onOpenChange={ts.setOpen}
        tableName={ts.tableName}
        settingsId={ts.settingsId}
        defaultVisibleKeys={ts.defaultVisibleKeys}
        onSave={ts.applySettings}
      />

      {/* 재고 조정 Dialog */}
      <Dialog open={adjustModalOpen} onOpenChange={setAdjustModalOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>재고 조정</DialogTitle>
            <DialogDescription>
              {selectedStock
                ? `${selectedStock.item_name || selectedStock.item_code} — 현재 수량: ${Number(selectedStock.current_qty || 0).toLocaleString()}`
                : ""}
            </DialogDescription>
          </DialogHeader>

          <div className="grid gap-4 py-2">
            {selectedStock?._isMissing && (
              <>
                <div className="grid gap-1.5">
                  <Label className="text-[11px] font-semibold text-muted-foreground">
                    창고 <span className="text-destructive">*</span>
                  </Label>
                  <Select
                    value={adjustForm.warehouse_code}
                    onValueChange={(v) =>
                      setAdjustForm((prev) => ({
                        ...prev,
                        warehouse_code: v,
                        location_code: "",
                      }))
                    }
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="창고를 선택해주세요" />
                    </SelectTrigger>
                    <SelectContent>
                      {warehouseList.map((w) => (
                        <SelectItem key={w.code} value={w.code}>
                          {w.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid gap-1.5">
                  <Label className="text-[11px] font-semibold text-muted-foreground">
                    위치
                  </Label>
                  <Select
                    value={adjustForm.location_code}
                    onValueChange={(v) =>
                      setAdjustForm((prev) => ({ ...prev, location_code: v }))
                    }
                    disabled={!adjustForm.warehouse_code || locationList.length === 0}
                  >
                    <SelectTrigger>
                      <SelectValue
                        placeholder={
                          !adjustForm.warehouse_code
                            ? "창고를 먼저 선택하세요"
                            : locationList.length === 0
                              ? "등록된 위치가 없어요"
                              : "위치 선택 (선택 사항)"
                        }
                      />
                    </SelectTrigger>
                    <SelectContent>
                      {locationList.map((l) => (
                        <SelectItem key={l.code} value={l.code}>
                          {l.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </>
            )}

            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                조정 유형
              </Label>
              <Select
                value={adjustForm.adjust_type}
                onValueChange={(v) =>
                  setAdjustForm((prev) => ({ ...prev, adjust_type: v }))
                }
                disabled={!!selectedStock?._isMissing}
              >
                <SelectTrigger>
                  <SelectValue placeholder="조정 유형 선택" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="증가">증가 (입고 보정)</SelectItem>
                  <SelectItem value="감소">감소 (출고 보정)</SelectItem>
                </SelectContent>
              </Select>
              {selectedStock?._isMissing && (
                <p className="text-[10px] text-muted-foreground">
                  미등록 품목은 증가(신규 등록)만 가능해요
                </p>
              )}
            </div>

            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                조정 수량
              </Label>
              <Input
                type="number"
                min={1}
                placeholder="수량을 입력해주세요"
                value={adjustForm.adjust_qty}
                onChange={(e) =>
                  setAdjustForm((prev) => ({
                    ...prev,
                    adjust_qty: e.target.value,
                  }))
                }
              />
              {adjustForm.adjust_qty && selectedStock && (
                <p className="text-xs text-muted-foreground">
                  조정 후 수량:{" "}
                  <span className="font-mono font-bold">
                    {(
                      Number(selectedStock.current_qty || 0) +
                      (adjustForm.adjust_type === "증가" ? 1 : -1) *
                        Number(adjustForm.adjust_qty || 0)
                    ).toLocaleString()}
                  </span>
                </p>
              )}
            </div>

            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                조정 사유 *
              </Label>
              <Textarea
                placeholder="조정 사유를 입력해주세요"
                rows={3}
                value={adjustForm.reason}
                onChange={(e) =>
                  setAdjustForm((prev) => ({
                    ...prev,
                    reason: e.target.value,
                  }))
                }
              />
            </div>
          </div>

          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setAdjustModalOpen(false)}
            >
              취소
            </Button>
            <Button onClick={handleAdjustSave} disabled={adjustSaving}>
              {adjustSaving && (
                <Loader2 className="h-4 w-4 animate-spin mr-1" />
              )}
              조정하기
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
