"use client";

/**
 * 창고정보관리 — 하드코딩 페이지 (Type B 마스터-디테일)
 *
 * 좌측: 창고 목록 (warehouse_info)
 * 우측: 선택 창고의 로케이션 목록 (warehouse_location)
 *
 * ★ 하위 위치가 있으면 창고 삭제 불가
 */

import React, { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Label } from "@/components/ui/label";
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 {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable";
import {
  Plus,
  Trash2,
  Loader2,
  Download,
  MapPin,
  Building2,
  Settings2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { useAuth } from "@/hooks/useAuth";
import { toast } from "sonner";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";
import { useTableSettings } from "@/hooks/useTableSettings";
import { TableSettingsModal } from "@/components/common/TableSettingsModal";
import { DynamicSearchFilter, FilterValue } from "@/components/common/DynamicSearchFilter";
import { exportToExcel } from "@/lib/utils/excelExport";

const WAREHOUSE_TABLE = "warehouse_info";

const WAREHOUSE_COLUMNS = [
  { key: "warehouse_code", label: "창고코드" },
  { key: "warehouse_name", label: "창고명" },
  { key: "warehouse_type", label: "유형" },
  { key: "manager", label: "관리자" },
  { key: "status", label: "상태" },
];
const LOCATION_TABLE = "warehouse_location";

const getStatusVariant = (
  status: string
): "default" | "secondary" | "outline" | "destructive" => {
  switch (status) {
    case "사용":
    case "사용중":
      return "default";
    case "미사용":
      return "secondary";
    case "폐쇄":
      return "destructive";
    default:
      return "outline";
  }
};

const getTypeVariant = (
  type: string
): "default" | "secondary" | "outline" => {
  switch (type) {
    case "원자재":
    case "일반":
      return "default";
    case "완제품":
    case "보관":
      return "secondary";
    default:
      return "outline";
  }
};

export default function WarehouseManagementPage() {
  const { user } = useAuth();
  const { confirm, ConfirmDialogComponent } = useConfirmDialog();
  const ts = useTableSettings("c16-warehouse", WAREHOUSE_TABLE, WAREHOUSE_COLUMNS);

  // 좌측: 창고 목록
  const [warehouses, setWarehouses] = useState<any[]>([]);
  const [warehouseLoading, setWarehouseLoading] = useState(false);
  const [warehouseCount, setWarehouseCount] = useState(0);
  const [selectedWarehouseId, setSelectedWarehouseId] = useState<string | null>(null);

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

  // 우측: 로케이션 목록
  const [locations, setLocations] = useState<any[]>([]);
  const [locationLoading, setLocationLoading] = useState(false);
  const [locationCheckedIds, setLocationCheckedIds] = useState<string[]>([]);

  // 모달: 창고 등록/수정
  const [warehouseModalOpen, setWarehouseModalOpen] = useState(false);
  const [warehouseEditMode, setWarehouseEditMode] = useState(false);
  const [warehouseForm, setWarehouseForm] = useState<Record<string, any>>({});
  const [warehouseSaving, setWarehouseSaving] = useState(false);

  // 모달: 위치 등록/수정
  const [locationModalOpen, setLocationModalOpen] = useState(false);
  const [locationEditMode, setLocationEditMode] = useState(false);
  const [locationForm, setLocationForm] = useState<Record<string, any>>({});
  const [locationSaving, setLocationSaving] = useState(false);

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

  // 카테고리 로드
  useEffect(() => {
    const load = async () => {
      const flatten = (vals: any[]): { code: string; label: string }[] => {
        const result: { code: string; label: string }[] = [];
        for (const v of vals) {
          result.push({ code: v.valueCode, label: v.valueLabel });
          if (v.children?.length) result.push(...flatten(v.children));
        }
        return result;
      };

      const whOpts: Record<string, { code: string; label: string }[]> = {};
      for (const col of ["warehouse_type", "status"]) {
        try {
          const res = await apiClient.get(
            `/table-categories/${WAREHOUSE_TABLE}/${col}/values`
          );
          if (res.data?.success) whOpts[col] = flatten(res.data.data || []);
        } catch {
          /* skip */
        }
      }
      setCategoryOptions(whOpts);

      const locOpts: Record<string, { code: string; label: string }[]> = {};
      for (const col of ["location_type", "status"]) {
        try {
          const res = await apiClient.get(
            `/table-categories/${LOCATION_TABLE}/${col}/values`
          );
          if (res.data?.success) locOpts[col] = flatten(res.data.data || []);
        } catch {
          /* skip */
        }
      }
      setLocationCategoryOptions(locOpts);
    };
    load();
  }, []);

  // 카테고리 코드→라벨 변환 헬퍼
  const resolveCategory = useCallback(
    (
      optMap: Record<string, { code: string; label: string }[]>,
      col: string,
      code: string
    ) => {
      if (!code) return "";
      return optMap[col]?.find((o) => o.code === code)?.label || code;
    },
    []
  );

  // 창고 목록 조회
  const fetchWarehouses = useCallback(async () => {
    setWarehouseLoading(true);
    try {
      const filters = searchFilters.map((f) => ({ columnName: f.columnName, operator: f.operator, value: f.value }));
      const res = await apiClient.post(
        `/table-management/tables/${WAREHOUSE_TABLE}/data`,
        {
          page: 1,
          size: 500,
          dataFilter: filters.length > 0 ? { enabled: true, filters } : undefined,
          autoFilter: true,
          sort: { columnName: "warehouse_code", order: "asc" },
        }
      );
      const raw = res.data?.data?.data || res.data?.data?.rows || [];
      const data = raw.map((r: any) => ({
        ...r,
        warehouse_type: resolveCategory(categoryOptions, "warehouse_type", r.warehouse_type),
        status: resolveCategory(categoryOptions, "status", r.status),
      }));
      setWarehouses(data);
      setWarehouseCount(res.data?.data?.total || raw.length);
    } catch {
      toast.error("창고 목록을 불러오지 못했어요");
    } finally {
      setWarehouseLoading(false);
    }
  }, [categoryOptions, resolveCategory, searchFilters]);

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

  // 선택된 창고
  const selectedWarehouse = warehouses.find((w) => w.id === selectedWarehouseId);

  // 로케이션 조회
  const fetchLocations = useCallback(async () => {
    if (!selectedWarehouse?.warehouse_code) {
      setLocations([]);
      return;
    }
    setLocationLoading(true);
    try {
      const res = await apiClient.post(
        `/table-management/tables/${LOCATION_TABLE}/data`,
        {
          page: 1,
          size: 500,
          dataFilter: {
            enabled: true,
            filters: [
              {
                columnName: "warehouse_code",
                operator: "equals",
                value: selectedWarehouse.warehouse_code,
              },
            ],
          },
          autoFilter: true,
          sort: { columnName: "location_code", order: "asc" },
        }
      );
      const raw = res.data?.data?.data || res.data?.data?.rows || [];
      const data = raw.map((r: any) => ({
        ...r,
        location_type: resolveCategory(locationCategoryOptions, "location_type", r.location_type),
        status: resolveCategory(locationCategoryOptions, "status", r.status),
      }));
      setLocations(data);
    } catch {
      toast.error("위치 목록을 불러오지 못했어요");
    } finally {
      setLocationLoading(false);
    }
  }, [selectedWarehouse?.warehouse_code, locationCategoryOptions, resolveCategory]);

  useEffect(() => {
    setLocationCheckedIds([]);
    fetchLocations();
  }, [fetchLocations]);

  // 체크박스 헬퍼
  const allLocationChecked =
    locations.length > 0 && locationCheckedIds.length === locations.length;
  const someLocationChecked =
    locationCheckedIds.length > 0 && locationCheckedIds.length < locations.length;

  const toggleAllLocations = (checked: boolean) => {
    setLocationCheckedIds(checked ? locations.map((l) => l.id) : []);
  };

  const toggleLocation = (id: string, checked: boolean) => {
    setLocationCheckedIds((prev) =>
      checked ? [...prev, id] : prev.filter((i) => i !== id)
    );
  };

  // ─── 창고 CRUD ───

  const openWarehouseCreateModal = () => {
    setWarehouseEditMode(false);
    setWarehouseForm({});
    setWarehouseModalOpen(true);
  };

  const openWarehouseEditModal = (row: any) => {
    setWarehouseEditMode(true);
    setWarehouseForm({ ...row });
    setWarehouseModalOpen(true);
  };

  const handleWarehouseSave = async () => {
    if (!warehouseForm.warehouse_code?.trim()) {
      toast.error("창고코드를 입력해주세요");
      return;
    }
    if (!warehouseForm.warehouse_name?.trim()) {
      toast.error("창고명을 입력해주세요");
      return;
    }
    setWarehouseSaving(true);
    try {
      const fields = {
        warehouse_code: warehouseForm.warehouse_code?.trim(),
        warehouse_name: warehouseForm.warehouse_name?.trim(),
        warehouse_type: warehouseForm.warehouse_type || "",
        manager: warehouseForm.manager || "",
        address: warehouseForm.address || "",
        status: warehouseForm.status || "",
        description: warehouseForm.description || "",
      };

      if (warehouseEditMode && warehouseForm.id) {
        await apiClient.put(
          `/table-management/tables/${WAREHOUSE_TABLE}/edit`,
          {
            originalData: { id: warehouseForm.id },
            updatedData: fields,
          }
        );
        toast.success("창고 정보가 수정되었어요");
      } else {
        await apiClient.post(
          `/table-management/tables/${WAREHOUSE_TABLE}/add`,
          { id: crypto.randomUUID(), ...fields }
        );
        toast.success("창고가 등록되었어요");
      }
      setWarehouseModalOpen(false);
      fetchWarehouses();
    } catch {
      toast.error(warehouseEditMode ? "창고 수정에 실패했어요" : "창고 등록에 실패했어요");
    } finally {
      setWarehouseSaving(false);
    }
  };

  const handleWarehouseDelete = async () => {
    if (!selectedWarehouse) return;
    if (locations.length > 0) {
      toast.error("하위 위치가 있어 삭제할 수 없어요. 위치를 먼저 삭제해주세요.");
      return;
    }
    const ok = await confirm(
      `"${selectedWarehouse.warehouse_name}" 창고를 삭제할까요?`
    );
    if (!ok) return;
    try {
      await apiClient.delete(
        `/table-management/tables/${WAREHOUSE_TABLE}/delete`,
        { data: [{ id: selectedWarehouse.id }] }
      );
      toast.success("창고가 삭제되었어요");
      setSelectedWarehouseId(null);
      fetchWarehouses();
    } catch {
      toast.error("창고 삭제에 실패했어요");
    }
  };

  // ─── 위치 CRUD ───

  const openLocationCreateModal = () => {
    setLocationEditMode(false);
    setLocationForm({ warehouse_code: selectedWarehouse?.warehouse_code || "" });
    setLocationModalOpen(true);
  };

  const openLocationEditModal = (row: any) => {
    setLocationEditMode(true);
    setLocationForm({ ...row });
    setLocationModalOpen(true);
  };

  const handleLocationSave = async () => {
    if (!locationForm.location_code?.trim()) {
      toast.error("위치코드를 입력해주세요");
      return;
    }
    if (!locationForm.location_name?.trim()) {
      toast.error("위치명을 입력해주세요");
      return;
    }
    setLocationSaving(true);
    try {
      const fields = {
        warehouse_code: locationForm.warehouse_code || selectedWarehouse?.warehouse_code || "",
        location_code: locationForm.location_code?.trim(),
        location_name: locationForm.location_name?.trim(),
        floor: locationForm.floor || "",
        zone: locationForm.zone || "",
        row_num: locationForm.row_num || "",
        level_num: locationForm.level_num || "",
        location_type: locationForm.location_type || "",
        status: locationForm.status || "",
      };

      if (locationEditMode && locationForm.id) {
        await apiClient.put(
          `/table-management/tables/${LOCATION_TABLE}/edit`,
          {
            originalData: { id: locationForm.id },
            updatedData: fields,
          }
        );
        toast.success("위치 정보가 수정되었어요");
      } else {
        await apiClient.post(
          `/table-management/tables/${LOCATION_TABLE}/add`,
          { id: crypto.randomUUID(), ...fields }
        );
        toast.success("위치가 등록되었어요");
      }
      setLocationModalOpen(false);
      fetchLocations();
    } catch {
      toast.error(locationEditMode ? "위치 수정에 실패했어요" : "위치 등록에 실패했어요");
    } finally {
      setLocationSaving(false);
    }
  };

  const handleLocationDelete = async () => {
    if (locationCheckedIds.length === 0) {
      toast.error("삭제할 위치를 선택해주세요");
      return;
    }
    const ok = await confirm(`${locationCheckedIds.length}건의 위치를 삭제할까요?`);
    if (!ok) return;
    try {
      await apiClient.delete(
        `/table-management/tables/${LOCATION_TABLE}/delete`,
        { data: locationCheckedIds.map((id) => ({ id })) }
      );
      toast.success("위치가 삭제되었어요");
      setLocationCheckedIds([]);
      fetchLocations();
    } catch {
      toast.error("위치 삭제에 실패했어요");
    }
  };

  // 엑셀 내보내기
  const handleExcelExport = () => {
    if (warehouses.length === 0) {
      toast.error("내보낼 데이터가 없어요");
      return;
    }
    exportToExcel(
      warehouses.map((r) => ({
        창고코드: r.warehouse_code,
        창고명: r.warehouse_name,
        유형: r.warehouse_type,
        관리자: r.manager,
        상태: r.status,
      })),
      "창고정보"
    );
  };

  return (
    <div className="flex flex-col h-full gap-3 p-3">
      {ConfirmDialogComponent}

      {/* 검색 바 */}
      <DynamicSearchFilter
        tableName={WAREHOUSE_TABLE}
        filterId="c16-warehouse"
        onFilterChange={setSearchFilters}
        externalFilterConfig={ts.filterConfig}
        dataCount={warehouses.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={45} minSize={25}>
          <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]">
                  {warehouses.length}건
                </Badge>
              </div>
              <div className="flex items-center gap-1.5">
                <Button
                  size="sm"
                  className="h-7 gap-1 text-xs"
                  onClick={openWarehouseCreateModal}
                >
                  <Plus className="h-3.5 w-3.5" />
                  등록
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  className="h-7 gap-1 text-xs text-destructive hover:text-destructive"
                  onClick={handleWarehouseDelete}
                  disabled={!selectedWarehouse}
                >
                  <Trash2 className="h-3.5 w-3.5" />
                  삭제
                </Button>
              </div>
            </div>

            <div className="flex-1 overflow-auto">
              {warehouseLoading ? (
                <div className="flex items-center justify-center h-32">
                  <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                </div>
              ) : warehouses.length === 0 ? (
                <div className="flex items-center justify-center h-32 text-sm 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>
                      {ts.visibleColumns.map((col) => (
                        <TableHead key={col.key} className="text-[11px] font-bold uppercase tracking-wide text-muted-foreground">{col.label}</TableHead>
                      ))}
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {warehouses.map((w, idx) => (
                      <TableRow
                        key={w.id}
                        className={cn(
                          "cursor-pointer text-xs",
                          selectedWarehouseId === w.id && "bg-primary/10"
                        )}
                        onClick={() => setSelectedWarehouseId(w.id)}
                        onDoubleClick={() => openWarehouseEditModal(w)}
                      >
                        <TableCell className="text-center text-muted-foreground">
                          {idx + 1}
                        </TableCell>
                        {ts.visibleColumns.map((col) => {
                          if (col.key === "warehouse_type") {
                            return (
                              <TableCell key={col.key}>
                                <Badge variant={getTypeVariant(w.warehouse_type)} className="text-[10px]">
                                  {w.warehouse_type}
                                </Badge>
                              </TableCell>
                            );
                          }
                          if (col.key === "status") {
                            return (
                              <TableCell key={col.key}>
                                <Badge variant={getStatusVariant(w.status)} className="text-[10px]">
                                  {w.status}
                                </Badge>
                              </TableCell>
                            );
                          }
                          return (
                            <TableCell key={col.key} className="truncate max-w-[150px]">
                              {w[col.key] ?? ""}
                            </TableCell>
                          );
                        })}
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              )}
            </div>
          </div>
        </ResizablePanel>

        <ResizableHandle withHandle />

        {/* 우측: 로케이션 */}
        <ResizablePanel defaultSize={55} minSize={30}>
          <div className="flex flex-col h-full">
            {!selectedWarehouse ? (
              <div className="flex flex-col items-center justify-center flex-1 m-5 border-2 border-dashed rounded-lg border-border">
                <Building2 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">
                    <MapPin className="h-4 w-4 text-muted-foreground" />
                    <span className="text-[13px] font-bold">
                      {selectedWarehouse.warehouse_name}
                    </span>
                    <Badge
                      variant="outline"
                      className="rounded-full text-[11px] font-mono"
                    >
                      {selectedWarehouse.warehouse_code}
                    </Badge>
                    <Badge variant="secondary" className="rounded-full text-[10px]">
                      {locations.length}개 위치
                    </Badge>
                  </div>
                  <div className="flex items-center gap-1.5">
                    <Button
                      size="sm"
                      className="h-7 gap-1 text-xs"
                      onClick={openLocationCreateModal}
                    >
                      <Plus className="h-3.5 w-3.5" />
                      위치 등록
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      className="h-7 gap-1 text-xs text-destructive hover:text-destructive"
                      onClick={handleLocationDelete}
                      disabled={locationCheckedIds.length === 0}
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                      삭제
                    </Button>
                  </div>
                </div>

                {/* 로케이션 테이블 */}
                <div className="flex-1 overflow-auto">
                  {locationLoading ? (
                    <div className="flex items-center justify-center h-32">
                      <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                    </div>
                  ) : locations.length === 0 ? (
                    <div className="flex items-center justify-center h-32 text-sm text-muted-foreground">
                      등록된 위치가 없어요
                    </div>
                  ) : (
                    <Table>
                      <TableHeader className="sticky top-0 z-10">
                        <TableRow className="bg-muted hover:bg-muted">
                          <TableHead className="w-10 text-center">
                            <Checkbox
                              checked={
                                someLocationChecked
                                  ? "indeterminate"
                                  : allLocationChecked
                              }
                              onCheckedChange={(v) =>
                                toggleAllLocations(v === true)
                              }
                              aria-label="전체 선택"
                            />
                          </TableHead>
                          <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="text-[11px] font-bold uppercase tracking-wide text-muted-foreground">위치명</TableHead>
                          <TableHead className="w-[50px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">층</TableHead>
                          <TableHead className="w-[70px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">구역</TableHead>
                          <TableHead className="w-[50px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">열</TableHead>
                          <TableHead className="w-[50px] text-center 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-[70px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">상태</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {locations.map((loc, idx) => (
                          <TableRow
                            key={loc.id}
                            className={cn(
                              "cursor-pointer text-xs",
                              locationCheckedIds.includes(loc.id) && "bg-primary/5"
                            )}
                            onDoubleClick={() => openLocationEditModal(loc)}
                          >
                            <TableCell className="text-center">
                              <Checkbox
                                checked={locationCheckedIds.includes(loc.id)}
                                onCheckedChange={(v) =>
                                  toggleLocation(loc.id, v === true)
                                }
                                aria-label="행 선택"
                              />
                            </TableCell>
                            <TableCell className="text-center text-muted-foreground">
                              {idx + 1}
                            </TableCell>
                            <TableCell className="font-mono truncate max-w-[110px]">
                              {loc.location_code}
                            </TableCell>
                            <TableCell className="truncate max-w-[120px]">
                              {loc.location_name}
                            </TableCell>
                            <TableCell className="text-center">{loc.floor}</TableCell>
                            <TableCell>{loc.zone}</TableCell>
                            <TableCell className="text-center">{loc.row_num}</TableCell>
                            <TableCell className="text-center">{loc.level_num}</TableCell>
                            <TableCell>
                              <Badge
                                variant={getTypeVariant(loc.location_type)}
                                className="text-[10px]"
                              >
                                {loc.location_type}
                              </Badge>
                            </TableCell>
                            <TableCell>
                              <Badge
                                variant={getStatusVariant(loc.status)}
                                className="text-[10px]"
                              >
                                {loc.status}
                              </Badge>
                            </TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  )}
                </div>
              </>
            )}
          </div>
        </ResizablePanel>
      </ResizablePanelGroup>

      {/* 창고 등록/수정 Dialog */}
      <Dialog open={warehouseModalOpen} onOpenChange={setWarehouseModalOpen}>
        <DialogContent className="max-w-xl">
          <DialogHeader>
            <DialogTitle>
              {warehouseEditMode ? "창고 수정" : "창고 등록"}
            </DialogTitle>
            <DialogDescription>
              {warehouseEditMode
                ? "창고 정보를 수정해주세요"
                : "새로운 창고를 등록해주세요"}
            </DialogDescription>
          </DialogHeader>

          <div className="grid grid-cols-2 gap-4 py-2">
            {/* 창고코드 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                창고코드 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={warehouseForm.warehouse_code || ""}
                onChange={(e) =>
                  setWarehouseForm((prev) => ({ ...prev, warehouse_code: e.target.value }))
                }
                placeholder="창고코드를 입력해주세요"
                disabled={warehouseEditMode}
              />
            </div>
            {/* 창고명 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                창고명 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={warehouseForm.warehouse_name || ""}
                onChange={(e) =>
                  setWarehouseForm((prev) => ({ ...prev, warehouse_name: e.target.value }))
                }
                placeholder="창고명을 입력해주세요"
              />
            </div>
            {/* 유형 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">유형</Label>
              <Select
                value={warehouseForm.warehouse_type || ""}
                onValueChange={(v) =>
                  setWarehouseForm((prev) => ({ ...prev, warehouse_type: v }))
                }
              >
                <SelectTrigger>
                  <SelectValue placeholder="유형 선택" />
                </SelectTrigger>
                <SelectContent>
                  {(categoryOptions["warehouse_type"] || []).map((o) => (
                    <SelectItem key={o.code} value={o.code}>
                      {o.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            {/* 관리자 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">관리자</Label>
              <Input
                value={warehouseForm.manager || ""}
                onChange={(e) =>
                  setWarehouseForm((prev) => ({ ...prev, manager: e.target.value }))
                }
                placeholder="관리자를 입력해주세요"
              />
            </div>
            {/* 상태 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">상태</Label>
              <Select
                value={warehouseForm.status || ""}
                onValueChange={(v) =>
                  setWarehouseForm((prev) => ({ ...prev, status: v }))
                }
              >
                <SelectTrigger>
                  <SelectValue placeholder="상태 선택" />
                </SelectTrigger>
                <SelectContent>
                  {(categoryOptions["status"] || []).map((o) => (
                    <SelectItem key={o.code} value={o.code}>
                      {o.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            {/* 주소 (전체 너비) */}
            <div className="grid gap-1.5 col-span-2">
              <Label className="text-[11px] font-semibold text-muted-foreground">주소</Label>
              <Input
                value={warehouseForm.address || ""}
                onChange={(e) =>
                  setWarehouseForm((prev) => ({ ...prev, address: e.target.value }))
                }
                placeholder="주소를 입력해주세요"
              />
            </div>
            {/* 비고 (전체 너비) */}
            <div className="grid gap-1.5 col-span-2">
              <Label className="text-[11px] font-semibold text-muted-foreground">비고</Label>
              <Input
                value={warehouseForm.description || ""}
                onChange={(e) =>
                  setWarehouseForm((prev) => ({ ...prev, description: e.target.value }))
                }
                placeholder="비고를 입력해주세요"
              />
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setWarehouseModalOpen(false)}>
              취소
            </Button>
            <Button onClick={handleWarehouseSave} disabled={warehouseSaving}>
              {warehouseSaving && (
                <Loader2 className="h-4 w-4 animate-spin mr-1" />
              )}
              {warehouseEditMode ? "수정하기" : "등록하기"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 위치 등록/수정 Dialog */}
      <Dialog open={locationModalOpen} onOpenChange={setLocationModalOpen}>
        <DialogContent className="max-w-xl">
          <DialogHeader>
            <DialogTitle>
              {locationEditMode ? "위치 수정" : "위치 등록"}
            </DialogTitle>
            <DialogDescription>
              {locationEditMode
                ? "위치 정보를 수정해주세요"
                : `${selectedWarehouse?.warehouse_name || ""} 창고에 새 위치를 등록해주세요`}
            </DialogDescription>
          </DialogHeader>

          <div className="grid grid-cols-2 gap-4 py-2">
            {/* 창고코드 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">창고코드</Label>
              <Input value={locationForm.warehouse_code || ""} disabled />
            </div>
            {/* 위치코드 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                위치코드 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={locationForm.location_code || ""}
                onChange={(e) =>
                  setLocationForm((prev) => ({ ...prev, location_code: e.target.value }))
                }
                placeholder="위치코드를 입력해주세요"
                disabled={locationEditMode}
              />
            </div>
            {/* 위치명 */}
            <div className="grid gap-1.5 col-span-2">
              <Label className="text-[11px] font-semibold text-muted-foreground">
                위치명 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={locationForm.location_name || ""}
                onChange={(e) =>
                  setLocationForm((prev) => ({ ...prev, location_name: e.target.value }))
                }
                placeholder="위치명을 입력해주세요"
              />
            </div>
            {/* 층 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">층</Label>
              <Input
                value={locationForm.floor || ""}
                onChange={(e) =>
                  setLocationForm((prev) => ({ ...prev, floor: e.target.value }))
                }
                placeholder="층을 입력해주세요"
              />
            </div>
            {/* 구역 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">구역</Label>
              <Input
                value={locationForm.zone || ""}
                onChange={(e) =>
                  setLocationForm((prev) => ({ ...prev, zone: e.target.value }))
                }
                placeholder="구역을 입력해주세요"
              />
            </div>
            {/* 열 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">열</Label>
              <Input
                value={locationForm.row_num || ""}
                onChange={(e) =>
                  setLocationForm((prev) => ({ ...prev, row_num: e.target.value }))
                }
                placeholder="열을 입력해주세요"
              />
            </div>
            {/* 단 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">단</Label>
              <Input
                value={locationForm.level_num || ""}
                onChange={(e) =>
                  setLocationForm((prev) => ({ ...prev, level_num: e.target.value }))
                }
                placeholder="단을 입력해주세요"
              />
            </div>
            {/* 위치유형 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">위치유형</Label>
              <Select
                value={locationForm.location_type || ""}
                onValueChange={(v) =>
                  setLocationForm((prev) => ({ ...prev, location_type: v }))
                }
              >
                <SelectTrigger>
                  <SelectValue placeholder="위치유형 선택" />
                </SelectTrigger>
                <SelectContent>
                  {(locationCategoryOptions["location_type"] || []).map((o) => (
                    <SelectItem key={o.code} value={o.code}>
                      {o.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            {/* 상태 */}
            <div className="grid gap-1.5">
              <Label className="text-[11px] font-semibold text-muted-foreground">상태</Label>
              <Select
                value={locationForm.status || ""}
                onValueChange={(v) =>
                  setLocationForm((prev) => ({ ...prev, status: v }))
                }
              >
                <SelectTrigger>
                  <SelectValue placeholder="상태 선택" />
                </SelectTrigger>
                <SelectContent>
                  {(locationCategoryOptions["status"] || []).map((o) => (
                    <SelectItem key={o.code} value={o.code}>
                      {o.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setLocationModalOpen(false)}>
              취소
            </Button>
            <Button onClick={handleLocationSave} disabled={locationSaving}>
              {locationSaving && (
                <Loader2 className="h-4 w-4 animate-spin mr-1" />
              )}
              {locationEditMode ? "수정하기" : "등록하기"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

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