"use client";

import React, { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandInput, CommandList, CommandEmpty, CommandItem } from "@/components/ui/command";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";
import {
  Search, Plus, Trash2, RotateCcw, Loader2, Package, Box, X, Save, Edit2, Download, ChevronsUpDown, Check, Inbox, Settings2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { toast } from "sonner";
import {
  getPkgUnits, createPkgUnit, updatePkgUnit, deletePkgUnit,
  getPkgUnitItems, createPkgUnitItem, deletePkgUnitItem,
  getLoadingUnits, createLoadingUnit, updateLoadingUnit, deleteLoadingUnit,
  getLoadingUnitPkgs, createLoadingUnitPkg, deleteLoadingUnitPkg,
  getItemsByDivision, getGeneralItems,
  type PkgUnit, type PkgUnitItem, type LoadingUnit, type LoadingUnitPkg, type ItemInfoForPkg,
} from "@/lib/api/packaging";
import { useTableSettings } from "@/hooks/useTableSettings";
import { TableSettingsModal } from "@/components/common/TableSettingsModal";

const GRID_COLUMNS = [
  { key: "pkg_code", label: "품목코드" },
  { key: "pkg_name", label: "포장명" },
  { key: "pkg_type", label: "유형" },
  { key: "size", label: "크기(mm)" },
  { key: "max_weight", label: "최대중량" },
  { key: "status", label: "상태" },
];

// --- 코드 → 라벨 매핑 ---
const PKG_TYPE_LABEL: Record<string, string> = {
  BOX: "박스", PACK: "팩", CANBOARD: "캔보드", AIRCAP: "에어캡",
  ZIPCOS: "집코스", CYLINDER: "원통형", POLYCARTON: "포리/카톤",
};
const LOADING_TYPE_LABEL: Record<string, string> = {
  PALLET: "파렛트", WOOD_PALLET: "목재파렛트", PLASTIC_PALLET: "플라스틱파렛트",
  ALU_PALLET: "알루미늄파렛트", CONTAINER: "컨테이너", STEEL_BOX: "철재함",
  CAGE: "케이지", ETC: "기타",
};
const STATUS_LABEL: Record<string, string> = { ACTIVE: "사용", INACTIVE: "미사용" };

const getStatusColor = (s: string) => s === "ACTIVE" ? "bg-success/10 text-success" : "bg-muted text-muted-foreground";
const fmtSize = (w: any, l: any, h: any) => {
  const vals = [w, l, h].map(v => Number(v) || 0);
  return vals.some(v => v > 0) ? vals.join("×") : "-";
};

// 규격 문자열에서 치수 파싱
function parseSpecDimensions(spec: string | null) {
  if (!spec) return { w: 0, l: 0, h: 0 };
  const m3 = spec.match(/(\d+)\s*[x×]\s*(\d+)\s*[x×]\s*(\d+)/i);
  if (m3) return { w: parseInt(m3[1]), l: parseInt(m3[2]), h: parseInt(m3[3]) };
  const m2 = spec.match(/(\d+)\s*[x×]\s*(\d+)/i);
  if (m2) return { w: parseInt(m2[1]), l: parseInt(m2[2]), h: 0 };
  return { w: 0, l: 0, h: 0 };
}

export default function PackagingPage() {
  const ts = useTableSettings("c16-packaging", "pkg_unit", GRID_COLUMNS);
  const { confirm, ConfirmDialogComponent } = useConfirmDialog();
  const [activeTab, setActiveTab] = useState<"packing" | "loading">("packing");

  // 검색
  const [searchKeyword, setSearchKeyword] = useState("");

  // 포장재 데이터
  const [pkgUnits, setPkgUnits] = useState<PkgUnit[]>([]);
  const [pkgLoading, setPkgLoading] = useState(false);
  const [selectedPkg, setSelectedPkg] = useState<PkgUnit | null>(null);
  const [pkgItems, setPkgItems] = useState<PkgUnitItem[]>([]);
  const [pkgItemsLoading, setPkgItemsLoading] = useState(false);

  // 적재함 데이터
  const [loadingUnits, setLoadingUnits] = useState<LoadingUnit[]>([]);
  const [loadingLoading, setLoadingLoading] = useState(false);
  const [selectedLoading, setSelectedLoading] = useState<LoadingUnit | null>(null);
  const [loadingPkgs, setLoadingPkgs] = useState<LoadingUnitPkg[]>([]);
  const [loadingPkgsLoading, setLoadingPkgsLoading] = useState(false);

  // 모달
  const [pkgModalOpen, setPkgModalOpen] = useState(false);
  const [pkgModalMode, setPkgModalMode] = useState<"create" | "edit">("create");
  const [pkgForm, setPkgForm] = useState<Record<string, any>>({});
  const [pkgItemOptions, setPkgItemOptions] = useState<ItemInfoForPkg[]>([]);
  const [pkgItemPopoverOpen, setPkgItemPopoverOpen] = useState(false);

  const [loadModalOpen, setLoadModalOpen] = useState(false);
  const [loadModalMode, setLoadModalMode] = useState<"create" | "edit">("create");
  const [loadForm, setLoadForm] = useState<Record<string, any>>({});
  const [loadItemOptions, setLoadItemOptions] = useState<ItemInfoForPkg[]>([]);
  const [loadItemPopoverOpen, setLoadItemPopoverOpen] = useState(false);

  const [itemMatchModalOpen, setItemMatchModalOpen] = useState(false);
  const [itemMatchKeyword, setItemMatchKeyword] = useState("");
  const [itemMatchResults, setItemMatchResults] = useState<ItemInfoForPkg[]>([]);
  const [itemMatchSelected, setItemMatchSelected] = useState<ItemInfoForPkg | null>(null);
  const [itemMatchQty, setItemMatchQty] = useState(1);

  const [pkgMatchModalOpen, setPkgMatchModalOpen] = useState(false);
  const [pkgMatchQty, setPkgMatchQty] = useState(1);
  const [pkgMatchMethod, setPkgMatchMethod] = useState("");
  const [pkgMatchSelected, setPkgMatchSelected] = useState<PkgUnit | null>(null);
  const [pkgMatchSearchKw, setPkgMatchSearchKw] = useState("");

  const [saving, setSaving] = useState(false);

  // --- 데이터 로드 ---
  const fetchPkgUnits = useCallback(async () => {
    setPkgLoading(true);
    try {
      const res = await getPkgUnits();
      if (res.success) setPkgUnits(res.data);
    } catch { /* ignore */ } finally { setPkgLoading(false); }
  }, []);

  const fetchLoadingUnits = useCallback(async () => {
    setLoadingLoading(true);
    try {
      const res = await getLoadingUnits();
      if (res.success) setLoadingUnits(res.data);
    } catch { /* ignore */ } finally { setLoadingLoading(false); }
  }, []);

  useEffect(() => { fetchPkgUnits(); fetchLoadingUnits(); }, [fetchPkgUnits, fetchLoadingUnits]);

  // 포장재 선택 시 매칭 품목 로드
  const selectPkg = useCallback(async (pkg: PkgUnit) => {
    setSelectedPkg(pkg);
    setPkgItemsLoading(true);
    try {
      const res = await getPkgUnitItems(pkg.pkg_code);
      if (res.success) setPkgItems(res.data);
    } catch { setPkgItems([]); } finally { setPkgItemsLoading(false); }
  }, []);

  // 적재함 선택 시 포장구성 로드
  const selectLoading = useCallback(async (lu: LoadingUnit) => {
    setSelectedLoading(lu);
    setLoadingPkgsLoading(true);
    try {
      const res = await getLoadingUnitPkgs(lu.loading_code);
      if (res.success) setLoadingPkgs(res.data);
    } catch { setLoadingPkgs([]); } finally { setLoadingPkgsLoading(false); }
  }, []);

  // 검색 필터 적용
  const filteredPkgUnits = pkgUnits.filter((p) => {
    if (!searchKeyword) return true;
    const kw = searchKeyword.toLowerCase();
    return (p.pkg_code?.toLowerCase().includes(kw) || p.pkg_name?.toLowerCase().includes(kw));
  });

  const filteredLoadingUnits = loadingUnits.filter((l) => {
    if (!searchKeyword) return true;
    const kw = searchKeyword.toLowerCase();
    return (l.loading_code?.toLowerCase().includes(kw) || l.loading_name?.toLowerCase().includes(kw));
  });

  // --- 포장재 등록/수정 모달 ---
  const openPkgModal = async (mode: "create" | "edit") => {
    setPkgModalMode(mode);
    if (mode === "edit" && selectedPkg) {
      setPkgForm({ ...selectedPkg });
    } else {
      setPkgForm({ pkg_code: "", pkg_name: "", pkg_type: "", status: "ACTIVE", width_mm: "", length_mm: "", height_mm: "", self_weight_kg: "", max_load_kg: "", volume_l: "", remarks: "" });
    }
    setPkgItemPopoverOpen(false);
    try {
      const res = await getItemsByDivision("포장재");
      if (res.success) setPkgItemOptions(res.data);
    } catch { setPkgItemOptions([]); }
    setPkgModalOpen(true);
  };

  const onPkgItemSelect = (item: ItemInfoForPkg) => {
    setPkgItemPopoverOpen(false);
    const dims = parseSpecDimensions(item.size);
    setPkgForm((prev) => ({
      ...prev,
      pkg_code: item.item_number,
      pkg_name: item.item_name,
      width_mm: dims.w || prev.width_mm,
      length_mm: dims.l || prev.length_mm,
      height_mm: dims.h || prev.height_mm,
    }));
  };

  const savePkgUnit = async () => {
    if (!pkgForm.pkg_code || !pkgForm.pkg_name) { toast.error("포장코드와 포장명은 필수입니다."); return; }
    if (!pkgForm.pkg_type) { toast.error("포장유형을 선택해주세요."); return; }
    setSaving(true);
    try {
      if (pkgModalMode === "create") {
        const res = await createPkgUnit(pkgForm);
        if (res.success) { toast.success("포장재 등록 완료"); setPkgModalOpen(false); fetchPkgUnits(); }
      } else {
        const res = await updatePkgUnit(pkgForm.id, pkgForm);
        if (res.success) { toast.success("포장재 수정 완료"); setPkgModalOpen(false); fetchPkgUnits(); setSelectedPkg(res.data); }
      }
    } catch { toast.error("저장 실패"); } finally { setSaving(false); }
  };

  const handleDeletePkg = async (pkg: PkgUnit) => {
    const ok = await confirm(`"${pkg.pkg_name}" 포장재를 삭제하시겠습니까?`, { variant: "destructive", confirmText: "삭제" });
    if (!ok) return;
    try {
      await deletePkgUnit(pkg.id);
      toast.success("삭제 완료");
      setSelectedPkg(null); setPkgItems([]);
      fetchPkgUnits();
    } catch { toast.error("삭제 실패"); }
  };

  // --- 적재함 등록/수정 모달 ---
  const openLoadModal = async (mode: "create" | "edit") => {
    setLoadModalMode(mode);
    if (mode === "edit" && selectedLoading) {
      setLoadForm({ ...selectedLoading });
    } else {
      setLoadForm({ loading_code: "", loading_name: "", loading_type: "", status: "ACTIVE", width_mm: "", length_mm: "", height_mm: "", self_weight_kg: "", max_load_kg: "", max_stack: "", remarks: "" });
    }
    setLoadItemPopoverOpen(false);
    try {
      const res = await getItemsByDivision("적재함");
      if (res.success) setLoadItemOptions(res.data);
    } catch { setLoadItemOptions([]); }
    setLoadModalOpen(true);
  };

  const onLoadItemSelect = (item: ItemInfoForPkg) => {
    setLoadItemPopoverOpen(false);
    const dims = parseSpecDimensions(item.size);
    setLoadForm((prev) => ({
      ...prev,
      loading_code: item.item_number,
      loading_name: item.item_name,
      width_mm: dims.w || prev.width_mm,
      length_mm: dims.l || prev.length_mm,
      height_mm: dims.h || prev.height_mm,
    }));
  };

  const saveLoadingUnit = async () => {
    if (!loadForm.loading_code || !loadForm.loading_name) { toast.error("적재함코드와 적재함명은 필수입니다."); return; }
    if (!loadForm.loading_type) { toast.error("적재유형을 선택해주세요."); return; }
    setSaving(true);
    try {
      if (loadModalMode === "create") {
        const res = await createLoadingUnit(loadForm);
        if (res.success) { toast.success("적재함 등록 완료"); setLoadModalOpen(false); fetchLoadingUnits(); }
      } else {
        const res = await updateLoadingUnit(loadForm.id, loadForm);
        if (res.success) { toast.success("적재함 수정 완료"); setLoadModalOpen(false); fetchLoadingUnits(); setSelectedLoading(res.data); }
      }
    } catch { toast.error("저장 실패"); } finally { setSaving(false); }
  };

  const handleDeleteLoading = async (lu: LoadingUnit) => {
    const ok = await confirm(`"${lu.loading_name}" 적재함을 삭제하시겠습니까?`, { variant: "destructive", confirmText: "삭제" });
    if (!ok) return;
    try {
      await deleteLoadingUnit(lu.id);
      toast.success("삭제 완료");
      setSelectedLoading(null); setLoadingPkgs([]);
      fetchLoadingUnits();
    } catch { toast.error("삭제 실패"); }
  };

  // --- 품목 추가 모달 (포장재 매칭) ---
  const openItemMatchModal = async () => {
    setItemMatchKeyword(""); setItemMatchSelected(null); setItemMatchQty(1);
    setItemMatchModalOpen(true);
    try {
      const res = await getGeneralItems();
      if (res.success) setItemMatchResults(res.data);
    } catch { setItemMatchResults([]); }
  };

  const searchItemsForMatch = async () => {
    try {
      const res = await getGeneralItems(itemMatchKeyword || undefined);
      if (res.success) setItemMatchResults(res.data);
    } catch { setItemMatchResults([]); }
  };

  const saveItemMatch = async () => {
    if (!selectedPkg || !itemMatchSelected) { toast.error("품목을 선택해주세요."); return; }
    if (itemMatchQty <= 0) { toast.error("포장수량을 입력해주세요."); return; }
    setSaving(true);
    try {
      const res = await createPkgUnitItem({
        pkg_code: selectedPkg.pkg_code,
        item_number: itemMatchSelected.item_number,
        pkg_qty: itemMatchQty,
      });
      if (res.success) { toast.success("품목 추가 완료"); setItemMatchModalOpen(false); selectPkg(selectedPkg); }
    } catch { toast.error("추가 실패"); } finally { setSaving(false); }
  };

  const handleDeletePkgItem = async (item: PkgUnitItem) => {
    const ok = await confirm("매칭 품목을 삭제하시겠습니까?", { variant: "destructive", confirmText: "삭제" });
    if (!ok) return;
    try {
      await deletePkgUnitItem(item.id);
      toast.success("삭제 완료");
      if (selectedPkg) selectPkg(selectedPkg);
    } catch { toast.error("삭제 실패"); }
  };

  // --- 포장단위 추가 모달 (적재함 구성) ---
  const openPkgMatchModal = () => {
    setPkgMatchSelected(null); setPkgMatchQty(1); setPkgMatchMethod(""); setPkgMatchSearchKw("");
    setPkgMatchModalOpen(true);
  };

  const savePkgMatch = async () => {
    if (!selectedLoading || !pkgMatchSelected) { toast.error("포장단위를 선택해주세요."); return; }
    if (pkgMatchQty <= 0) { toast.error("최대적재수량을 입력해주세요."); return; }
    setSaving(true);
    try {
      const res = await createLoadingUnitPkg({
        loading_code: selectedLoading.loading_code,
        pkg_code: pkgMatchSelected.pkg_code,
        max_load_qty: pkgMatchQty,
        load_method: pkgMatchMethod || undefined,
      });
      if (res.success) { toast.success("포장단위 추가 완료"); setPkgMatchModalOpen(false); selectLoading(selectedLoading); }
    } catch { toast.error("추가 실패"); } finally { setSaving(false); }
  };

  const handleDeleteLoadPkg = async (lp: LoadingUnitPkg) => {
    const ok = await confirm("적재 구성을 삭제하시겠습니까?", { variant: "destructive", confirmText: "삭제" });
    if (!ok) return;
    try {
      await deleteLoadingUnitPkg(lp.id);
      toast.success("삭제 완료");
      if (selectedLoading) selectLoading(selectedLoading);
    } catch { toast.error("삭제 실패"); }
  };

  return (
    <div className="flex h-[calc(100vh-4rem)] flex-col gap-3 p-4">

      {/* 1. 필터 바 */}
      <div className="flex shrink-0 items-center gap-4 rounded-lg border bg-card px-4 py-3">
        <div className="flex items-center gap-2">
          <span className="whitespace-nowrap text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">검색</span>
          <Input
            placeholder="포장코드 / 포장명 / 적재함명"
            value={searchKeyword}
            onChange={(e) => setSearchKeyword(e.target.value)}
            className="h-8 w-[260px] text-xs"
          />
          {searchKeyword && (
            <Button variant="ghost" size="icon" className="h-7 w-7" onClick={() => setSearchKeyword("")}>
              <X className="h-3.5 w-3.5" />
            </Button>
          )}
        </div>
        <Button variant="ghost" size="sm" className="ml-auto" onClick={() => setSearchKeyword("")}>
          <RotateCcw className="mr-1.5 h-3.5 w-3.5" /> 초기화
        </Button>
      </div>

      {/* 2. 탭 바 */}
      <div className="flex shrink-0 gap-1 border-b">
        {(
          [
            ["packing", "포장재 관리", filteredPkgUnits.length],
            ["loading", "적재함 관리", filteredLoadingUnits.length],
          ] as const
        ).map(([tab, label, count]) => (
          <button
            key={tab}
            onClick={() => {
              setActiveTab(tab);
              if (tab === "packing") { setSelectedLoading(null); setLoadingPkgs([]); }
              else { setSelectedPkg(null); setPkgItems([]); }
            }}
            className={cn(
              "-mb-px flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors",
              activeTab === tab
                ? "border-primary text-primary"
                : "border-transparent text-muted-foreground hover:text-foreground"
            )}
          >
            {tab === "packing" ? <Package className="h-4 w-4" /> : <Box className="h-4 w-4" />}
            {label}
            <span className="rounded-full border border-primary/15 bg-primary/10 px-2 py-0.5 font-mono text-[11px] font-semibold text-primary">
              {count}
            </span>
          </button>
        ))}
      </div>

      {/* 3. 액션 바 */}
      <div className="flex shrink-0 items-center justify-between">
        <div className="flex items-center gap-2">
          <h3 className="text-sm font-semibold">
            {activeTab === "packing" ? "포장재 목록" : "적재함 목록"}
          </h3>
          {(activeTab === "packing" ? pkgLoading : loadingLoading) && (
            <Loader2 className="h-3.5 w-3.5 animate-spin text-muted-foreground" />
          )}
        </div>
        <div className="flex items-center gap-1.5">
          {activeTab === "packing" && selectedPkg && (
            <>
              <Button size="sm" variant="outline" className="h-7 text-xs" onClick={() => openPkgModal("edit")}>
                <Edit2 className="mr-1 h-3 w-3" /> 수정
              </Button>
              <Button
                size="sm" variant="outline"
                className="h-7 text-xs text-destructive border-destructive/20 bg-destructive/5 hover:bg-destructive/10"
                onClick={() => handleDeletePkg(selectedPkg)}
              >
                <Trash2 className="mr-1 h-3 w-3" /> 삭제
              </Button>
              <div className="h-4 w-px bg-border" />
            </>
          )}
          {activeTab === "loading" && selectedLoading && (
            <>
              <Button size="sm" variant="outline" className="h-7 text-xs" onClick={() => openLoadModal("edit")}>
                <Edit2 className="mr-1 h-3 w-3" /> 수정
              </Button>
              <Button
                size="sm" variant="outline"
                className="h-7 text-xs text-destructive border-destructive/20 bg-destructive/5 hover:bg-destructive/10"
                onClick={() => handleDeleteLoading(selectedLoading)}
              >
                <Trash2 className="mr-1 h-3 w-3" /> 삭제
              </Button>
              <div className="h-4 w-px bg-border" />
            </>
          )}
          <Button
            size="sm"
            onClick={() => activeTab === "packing" ? openPkgModal("create") : openLoadModal("create")}
          >
            <Plus className="mr-1 h-3.5 w-3.5" /> 등록
          </Button>
          <Button variant="ghost" size="sm" onClick={() => ts.setOpen(true)} title="테이블 설정">
            <Settings2 className="h-4 w-4" />
          </Button>
        </div>
      </div>

      {/* 4. 콘텐츠 영역 */}
      {activeTab === "packing" ? (
        <div className="flex flex-1 flex-col overflow-hidden rounded-lg border bg-card">
          {/* 포장재 목록 테이블 */}
          <div className={cn("overflow-auto", selectedPkg ? "flex-[0_0_50%] border-b" : "flex-1")}>
            <Table>
              <TableHeader className="sticky top-0 z-10 bg-muted/80 backdrop-blur-sm">
                <TableRow className="text-[11px]">
                  {ts.isVisible("pkg_code") && <TableHead className="p-2">품목코드</TableHead>}
                  {ts.isVisible("pkg_name") && <TableHead className="p-2">포장명</TableHead>}
                  {ts.isVisible("pkg_type") && <TableHead className="p-2 w-[80px]">유형</TableHead>}
                  {ts.isVisible("size") && <TableHead className="p-2 w-[100px]">크기(mm)</TableHead>}
                  {ts.isVisible("max_weight") && <TableHead className="p-2 w-[80px] text-right">최대중량</TableHead>}
                  {ts.isVisible("status") && <TableHead className="p-2 w-[60px] text-center">상태</TableHead>}
                </TableRow>
              </TableHeader>
              <TableBody>
                {pkgLoading ? (
                  <TableRow>
                    <TableCell colSpan={6} className="h-32 text-center">
                      <Loader2 className="mx-auto h-5 w-5 animate-spin text-muted-foreground" />
                    </TableCell>
                  </TableRow>
                ) : filteredPkgUnits.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={6} className="h-40 text-center">
                      <div className="flex flex-col items-center justify-center gap-2">
                        <div className="flex h-12 w-12 items-center justify-center rounded-full border-2 border-dashed border-muted-foreground/20">
                          <Inbox className="h-6 w-6 text-muted-foreground/40" />
                        </div>
                        <p className="text-xs text-muted-foreground">등록된 포장재가 없어요</p>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : filteredPkgUnits.map((p) => (
                  <TableRow
                    key={p.id}
                    className={cn(
                      "cursor-pointer text-xs transition-colors",
                      selectedPkg?.id === p.id ? "bg-primary/5" : "hover:bg-muted/50"
                    )}
                    onClick={() => selectPkg(p)}
                  >
                    {ts.isVisible("pkg_code") && <TableCell className="p-2 font-medium">{p.pkg_code}</TableCell>}
                    {ts.isVisible("pkg_name") && <TableCell className="p-2">{p.pkg_name}</TableCell>}
                    {ts.isVisible("pkg_type") && <TableCell className="p-2">{PKG_TYPE_LABEL[p.pkg_type] || p.pkg_type || "-"}</TableCell>}
                    {ts.isVisible("size") && <TableCell className="p-2 text-[10px] tabular-nums">{fmtSize(p.width_mm, p.length_mm, p.height_mm)}</TableCell>}
                    {ts.isVisible("max_weight") && <TableCell className="p-2 text-right">{Number(p.max_load_kg || 0) > 0 ? `${p.max_load_kg}kg` : "-"}</TableCell>}
                    {ts.isVisible("status") && <TableCell className="p-2 text-center">
                      <span className={cn("rounded px-1.5 py-0.5 text-[10px] font-medium", getStatusColor(p.status))}>
                        {STATUS_LABEL[p.status] || p.status}
                      </span>
                    </TableCell>}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>

          {/* 매칭 품목 서브패널 */}
          {selectedPkg && (
            <>
              <div className="flex shrink-0 items-center justify-between bg-muted/50 px-4 py-2">
                <div className="flex items-center gap-2">
                  <span className="text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">매칭 품목</span>
                  <span className="rounded-full border border-primary/15 bg-primary/10 px-2 py-0.5 font-mono text-[11px] font-semibold text-primary">
                    {pkgItems.length}건
                  </span>
                  <span className="max-w-[200px] truncate text-[11px] text-muted-foreground">
                    — {selectedPkg.pkg_name}
                  </span>
                </div>
                <div className="flex items-center gap-1.5">
                  <Button size="sm" variant="outline" className="h-7 text-xs" onClick={openItemMatchModal}>
                    <Plus className="mr-1 h-3 w-3" /> 품목 추가
                  </Button>
                  <Button
                    size="sm" variant="ghost" className="h-7 w-7 p-0 text-muted-foreground"
                    onClick={() => { setSelectedPkg(null); setPkgItems([]); }}
                  >
                    <X className="h-3.5 w-3.5" />
                  </Button>
                </div>
              </div>
              <div className="flex-1 overflow-auto">
                {pkgItemsLoading ? (
                  <div className="flex h-24 items-center justify-center">
                    <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                  </div>
                ) : pkgItems.length === 0 ? (
                  <div className="flex h-24 flex-col items-center justify-center gap-1.5">
                    <Inbox className="h-5 w-5 text-muted-foreground/40" />
                    <p className="text-xs text-muted-foreground">매칭된 품목이 없어요</p>
                  </div>
                ) : (
                  <Table>
                    <TableHeader className="sticky top-0 z-10 bg-muted/80 backdrop-blur-sm">
                      <TableRow className="text-[11px]">
                        <TableHead className="p-2">품목코드</TableHead>
                        <TableHead className="p-2">품목명</TableHead>
                        <TableHead className="p-2 w-[80px]">규격</TableHead>
                        <TableHead className="p-2 w-[50px]">단위</TableHead>
                        <TableHead className="p-2 w-[80px] text-right">포장수량</TableHead>
                        <TableHead className="p-2 w-[40px]" />
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {pkgItems.map((item) => (
                        <TableRow key={item.id} className="text-xs">
                          <TableCell className="p-2 font-medium">{item.item_number}</TableCell>
                          <TableCell className="p-2">{item.item_name || "-"}</TableCell>
                          <TableCell className="p-2">{item.spec || "-"}</TableCell>
                          <TableCell className="p-2">{item.unit || "EA"}</TableCell>
                          <TableCell className="p-2 text-right font-semibold">{Number(item.pkg_qty).toLocaleString()}</TableCell>
                          <TableCell className="p-2 text-center">
                            <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => handleDeletePkgItem(item)}>
                              <X className="h-3 w-3" />
                            </Button>
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                )}
              </div>
            </>
          )}
        </div>
      ) : (
        /* 적재함 관리 탭 */
        <div className="flex flex-1 flex-col overflow-hidden rounded-lg border bg-card">
          {/* 적재함 목록 테이블 */}
          <div className={cn("overflow-auto", selectedLoading ? "flex-[0_0_50%] border-b" : "flex-1")}>
            <Table>
              <TableHeader className="sticky top-0 z-10 bg-muted/80 backdrop-blur-sm">
                <TableRow className="text-[11px]">
                  <TableHead className="p-2">품목코드</TableHead>
                  <TableHead className="p-2">적재함명</TableHead>
                  <TableHead className="p-2 w-[90px]">유형</TableHead>
                  <TableHead className="p-2 w-[100px]">크기(mm)</TableHead>
                  <TableHead className="p-2 w-[80px] text-right">최대적재</TableHead>
                  <TableHead className="p-2 w-[60px] text-center">상태</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {loadingLoading ? (
                  <TableRow>
                    <TableCell colSpan={6} className="h-32 text-center">
                      <Loader2 className="mx-auto h-5 w-5 animate-spin text-muted-foreground" />
                    </TableCell>
                  </TableRow>
                ) : filteredLoadingUnits.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={6} className="h-40 text-center">
                      <div className="flex flex-col items-center justify-center gap-2">
                        <div className="flex h-12 w-12 items-center justify-center rounded-full border-2 border-dashed border-muted-foreground/20">
                          <Inbox className="h-6 w-6 text-muted-foreground/40" />
                        </div>
                        <p className="text-xs text-muted-foreground">등록된 적재함이 없어요</p>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : filteredLoadingUnits.map((l) => (
                  <TableRow
                    key={l.id}
                    className={cn(
                      "cursor-pointer text-xs transition-colors",
                      selectedLoading?.id === l.id ? "bg-primary/5" : "hover:bg-muted/50"
                    )}
                    onClick={() => selectLoading(l)}
                  >
                    <TableCell className="p-2 font-medium">{l.loading_code}</TableCell>
                    <TableCell className="p-2">{l.loading_name}</TableCell>
                    <TableCell className="p-2">{LOADING_TYPE_LABEL[l.loading_type] || l.loading_type || "-"}</TableCell>
                    <TableCell className="p-2 text-[10px] tabular-nums">{fmtSize(l.width_mm, l.length_mm, l.height_mm)}</TableCell>
                    <TableCell className="p-2 text-right">{Number(l.max_load_kg || 0) > 0 ? `${l.max_load_kg}kg` : "-"}</TableCell>
                    <TableCell className="p-2 text-center">
                      <span className={cn("rounded px-1.5 py-0.5 text-[10px] font-medium", getStatusColor(l.status))}>
                        {STATUS_LABEL[l.status] || l.status}
                      </span>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>

          {/* 포장구성 서브패널 */}
          {selectedLoading && (
            <>
              <div className="flex shrink-0 items-center justify-between bg-muted/50 px-4 py-2">
                <div className="flex items-center gap-2">
                  <span className="text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">적재 가능 포장단위</span>
                  <span className="rounded-full border border-primary/15 bg-primary/10 px-2 py-0.5 font-mono text-[11px] font-semibold text-primary">
                    {loadingPkgs.length}건
                  </span>
                  <span className="max-w-[200px] truncate text-[11px] text-muted-foreground">
                    — {selectedLoading.loading_name}
                  </span>
                </div>
                <div className="flex items-center gap-1.5">
                  <Button size="sm" variant="outline" className="h-7 text-xs" onClick={openPkgMatchModal}>
                    <Plus className="mr-1 h-3 w-3" /> 포장단위 추가
                  </Button>
                  <Button
                    size="sm" variant="ghost" className="h-7 w-7 p-0 text-muted-foreground"
                    onClick={() => { setSelectedLoading(null); setLoadingPkgs([]); }}
                  >
                    <X className="h-3.5 w-3.5" />
                  </Button>
                </div>
              </div>
              <div className="flex-1 overflow-auto">
                {loadingPkgsLoading ? (
                  <div className="flex h-24 items-center justify-center">
                    <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                  </div>
                ) : loadingPkgs.length === 0 ? (
                  <div className="flex h-24 flex-col items-center justify-center gap-1.5">
                    <Inbox className="h-5 w-5 text-muted-foreground/40" />
                    <p className="text-xs text-muted-foreground">등록된 포장단위가 없어요</p>
                  </div>
                ) : (
                  <Table>
                    <TableHeader className="sticky top-0 z-10 bg-muted/80 backdrop-blur-sm">
                      <TableRow className="text-[11px]">
                        <TableHead className="p-2">포장코드</TableHead>
                        <TableHead className="p-2">포장명</TableHead>
                        <TableHead className="p-2 w-[80px]">유형</TableHead>
                        <TableHead className="p-2 w-[90px] text-right">최대수량</TableHead>
                        <TableHead className="p-2 w-[80px]">적재방향</TableHead>
                        <TableHead className="p-2 w-[40px]" />
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {loadingPkgs.map((lp) => (
                        <TableRow key={lp.id} className="text-xs">
                          <TableCell className="p-2 font-medium">{lp.pkg_code}</TableCell>
                          <TableCell className="p-2">{lp.pkg_name || "-"}</TableCell>
                          <TableCell className="p-2">{PKG_TYPE_LABEL[lp.pkg_type || ""] || lp.pkg_type || "-"}</TableCell>
                          <TableCell className="p-2 text-right font-semibold">{Number(lp.max_load_qty).toLocaleString()}</TableCell>
                          <TableCell className="p-2">{lp.load_method || "-"}</TableCell>
                          <TableCell className="p-2 text-center">
                            <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => handleDeleteLoadPkg(lp)}>
                              <X className="h-3 w-3" />
                            </Button>
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                )}
              </div>
            </>
          )}
        </div>
      )}

      {/* 포장재 등록/수정 모달 */}
      <Dialog open={pkgModalOpen} onOpenChange={setPkgModalOpen}>
        <DialogContent className="max-w-2xl" style={{ maxHeight: "90vh", overflowY: "auto" }}>
          <DialogHeader>
            <DialogTitle>{pkgModalMode === "create" ? "포장재 등록" : "포장재 수정"}</DialogTitle>
            <DialogDescription>품목정보에서 포장재를 선택하면 코드와 이름이 자동 연동됩니다.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            {pkgModalMode === "create" && (
              <div className="rounded-lg border bg-muted/50 p-4">
                <Label className="mb-2 block text-xs font-semibold">품목정보 연결 (구분: 포장재)</Label>
                <Popover open={pkgItemPopoverOpen} onOpenChange={setPkgItemPopoverOpen}>
                  <PopoverTrigger asChild>
                    <Button variant="outline" role="combobox" className="h-9 w-full justify-between text-sm font-normal">
                      {pkgForm.pkg_code ? `${pkgForm.pkg_name} (${pkgForm.pkg_code})` : "품목정보에서 포장재를 선택하세요"}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="p-0" align="start" style={{ width: "var(--radix-popover-trigger-width)" }}>
                    <Command filter={(value, search) => {
                      const item = pkgItemOptions.find((i) => i.id === value);
                      if (!item) return 0;
                      const target = `${item.item_number} ${item.item_name} ${item.size || ""}`.toLowerCase();
                      return target.includes(search.toLowerCase()) ? 1 : 0;
                    }}>
                      <CommandInput placeholder="품목코드 / 품목명 검색..." />
                      <CommandList className="max-h-[200px]">
                        <CommandEmpty>검색 결과가 없습니다</CommandEmpty>
                        {pkgItemOptions.map((item) => (
                          <CommandItem key={item.id} value={item.id} onSelect={() => onPkgItemSelect(item)} className="text-xs">
                            <Check className={cn("mr-2 h-3 w-3", pkgForm.pkg_code === item.item_number ? "opacity-100" : "opacity-0")} />
                            <span className="font-medium">{item.item_name}</span>
                            <span className="ml-2 text-muted-foreground">{item.item_number}</span>
                            {item.size && <span className="ml-auto text-[10px] text-muted-foreground">{item.size}</span>}
                          </CommandItem>
                        ))}
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>
            )}
            <div className="grid grid-cols-2 gap-4">
              <div><Label className="text-xs">품목코드</Label><Input value={pkgForm.pkg_code || ""} readOnly className="h-9 bg-muted text-xs" /></div>
              <div><Label className="text-xs">포장명</Label><Input value={pkgForm.pkg_name || ""} readOnly className="h-9 bg-muted text-xs" /></div>
              <div>
                <Label className="text-xs">포장유형 <span className="text-destructive">*</span></Label>
                <Select value={pkgForm.pkg_type || ""} onValueChange={(v) => setPkgForm((p) => ({ ...p, pkg_type: v }))}>
                  <SelectTrigger className="h-9 text-xs"><SelectValue placeholder="선택" /></SelectTrigger>
                  <SelectContent>{Object.entries(PKG_TYPE_LABEL).map(([k, v]) => <SelectItem key={k} value={k}>{v}</SelectItem>)}</SelectContent>
                </Select>
              </div>
              <div>
                <Label className="text-xs">상태</Label>
                <Select value={pkgForm.status || "ACTIVE"} onValueChange={(v) => setPkgForm((p) => ({ ...p, status: v }))}>
                  <SelectTrigger className="h-9 text-xs"><SelectValue /></SelectTrigger>
                  <SelectContent>{Object.entries(STATUS_LABEL).map(([k, v]) => <SelectItem key={k} value={k}>{v}</SelectItem>)}</SelectContent>
                </Select>
              </div>
            </div>
            <div>
              <Label className="text-xs font-semibold">규격정보</Label>
              <div className="mt-2 grid grid-cols-3 gap-3">
                <div><Label className="text-[10px]">가로(mm)</Label><Input type="number" value={pkgForm.width_mm || ""} onChange={(e) => setPkgForm((p) => ({ ...p, width_mm: e.target.value }))} className="h-9 text-xs" /></div>
                <div><Label className="text-[10px]">세로(mm)</Label><Input type="number" value={pkgForm.length_mm || ""} onChange={(e) => setPkgForm((p) => ({ ...p, length_mm: e.target.value }))} className="h-9 text-xs" /></div>
                <div><Label className="text-[10px]">높이(mm)</Label><Input type="number" value={pkgForm.height_mm || ""} onChange={(e) => setPkgForm((p) => ({ ...p, height_mm: e.target.value }))} className="h-9 text-xs" /></div>
                <div><Label className="text-[10px]">자체중량(kg)</Label><Input type="number" value={pkgForm.self_weight_kg || ""} onChange={(e) => setPkgForm((p) => ({ ...p, self_weight_kg: e.target.value }))} className="h-9 text-xs" step="0.1" /></div>
                <div><Label className="text-[10px]">최대적재중량(kg)</Label><Input type="number" value={pkgForm.max_load_kg || ""} onChange={(e) => setPkgForm((p) => ({ ...p, max_load_kg: e.target.value }))} className="h-9 text-xs" step="0.1" /></div>
                <div><Label className="text-[10px]">내용적(L)</Label><Input type="number" value={pkgForm.volume_l || ""} onChange={(e) => setPkgForm((p) => ({ ...p, volume_l: e.target.value }))} className="h-9 text-xs" step="0.1" /></div>
              </div>
            </div>
            <div><Label className="text-xs">비고</Label><Input value={pkgForm.remarks || ""} onChange={(e) => setPkgForm((p) => ({ ...p, remarks: e.target.value }))} className="h-9 text-xs" placeholder="메모" /></div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setPkgModalOpen(false)}>취소</Button>
            <Button onClick={savePkgUnit} disabled={saving}>
              {saving ? <Loader2 className="mr-1 h-4 w-4 animate-spin" /> : <Save className="mr-1 h-4 w-4" />} 저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 적재함 등록/수정 모달 */}
      <Dialog open={loadModalOpen} onOpenChange={setLoadModalOpen}>
        <DialogContent className="max-w-2xl" style={{ maxHeight: "90vh", overflowY: "auto" }}>
          <DialogHeader>
            <DialogTitle>{loadModalMode === "create" ? "적재함 등록" : "적재함 수정"}</DialogTitle>
            <DialogDescription>품목정보에서 적재함을 선택하면 코드와 이름이 자동 연동됩니다.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            {loadModalMode === "create" && (
              <div className="rounded-lg border bg-muted/50 p-4">
                <Label className="mb-2 block text-xs font-semibold">품목정보 연결 (구분: 적재함)</Label>
                <Popover open={loadItemPopoverOpen} onOpenChange={setLoadItemPopoverOpen}>
                  <PopoverTrigger asChild>
                    <Button variant="outline" role="combobox" className="h-9 w-full justify-between text-sm font-normal">
                      {loadForm.loading_code ? `${loadForm.loading_name} (${loadForm.loading_code})` : "품목정보에서 적재함을 선택하세요"}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="p-0" align="start" style={{ width: "var(--radix-popover-trigger-width)" }}>
                    <Command filter={(value, search) => {
                      const item = loadItemOptions.find((i) => i.id === value);
                      if (!item) return 0;
                      const target = `${item.item_number} ${item.item_name} ${item.size || ""}`.toLowerCase();
                      return target.includes(search.toLowerCase()) ? 1 : 0;
                    }}>
                      <CommandInput placeholder="품목코드 / 품목명 검색..." />
                      <CommandList className="max-h-[200px]">
                        <CommandEmpty>검색 결과가 없습니다</CommandEmpty>
                        {loadItemOptions.map((item) => (
                          <CommandItem key={item.id} value={item.id} onSelect={() => onLoadItemSelect(item)} className="text-xs">
                            <Check className={cn("mr-2 h-3 w-3", loadForm.loading_code === item.item_number ? "opacity-100" : "opacity-0")} />
                            <span className="font-medium">{item.item_name}</span>
                            <span className="ml-2 text-muted-foreground">{item.item_number}</span>
                            {item.size && <span className="ml-auto text-[10px] text-muted-foreground">{item.size}</span>}
                          </CommandItem>
                        ))}
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>
            )}
            <div className="grid grid-cols-2 gap-4">
              <div><Label className="text-xs">적재함코드</Label><Input value={loadForm.loading_code || ""} readOnly className="h-9 bg-muted text-xs" /></div>
              <div><Label className="text-xs">적재함명</Label><Input value={loadForm.loading_name || ""} readOnly className="h-9 bg-muted text-xs" /></div>
              <div>
                <Label className="text-xs">적재유형 <span className="text-destructive">*</span></Label>
                <Select value={loadForm.loading_type || ""} onValueChange={(v) => setLoadForm((p) => ({ ...p, loading_type: v }))}>
                  <SelectTrigger className="h-9 text-xs"><SelectValue placeholder="선택" /></SelectTrigger>
                  <SelectContent>{Object.entries(LOADING_TYPE_LABEL).map(([k, v]) => <SelectItem key={k} value={k}>{v}</SelectItem>)}</SelectContent>
                </Select>
              </div>
              <div>
                <Label className="text-xs">상태</Label>
                <Select value={loadForm.status || "ACTIVE"} onValueChange={(v) => setLoadForm((p) => ({ ...p, status: v }))}>
                  <SelectTrigger className="h-9 text-xs"><SelectValue /></SelectTrigger>
                  <SelectContent>{Object.entries(STATUS_LABEL).map(([k, v]) => <SelectItem key={k} value={k}>{v}</SelectItem>)}</SelectContent>
                </Select>
              </div>
            </div>
            <div>
              <Label className="text-xs font-semibold">규격정보</Label>
              <div className="mt-2 grid grid-cols-3 gap-3">
                <div><Label className="text-[10px]">가로(mm)</Label><Input type="number" value={loadForm.width_mm || ""} onChange={(e) => setLoadForm((p) => ({ ...p, width_mm: e.target.value }))} className="h-9 text-xs" /></div>
                <div><Label className="text-[10px]">세로(mm)</Label><Input type="number" value={loadForm.length_mm || ""} onChange={(e) => setLoadForm((p) => ({ ...p, length_mm: e.target.value }))} className="h-9 text-xs" /></div>
                <div><Label className="text-[10px]">높이(mm)</Label><Input type="number" value={loadForm.height_mm || ""} onChange={(e) => setLoadForm((p) => ({ ...p, height_mm: e.target.value }))} className="h-9 text-xs" /></div>
                <div><Label className="text-[10px]">자체중량(kg)</Label><Input type="number" value={loadForm.self_weight_kg || ""} onChange={(e) => setLoadForm((p) => ({ ...p, self_weight_kg: e.target.value }))} className="h-9 text-xs" step="0.1" /></div>
                <div><Label className="text-[10px]">최대적재중량(kg)</Label><Input type="number" value={loadForm.max_load_kg || ""} onChange={(e) => setLoadForm((p) => ({ ...p, max_load_kg: e.target.value }))} className="h-9 text-xs" step="0.1" /></div>
                <div><Label className="text-[10px]">최대단수</Label><Input type="number" value={loadForm.max_stack || ""} onChange={(e) => setLoadForm((p) => ({ ...p, max_stack: e.target.value }))} className="h-9 text-xs" /></div>
              </div>
            </div>
            <div><Label className="text-xs">비고</Label><Input value={loadForm.remarks || ""} onChange={(e) => setLoadForm((p) => ({ ...p, remarks: e.target.value }))} className="h-9 text-xs" placeholder="메모" /></div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setLoadModalOpen(false)}>취소</Button>
            <Button onClick={saveLoadingUnit} disabled={saving}>
              {saving ? <Loader2 className="mr-1 h-4 w-4 animate-spin" /> : <Save className="mr-1 h-4 w-4" />} 저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 품목 추가 모달 (포장재 매칭) */}
      <Dialog open={itemMatchModalOpen} onOpenChange={setItemMatchModalOpen}>
        <DialogContent className="max-w-[900px]">
          <DialogHeader>
            <DialogTitle>품목 추가 — {selectedPkg?.pkg_name}</DialogTitle>
            <DialogDescription>포장재에 매칭할 품목을 검색하여 추가합니다.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <Input
              placeholder="품목코드 / 품목명 검색 (입력 시 자동 검색)"
              value={itemMatchKeyword}
              onChange={(e) => {
                setItemMatchKeyword(e.target.value);
                const kw = e.target.value;
                clearTimeout((window as any).__itemMatchTimer);
                (window as any).__itemMatchTimer = setTimeout(async () => {
                  try {
                    const res = await getGeneralItems(kw || undefined);
                    if (res.success) setItemMatchResults(res.data);
                  } catch { /* ignore */ }
                }, 300);
              }}
              className="h-9 text-xs"
            />
            <div className="max-h-[300px] overflow-auto rounded border">
              <Table>
                <TableHeader>
                  <TableRow className="text-[11px]">
                    <TableHead className="p-2 w-[30px]" />
                    <TableHead className="p-2 w-[130px]">품목코드</TableHead>
                    <TableHead className="p-2">품목명</TableHead>
                    <TableHead className="p-2 w-[100px]">규격</TableHead>
                    <TableHead className="p-2 w-[80px]">재질</TableHead>
                    <TableHead className="p-2 w-[50px]">단위</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {itemMatchResults.filter(i => !pkgItems.some(pi => pi.item_number === i.item_number)).length === 0 ? (
                    <TableRow><TableCell colSpan={6} className="h-16 text-center text-[13px] text-muted-foreground">검색 결과가 없습니다</TableCell></TableRow>
                  ) : itemMatchResults.filter(i => !pkgItems.some(pi => pi.item_number === i.item_number)).map((item) => (
                    <TableRow
                      key={item.id}
                      className={cn("cursor-pointer text-xs", itemMatchSelected?.id === item.id && "bg-primary/10")}
                      onClick={() => setItemMatchSelected(item)}
                    >
                      <TableCell className="p-2 text-center">{itemMatchSelected?.id === item.id ? "✓" : ""}</TableCell>
                      <TableCell className="p-2 font-medium">{item.item_number}</TableCell>
                      <TableCell className="p-2">{item.item_name}</TableCell>
                      <TableCell className="p-2">{item.spec || "-"}</TableCell>
                      <TableCell className="p-2">{item.material || "-"}</TableCell>
                      <TableCell className="p-2">{item.unit || "EA"}</TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
            <div className="flex items-end gap-4">
              <div className="flex-1">
                <Label className="text-xs">선택된 품목</Label>
                <Input
                  value={itemMatchSelected ? `${itemMatchSelected.item_name} (${itemMatchSelected.item_number})` : ""}
                  readOnly className="h-9 bg-muted text-xs"
                />
              </div>
              <div className="w-[120px]">
                <Label htmlFor="pkg-item-match-qty" className="text-xs">포장수량(EA) <span className="text-destructive">*</span></Label>
                <Input
                  id="pkg-item-match-qty" type="number" value={itemMatchQty}
                  onChange={(e) => setItemMatchQty(Number(e.target.value) || 0)}
                  min={1} className="h-9 text-xs"
                />
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setItemMatchModalOpen(false)}>취소</Button>
            <Button type="button" data-action-type="custom" onClick={saveItemMatch} disabled={saving || !itemMatchSelected}>
              {saving ? <Loader2 className="mr-1 h-4 w-4 animate-spin" /> : null} 추가
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 포장단위 추가 모달 (적재함 구성) */}
      <Dialog open={pkgMatchModalOpen} onOpenChange={setPkgMatchModalOpen}>
        <DialogContent className="max-w-[800px]">
          <DialogHeader>
            <DialogTitle>포장단위 추가 — {selectedLoading?.loading_name}</DialogTitle>
            <DialogDescription>적재함에 적재할 포장단위를 선택합니다.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <Input
              placeholder="포장코드 / 포장명 검색"
              value={pkgMatchSearchKw}
              onChange={(e) => setPkgMatchSearchKw(e.target.value)}
              className="h-9 text-xs"
            />
            <div className="max-h-[300px] overflow-auto rounded border">
              <Table>
                <TableHeader>
                  <TableRow className="text-[11px]">
                    <TableHead className="p-2 w-[30px]" />
                    <TableHead className="p-2 w-[120px]">포장코드</TableHead>
                    <TableHead className="p-2">포장명</TableHead>
                    <TableHead className="p-2 w-[70px]">유형</TableHead>
                    <TableHead className="p-2 w-[100px]">크기(mm)</TableHead>
                    <TableHead className="p-2 w-[80px] text-right">최대중량</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {(() => {
                    const kw = pkgMatchSearchKw.toLowerCase();
                    const filtered = pkgUnits.filter(p =>
                      p.status === "ACTIVE"
                      && !loadingPkgs.some(lp => lp.pkg_code === p.pkg_code)
                      && (!kw || p.pkg_code?.toLowerCase().includes(kw) || p.pkg_name?.toLowerCase().includes(kw))
                    );
                    return filtered.length === 0 ? (
                      <TableRow><TableCell colSpan={6} className="h-16 text-center text-[13px] text-muted-foreground">추가 가능한 포장단위가 없습니다</TableCell></TableRow>
                    ) : filtered.map((p) => (
                      <TableRow
                        key={p.id}
                        className={cn("cursor-pointer text-xs", pkgMatchSelected?.id === p.id && "bg-primary/10")}
                        onClick={() => setPkgMatchSelected(p)}
                      >
                        <TableCell className="p-2 text-center">{pkgMatchSelected?.id === p.id ? "✓" : ""}</TableCell>
                        <TableCell className="p-2 font-medium">{p.pkg_code}</TableCell>
                        <TableCell className="p-2">{p.pkg_name}</TableCell>
                        <TableCell className="p-2">{PKG_TYPE_LABEL[p.pkg_type] || p.pkg_type}</TableCell>
                        <TableCell className="p-2 text-[10px]">{fmtSize(p.width_mm, p.length_mm, p.height_mm)}</TableCell>
                        <TableCell className="p-2 text-right">{Number(p.max_load_kg || 0) > 0 ? `${p.max_load_kg}kg` : "-"}</TableCell>
                      </TableRow>
                    ));
                  })()}
                </TableBody>
              </Table>
            </div>
            <div className="flex items-end gap-4">
              <div className="w-[150px]">
                <Label htmlFor="loading-pkg-match-qty" className="text-xs">최대적재수량 <span className="text-destructive">*</span></Label>
                <Input
                  id="loading-pkg-match-qty" type="number" value={pkgMatchQty}
                  onChange={(e) => setPkgMatchQty(Number(e.target.value) || 0)}
                  min={1} className="h-9 text-xs"
                />
              </div>
              <div className="flex-1">
                <Label className="text-xs">적재방향</Label>
                <Input
                  value={pkgMatchMethod}
                  onChange={(e) => setPkgMatchMethod(e.target.value)}
                  placeholder="수직/수평/혼합"
                  className="h-9 text-xs"
                />
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setPkgMatchModalOpen(false)}>취소</Button>
            <Button type="button" data-action-type="custom" onClick={savePkgMatch} disabled={saving || !pkgMatchSelected}>
              {saving ? <Loader2 className="mr-1 h-4 w-4 animate-spin" /> : null} 추가
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {ConfirmDialogComponent}

      <TableSettingsModal
        open={ts.open}
        onOpenChange={ts.setOpen}
        tableName={ts.tableName}
        settingsId={ts.settingsId}
        onSave={ts.applySettings}
      />
    </div>
  );
}
