"use client";

import React, { useState, useMemo, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
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 } from "@/components/ui/dialog";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import { Plus, Trash2, Save, X, ChevronDown, ChevronRight, ChevronLeft, ChevronsLeft, ChevronsRight, Search, Loader2, FileSpreadsheet, Inbox, Settings2 } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  getShippingOrderList,
  saveShippingOrder,
  deleteShippingOrders,
  previewShippingOrderNo,
  getShipmentPlanSource,
  getSalesOrderSource,
  getItemSource,
} from "@/lib/api/shipping";
import { ExcelUploadModal } from "@/components/common/ExcelUploadModal";
import { useTableSettings } from "@/hooks/useTableSettings";
import { TableSettingsModal } from "@/components/common/TableSettingsModal";
import { DynamicSearchFilter, FilterValue } from "@/components/common/DynamicSearchFilter";
import { EDataTable, EDataTableColumn } from "@/components/common/EDataTable";

const GRID_COLUMNS = [
  { key: "instruction_no", label: "출하지시번호" },
  { key: "ship_date", label: "출하일자" },
  { key: "customer_name", label: "거래처명" },
  { key: "transport_company", label: "운송업체" },
  { key: "vehicle_no", label: "차량번호" },
  { key: "driver_name", label: "기사명" },
  { key: "status", label: "상태" },
  { key: "item_code", label: "품번" },
  { key: "item_name", label: "품명" },
  { key: "qty", label: "수량" },
  { key: "source_type", label: "소스" },
  { key: "remark", label: "비고" },
];

type DataSourceType = "shipmentPlan" | "salesOrder" | "itemInfo";

const STATUS_OPTIONS = [
  { value: "all", label: "전체" },
  { value: "READY", label: "준비중" },
  { value: "IN_PROGRESS", label: "진행중" },
  { value: "COMPLETED", label: "완료" },
];

const getStatusLabel = (s: string) => STATUS_OPTIONS.find(o => o.value === s)?.label || s;

const getStatusColor = (s: string) => {
  switch (s) {
    case "READY": return "bg-warning/10 text-warning";
    case "IN_PROGRESS": return "bg-primary/10 text-primary";
    case "COMPLETED": return "bg-success/10 text-success";
    default: return "bg-muted text-muted-foreground";
  }
};

const getSourceBadge = (s: string) => {
  switch (s) {
    case "shipmentPlan": return { label: "출하계획", cls: "bg-primary/10 text-primary" };
    case "salesOrder": return { label: "수주", cls: "bg-success/10 text-success" };
    case "itemInfo": return { label: "품목", cls: "bg-secondary text-secondary-foreground" };
    default: return { label: s, cls: "bg-muted text-muted-foreground" };
  }
};

interface SelectedItem {
  id: string | number;
  itemCode: string;
  itemName: string;
  spec: string;
  material: string;
  customer: string;
  planQty: number;
  orderQty: number;
  sourceType: DataSourceType;
  shipmentPlanId?: number;
  salesOrderId?: number;
  detailId?: string;
  partnerCode?: string;
}

export default function ShippingOrderPage() {
  const ts = useTableSettings("c16-shipping-order", "shipment_instruction", GRID_COLUMNS);
  const [orders, setOrders] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [checkedIds, setCheckedIds] = useState<number[]>([]);
  const [selectedOrderId, setSelectedOrderId] = useState<number | null>(null);

  // 검색 필터 (DynamicSearchFilter에서 관리)
  const [searchFilters, setSearchFilters] = useState<FilterValue[]>([]);

  // 서버 페이징
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [totalCount, setTotalCount] = useState(0);

  // 엑셀 업로드
  const [excelUploadOpen, setExcelUploadOpen] = useState(false);

  // 모달
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isEditMode, setIsEditMode] = useState(false);
  const [editId, setEditId] = useState<number | null>(null);
  const [saving, setSaving] = useState(false);

  // 모달 폼
  const [formOrderNumber, setFormOrderNumber] = useState("");
  const [formOrderDate, setFormOrderDate] = useState("");
  const [formCustomer, setFormCustomer] = useState("");
  const [formPartnerId, setFormPartnerId] = useState("");
  const [formStatus, setFormStatus] = useState("READY");
  const [formCarrier, setFormCarrier] = useState("");
  const [formVehicle, setFormVehicle] = useState("");
  const [formDriver, setFormDriver] = useState("");
  const [formDriverPhone, setFormDriverPhone] = useState("");
  const [formArrival, setFormArrival] = useState("");
  const [formAddress, setFormAddress] = useState("");
  const [formMemo, setFormMemo] = useState("");
  const [isTransportCollapsed, setIsTransportCollapsed] = useState(false);

  // 모달 왼쪽 패널
  const [dataSource, setDataSource] = useState<DataSourceType>("shipmentPlan");
  const [sourceKeyword, setSourceKeyword] = useState("");
  const [sourceData, setSourceData] = useState<any[]>([]);
  const [sourceLoading, setSourceLoading] = useState(false);
  const [selectedItems, setSelectedItems] = useState<SelectedItem[]>([]);
  const [sourcePage, setSourcePage] = useState(1);
  const [sourcePageSize, setSourcePageSize] = useState(20);
  const [sourceTotalCount, setSourceTotalCount] = useState(0);


  // 데이터 조회
  const fetchOrders = useCallback(async () => {
    setLoading(true);
    try {
      const params: any = { page: currentPage, size: pageSize };
      for (const f of searchFilters) {
        if (f.columnName === "ship_date" && f.operator === "between" && f.value) {
          const [from, to] = f.value.split(",");
          if (from) params.dateFrom = from;
          if (to) params.dateTo = to;
        } else if (f.columnName === "status") {
          params.status = f.value;
        } else if (f.columnName === "customer_name") {
          params.customer = f.value;
        } else {
          params.keyword = f.value;
        }
      }

      const result = await getShippingOrderList(params);
      if (result.success) {
        setOrders(result.data || []);
        setTotalCount(result.total ?? result.data?.length ?? 0);
      }
    } catch (err) {
      console.error("출하지시 조회 실패:", err);
    } finally {
      setLoading(false);
    }
  }, [searchFilters, currentPage, pageSize]);

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

  useEffect(() => {
    setCurrentPage(1);
  }, [searchFilters]);

  // 소스 데이터 조회
  const fetchSourceData = useCallback(async (pageOverride?: number) => {
    setSourceLoading(true);
    try {
      const currentPage = pageOverride ?? sourcePage;
      const params: any = { page: currentPage, pageSize: sourcePageSize };
      if (sourceKeyword.trim()) params.keyword = sourceKeyword.trim();

      let result;
      switch (dataSource) {
        case "shipmentPlan":
          result = await getShipmentPlanSource(params);
          break;
        case "salesOrder":
          result = await getSalesOrderSource(params);
          break;
        case "itemInfo":
          result = await getItemSource(params);
          break;
      }
      if (result?.success) {
        setSourceData(result.data || []);
        setSourceTotalCount(result.totalCount || 0);
      }
    } catch (err) {
      console.error("소스 데이터 조회 실패:", err);
    } finally {
      setSourceLoading(false);
    }
  }, [dataSource, sourceKeyword, sourcePage, sourcePageSize]);

  useEffect(() => {
    if (isModalOpen) {
      setSourcePage(1);
      fetchSourceData(1);
    }
  }, [isModalOpen, dataSource]);

  const handleDeleteSelected = async () => {
    if (checkedIds.length === 0) return;
    if (!confirm(`선택한 ${checkedIds.length}개의 출하지시를 삭제하시겠습니까?`)) return;
    try {
      const result = await deleteShippingOrders(checkedIds);
      if (result.success) {
        setCheckedIds([]);
        fetchOrders();
        alert("삭제되었어요.");
      }
    } catch (err: any) {
      alert(err.message || "삭제 실패");
    }
  };

  // 모달 열기
  const openModal = (order?: any) => {
    if (order) {
      setIsEditMode(true);
      setEditId(order.id);
      setFormOrderNumber(order.instruction_no || "");
      setFormOrderDate(order.instruction_date ? order.instruction_date.split("T")[0] : "");
      setFormCustomer(order.customer_name || "");
      setFormPartnerId(order.partner_id || "");
      setFormStatus(order.status || "READY");
      setFormCarrier(order.carrier_name || "");
      setFormVehicle(order.vehicle_no || "");
      setFormDriver(order.driver_name || "");
      setFormDriverPhone(order.driver_contact || "");
      setFormArrival(order.arrival_time ? new Date(order.arrival_time).toLocaleString("sv-SE", { timeZone: "Asia/Seoul" }).replace(" ", "T").slice(0, 16) : "");
      setFormAddress(order.delivery_address || "");
      setFormMemo(order.memo || "");

      const items = order.items || [];
      setSelectedItems(items.filter((it: any) => it.id).map((it: any) => {
        const srcType = it.source_type || "shipmentPlan";
        let sourceId: string | number = it.id;
        if (srcType === "shipmentPlan" && it.shipment_plan_id) sourceId = it.shipment_plan_id;
        else if (srcType === "salesOrder" && it.detail_id) sourceId = it.detail_id;
        else if (srcType === "itemInfo") sourceId = it.item_code || "";

        return {
          id: sourceId,
          itemCode: it.item_code || "",
          itemName: it.item_name || "",
          spec: it.spec || "",
          material: it.material || "",
          customer: order.customer_name || "",
          planQty: Number(it.plan_qty || 0),
          orderQty: Number(it.order_qty || 0),
          sourceType: srcType,
          shipmentPlanId: it.shipment_plan_id,
          salesOrderId: it.sales_order_id,
          detailId: it.detail_id,
          partnerCode: order.partner_id,
        };
      }));
    } else {
      setIsEditMode(false);
      setEditId(null);
      setFormOrderNumber("불러오는 중...");
      setFormOrderDate(new Date().toISOString().split("T")[0]);
      previewShippingOrderNo().then(r => {
        if (r.success) setFormOrderNumber(r.instructionNo);
        else setFormOrderNumber("(자동생성)");
      }).catch(() => setFormOrderNumber("(자동생성)"));
      setFormCustomer("");
      setFormPartnerId("");
      setFormStatus("READY");
      setFormCarrier("");
      setFormVehicle("");
      setFormDriver("");
      setFormDriverPhone("");
      setFormArrival("");
      setFormAddress("");
      setFormMemo("");
      setSelectedItems([]);
    }
    setDataSource("shipmentPlan");
    setSourceKeyword("");
    setSourceData([]);
    setIsTransportCollapsed(false);
    setIsModalOpen(true);
  };

  // 소스 아이템 선택 토글
  const toggleSourceItem = (item: any) => {
    const key = dataSource === "shipmentPlan" ? item.id
      : dataSource === "salesOrder" ? item.id
      : item.item_code;

    const exists = selectedItems.findIndex(s => {
      if (s.sourceType === dataSource) {
        if (dataSource === "itemInfo") return s.itemCode === key;
        return String(s.id) === String(key);
      }
      if (dataSource === "shipmentPlan" && s.shipmentPlanId) return String(s.shipmentPlanId) === String(item.id);
      if (dataSource === "salesOrder" && s.detailId) return String(s.detailId) === String(item.id);
      return false;
    });

    if (exists > -1) {
      setSelectedItems(prev => prev.filter((_, i) => i !== exists));
    } else {
      const newItem: SelectedItem = {
        id: key,
        itemCode: item.item_code || "",
        itemName: item.item_name || "",
        spec: item.spec || "",
        material: item.material || "",
        customer: item.customer_name || "",
        planQty: Number(item.plan_qty || item.qty || item.balance_qty || 0),
        orderQty: Number(item.plan_qty || item.balance_qty || item.qty || 1),
        sourceType: dataSource,
        shipmentPlanId: dataSource === "shipmentPlan" ? item.id : undefined,
        salesOrderId: dataSource === "salesOrder" ? (item.master_id || undefined) : undefined,
        detailId: dataSource === "salesOrder" ? item.id : (dataSource === "shipmentPlan" ? item.detail_id : undefined),
        partnerCode: item.partner_code || "",
      };
      setSelectedItems(prev => [...prev, newItem]);

      if (!formCustomer && item.customer_name) {
        setFormCustomer(item.customer_name);
        setFormPartnerId(item.partner_code || "");
      }
    }
  };

  const removeSelectedItem = (idx: number) => {
    setSelectedItems(prev => prev.filter((_, i) => i !== idx));
  };

  const updateOrderQty = (idx: number, val: number) => {
    setSelectedItems(prev => prev.map((item, i) => i === idx ? { ...item, orderQty: val } : item));
  };

  // 저장
  const handleSave = async () => {
    if (!formOrderDate) { alert("출하지시일을 입력해주세요."); return; }
    if (selectedItems.length === 0) { alert("품목을 선택해주세요."); return; }

    setSaving(true);
    try {
      const payload = {
        id: isEditMode ? editId : undefined,
        instructionDate: formOrderDate,
        partnerId: formPartnerId || formCustomer,
        status: formStatus,
        memo: formMemo,
        carrierName: formCarrier,
        vehicleNo: formVehicle,
        driverName: formDriver,
        driverContact: formDriverPhone,
        arrivalTime: formArrival ? `${formArrival}+09:00` : null,
        deliveryAddress: formAddress,
        items: selectedItems.map(item => ({
          itemCode: item.itemCode,
          itemName: item.itemName,
          spec: item.spec,
          material: item.material,
          orderQty: item.orderQty,
          planQty: item.orderQty,
          shipQty: 0,
          sourceType: item.sourceType,
          shipmentPlanId: item.shipmentPlanId,
          salesOrderId: item.salesOrderId,
          detailId: item.detailId,
        })),
      };

      const result = await saveShippingOrder(payload);
      if (result.success) {
        setIsModalOpen(false);
        fetchOrders();
        alert(isEditMode ? "출하지시가 수정되었어요." : "출하지시가 등록되었어요.");
      } else {
        alert(result.message || "저장 실패");
      }
    } catch (err: any) {
      alert(err.message || "저장 중 오류 발생");
    } finally {
      setSaving(false);
    }
  };

  const formatDate = (d: string) => d ? d.split("T")[0] : "-";

  // 출하지시 데이터를 플랫한 행 목록으로 변환 (EDataTable용)
  const flattenedOrders = useMemo(() => {
    const rows: any[] = [];
    for (const order of orders) {
      const items = Array.isArray(order.items) ? order.items.filter((it: any) => it.id) : [];
      if (items.length === 0) {
        rows.push({
          _rowId: String(order.id),
          _orderId: order.id,
          _order: order,
          instruction_no: order.instruction_no,
          ship_date: formatDate(order.instruction_date),
          customer_name: order.customer_name || "-",
          transport_company: order.carrier_name || "-",
          vehicle_no: order.vehicle_no || "-",
          driver_name: order.driver_name || "-",
          status: order.status,
          item_code: "-",
          item_name: "-",
          qty: 0,
          source_type: "-",
          remark: order.memo || "-",
        });
      } else {
        items.forEach((item: any, idx: number) => {
          rows.push({
            _rowId: `${order.id}-${item.id}`,
            _orderId: order.id,
            _order: order,
            instruction_no: idx === 0 ? order.instruction_no : "",
            ship_date: idx === 0 ? formatDate(order.instruction_date) : "",
            customer_name: idx === 0 ? (order.customer_name || "-") : "",
            transport_company: idx === 0 ? (order.carrier_name || "-") : "",
            vehicle_no: idx === 0 ? (order.vehicle_no || "-") : "",
            driver_name: idx === 0 ? (order.driver_name || "-") : "",
            status: idx === 0 ? order.status : "",
            item_code: item.item_code || "",
            item_name: item.item_name || "",
            qty: Number(item.order_qty || 0),
            source_type: item.source_type || "",
            remark: idx === 0 ? (order.memo || "-") : "",
          });
        });
      }
    }
    return rows;
  }, [orders]);

  // checkedIds를 order.id 기준으로 관리하므로 _orderId로 매핑
  const flatCheckedRowIds = useMemo(() => {
    return flattenedOrders
      .filter((r) => checkedIds.includes(r._orderId))
      .map((r) => r._rowId);
  }, [flattenedOrders, checkedIds]);

  const handleFlatCheckedChange = useCallback((rowIds: string[]) => {
    const orderIds = new Set<number>();
    for (const rowId of rowIds) {
      const row = flattenedOrders.find((r) => r._rowId === rowId);
      if (row) orderIds.add(row._orderId);
    }
    setCheckedIds(Array.from(orderIds));
  }, [flattenedOrders]);

  const dataSourceTitle: Record<DataSourceType, string> = {
    shipmentPlan: "출하계획 목록",
    salesOrder: "수주정보 목록",
    itemInfo: "품목정보 목록",
  };

  return (
    <div className="flex flex-col h-full p-4 gap-3">
      {/* 브레드크럼 */}
      <nav className="flex items-center gap-1.5 text-xs text-muted-foreground shrink-0">
        <span>영업관리</span>
        <span className="text-muted-foreground/40">/</span>
        <span className="font-semibold text-foreground">출하지시</span>
      </nav>

      {/* 검색 필터 (DynamicSearchFilter) */}
      <DynamicSearchFilter
        tableName={ts.tableName}
        filterId="c16-shipping-order"
        onFilterChange={setSearchFilters}
        dataCount={totalCount}
        externalFilterConfig={ts.filterConfig}
      />

      {/* 액션 바 */}
      <div className="flex items-center justify-between flex-wrap gap-3 shrink-0">
        <div className="flex items-center gap-2">
          <h2 className="text-[15px] font-bold text-foreground">출하지시 관리</h2>
          <span className="text-[11px] font-semibold text-primary bg-primary/10 border border-primary/15 px-2 py-0.5 rounded-full font-mono">
            {totalCount}건
          </span>
          {loading && <Loader2 className="w-3.5 h-3.5 animate-spin text-muted-foreground" />}
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={() => setExcelUploadOpen(true)}>
            <FileSpreadsheet className="w-3.5 h-3.5" />
            엑셀 업로드
          </Button>
          <Button size="sm" onClick={() => openModal()}>
            <Plus className="w-3.5 h-3.5" />
            출하지시 등록
          </Button>
          <div className="w-px h-5 bg-border" />
          <Button
            variant="outline"
            size="sm"
            className="text-destructive border-destructive/20 bg-destructive/5 hover:bg-destructive/10"
            disabled={checkedIds.length === 0}
            onClick={handleDeleteSelected}
          >
            <Trash2 className="w-3.5 h-3.5" />
            선택삭제 {checkedIds.length > 0 && `(${checkedIds.length})`}
          </Button>
          <div className="w-px h-5 bg-border" />
          <Button variant="ghost" size="sm" onClick={() => ts.setOpen(true)} title="테이블 설정">
            <Settings2 className="h-4 w-4" />
          </Button>
        </div>
      </div>

      {/* 메인 테이블 */}
      <div className="flex-1 overflow-hidden rounded-lg border bg-card flex flex-col">
        <EDataTable
          columns={ts.visibleColumns.map((col): EDataTableColumn => ({
            key: col.key,
            label: col.label,
            align: col.key === "qty" ? "right" : col.key === "status" || col.key === "source_type" || col.key === "ship_date" ? "center" : undefined,
            formatNumber: col.key === "qty",
            sortable: false,
            filterable: false,
            render: col.key === "status"
              ? (val: any) => val ? (
                  <span className={cn("px-2 py-0.5 rounded-full text-[11px] font-medium", getStatusColor(val))}>
                    {getStatusLabel(val)}
                  </span>
                ) : null
              : col.key === "source_type"
              ? (val: any) => {
                  if (!val || val === "-") return <span>-</span>;
                  const b = getSourceBadge(val);
                  return <span className={cn("px-2 py-0.5 rounded-full text-[10px] font-medium", b.cls)}>{b.label}</span>;
                }
              : undefined,
          }))}
          data={ts.groupData(flattenedOrders)}
          rowKey={(row) => row._rowId}
          loading={loading}
          emptyMessage="등록된 출하지시가 없어요"
          showCheckbox
          checkedIds={flatCheckedRowIds}
          onCheckedChange={handleFlatCheckedChange}
          selectedId={selectedOrderId != null ? String(selectedOrderId) : null}
          onRowClick={(row) => setSelectedOrderId(row._orderId)}
          onRowDoubleClick={(row) => openModal(row._order)}
          showPagination
          serverPagination
          serverCurrentPage={currentPage}
          serverPageSize={pageSize}
          serverTotalCount={totalCount}
          onServerPageChange={setCurrentPage}
          onServerPageSizeChange={(s) => { setPageSize(s); setCurrentPage(1); }}
          defaultPageSize={pageSize}
          draggableColumns={false}
          columnOrderKey="c16-shipping-order"
        />
      </div>

      {/* 등록/수정 모달 */}
      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
        <DialogContent className="max-w-[90vw] w-[1400px] h-[90vh] flex flex-col overflow-hidden p-0 gap-0">
          <DialogHeader className="px-4 py-3 border-b shrink-0">
            <DialogTitle className="text-[15px] font-bold">
              {isEditMode ? "출하지시 수정" : "출하지시 등록"}
            </DialogTitle>
            <DialogDescription className="text-xs text-muted-foreground mt-0.5">
              {isEditMode ? "출하지시 정보를 수정해요." : "왼쪽에서 데이터를 선택하고 오른쪽에서 출하지시 정보를 입력해요."}
            </DialogDescription>
          </DialogHeader>

          <div className="flex-1 overflow-hidden">
            <ResizablePanelGroup direction="horizontal">
              {/* 왼쪽: 데이터 소스 */}
              <ResizablePanel defaultSize={55} minSize={30}>
                <div className="flex flex-col h-full">
                  {/* 소스 검색 헤더 */}
                  <div className="px-4 py-2 border-b bg-muted/50 flex flex-wrap items-center gap-2 shrink-0">
                    <Select value={dataSource} onValueChange={(v) => setDataSource(v as DataSourceType)}>
                      <SelectTrigger className="w-[120px] h-9 text-xs"><SelectValue /></SelectTrigger>
                      <SelectContent>
                        <SelectItem value="shipmentPlan">출하계획</SelectItem>
                        <SelectItem value="salesOrder">수주정보</SelectItem>
                        <SelectItem value="itemInfo">품목정보</SelectItem>
                      </SelectContent>
                    </Select>
                    <Input
                      placeholder="품번, 품명 검색"
                      className="flex-1 h-9 text-xs min-w-[120px]"
                      value={sourceKeyword}
                      onChange={(e) => setSourceKeyword(e.target.value)}
                      onKeyDown={(e) => {
                        if (e.key === "Enter") { setSourcePage(1); fetchSourceData(1); }
                      }}
                    />
                    <Button
                      size="sm"
                      className="h-8 text-xs"
                      onClick={() => { setSourcePage(1); fetchSourceData(1); }}
                      disabled={sourceLoading}
                    >
                      {sourceLoading ? <Loader2 className="w-3 h-3 animate-spin" /> : <Search className="w-3 h-3" />}
                      <span className="ml-1">조회</span>
                    </Button>
                  </div>

                  {/* 소스 서브 헤더 */}
                  <div className="px-3 py-1.5 flex items-center gap-2 border-b bg-muted/30 shrink-0">
                    <span className="text-[13px] font-bold text-foreground">{dataSourceTitle[dataSource]}</span>
                    <span className="text-[11px] font-semibold text-primary bg-primary/10 border border-primary/15 px-2 py-0.5 rounded-full font-mono">
                      선택 {selectedItems.length}개
                    </span>
                  </div>

                  {/* 소스 테이블 */}
                  <div className="flex-1 overflow-auto">
                    {sourceLoading ? (
                      <div className="flex items-center justify-center py-12">
                        <Loader2 className="w-5 h-5 animate-spin text-muted-foreground" />
                      </div>
                    ) : sourceData.length === 0 ? (
                      <div className="flex flex-col items-center justify-center py-12 text-muted-foreground gap-2">
                        <div className="w-12 h-12 rounded-full border-2 border-dashed border-muted-foreground/20 flex items-center justify-center">
                          <Search className="w-5 h-5 text-muted-foreground/30" />
                        </div>
                        <p className="text-sm">조회 버튼을 눌러 데이터를 불러와주세요</p>
                      </div>
                    ) : (
                      <Table>
                        <TableHeader className="sticky top-0 z-10">
                          <TableRow className="bg-muted hover:bg-muted">
                            <TableHead className="w-[40px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">선택</TableHead>
                            <TableHead className="w-[100px] 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-[100px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">규격</TableHead>
                            <TableHead className="w-[100px] text-[11px] font-bold uppercase tracking-wide text-muted-foreground">거래처</TableHead>
                            <TableHead className="w-[70px] text-right text-[11px] font-bold uppercase tracking-wide text-muted-foreground">수량</TableHead>
                            {dataSource === "shipmentPlan" && <TableHead className="w-[70px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">상태</TableHead>}
                          </TableRow>
                        </TableHeader>
                        <TableBody>
                          {sourceData.map((item: any, idx: number) => {
                            const itemId = dataSource === "itemInfo" ? item.item_code : item.id;
                            const isSelected = selectedItems.some(s => {
                              if (s.sourceType === dataSource) {
                                if (dataSource === "itemInfo") return s.itemCode === itemId;
                                return String(s.id) === String(itemId);
                              }
                              if (dataSource === "shipmentPlan" && s.shipmentPlanId) return String(s.shipmentPlanId) === String(item.id);
                              if (dataSource === "salesOrder" && s.detailId) return String(s.detailId) === String(item.id);
                              return false;
                            });
                            return (
                              <TableRow
                                key={`${dataSource}-${itemId}-${idx}`}
                                className={cn("cursor-pointer transition-colors", isSelected && "bg-primary/5")}
                                onClick={() => toggleSourceItem(item)}
                              >
                                <TableCell className="text-center" onClick={e => e.stopPropagation()}>
                                  <Checkbox checked={isSelected} onCheckedChange={() => toggleSourceItem(item)} />
                                </TableCell>
                                <TableCell className="text-[13px]">{item.item_code || "-"}</TableCell>
                                <TableCell className="text-sm font-medium">{item.item_name || "-"}</TableCell>
                                <TableCell className="text-[13px] text-muted-foreground">{item.spec || "-"}</TableCell>
                                <TableCell className="text-[13px]">{item.customer_name || "-"}</TableCell>
                                <TableCell className="text-right text-[13px]">
                                  {Number(item.plan_qty || item.qty || item.balance_qty || 0).toLocaleString()}
                                </TableCell>
                                {dataSource === "shipmentPlan" && (
                                  <TableCell className="text-center">
                                    <span className={cn("px-2 py-0.5 rounded-full text-[10px] font-medium", getStatusColor(item.status))}>
                                      {getStatusLabel(item.status)}
                                    </span>
                                  </TableCell>
                                )}
                              </TableRow>
                            );
                          })}
                        </TableBody>
                      </Table>
                    )}
                  </div>

                  {/* 페이징 */}
                  {sourceTotalCount > 0 && (
                    <div className="px-3 py-1.5 border-t bg-muted/30 flex items-center justify-between shrink-0">
                      <div className="flex items-center gap-2">
                        <span className="text-muted-foreground text-[11px]">표시:</span>
                        <Input
                          type="number"
                          min={1}
                          max={500}
                          value={sourcePageSize}
                          onChange={(e) => {
                            const v = parseInt(e.target.value, 10);
                            if (v > 0) { setSourcePageSize(v); setSourcePage(1); fetchSourceData(1); }
                          }}
                          className="h-7 w-[60px] text-center text-[11px]"
                        />
                        <span className="text-muted-foreground text-[11px]">총 {sourceTotalCount}건</span>
                      </div>
                      <div className="flex items-center gap-1">
                        <Button variant="outline" size="icon" className="h-7 w-7" disabled={sourcePage <= 1}
                          onClick={() => { setSourcePage(1); fetchSourceData(1); }}>
                          <ChevronsLeft className="w-3.5 h-3.5" />
                        </Button>
                        <Button variant="outline" size="icon" className="h-7 w-7" disabled={sourcePage <= 1}
                          onClick={() => { const p = sourcePage - 1; setSourcePage(p); fetchSourceData(p); }}>
                          <ChevronLeft className="w-3.5 h-3.5" />
                        </Button>
                        <span className="text-xs font-medium px-2">
                          {sourcePage} / {Math.max(1, Math.ceil(sourceTotalCount / sourcePageSize))}
                        </span>
                        <Button variant="outline" size="icon" className="h-7 w-7"
                          disabled={sourcePage >= Math.ceil(sourceTotalCount / sourcePageSize)}
                          onClick={() => { const p = sourcePage + 1; setSourcePage(p); fetchSourceData(p); }}>
                          <ChevronRight className="w-3.5 h-3.5" />
                        </Button>
                        <Button variant="outline" size="icon" className="h-7 w-7"
                          disabled={sourcePage >= Math.ceil(sourceTotalCount / sourcePageSize)}
                          onClick={() => { const p = Math.ceil(sourceTotalCount / sourcePageSize); setSourcePage(p); fetchSourceData(p); }}>
                          <ChevronsRight className="w-3.5 h-3.5" />
                        </Button>
                      </div>
                    </div>
                  )}
                </div>
              </ResizablePanel>

              <ResizableHandle withHandle onPointerDown={(e) => e.stopPropagation()} />

              {/* 오른쪽: 폼 */}
              <ResizablePanel defaultSize={45} minSize={30}>
                <div className="flex flex-col h-full overflow-auto p-4 gap-4">
                  {/* 기본 정보 */}
                  <div className="border rounded-lg p-4 shrink-0">
                    <p className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wide mb-3">기본 정보</p>
                    <div className="grid grid-cols-2 gap-3">
                      <div className="space-y-1">
                        <Label className="text-[11px] font-semibold text-muted-foreground">출하지시번호</Label>
                        <Input value={formOrderNumber} readOnly className="h-9 bg-muted/50 text-muted-foreground" />
                      </div>
                      <div className="space-y-1">
                        <Label className="text-[11px] font-semibold text-muted-foreground">
                          출하지시일 <span className="text-destructive">*</span>
                        </Label>
                        <Input
                          type="date"
                          className="h-9"
                          value={formOrderDate}
                          onChange={(e) => setFormOrderDate(e.target.value)}
                        />
                      </div>
                      <div className="space-y-1">
                        <Label className="text-[11px] font-semibold text-muted-foreground">거래처</Label>
                        <Input value={formCustomer} readOnly placeholder="품목 선택 시 자동" className="h-9 bg-muted/50" />
                      </div>
                      <div className="space-y-1">
                        <Label className="text-[11px] font-semibold text-muted-foreground">상태</Label>
                        <Select value={formStatus} onValueChange={setFormStatus}>
                          <SelectTrigger className="h-9"><SelectValue /></SelectTrigger>
                          <SelectContent>
                            <SelectItem value="READY">준비중</SelectItem>
                            <SelectItem value="IN_PROGRESS">진행중</SelectItem>
                            <SelectItem value="COMPLETED">완료</SelectItem>
                          </SelectContent>
                        </Select>
                      </div>
                    </div>
                  </div>

                  {/* 운송 정보 */}
                  <div className="bg-muted/50 border rounded-lg overflow-hidden shrink-0">
                    <button
                      className="w-full px-4 py-2.5 flex items-center justify-between text-left"
                      onClick={() => setIsTransportCollapsed(!isTransportCollapsed)}
                    >
                      <p className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wide flex items-center gap-2">
                        운송 정보 <span className="text-[10px] font-normal">(선택사항)</span>
                      </p>
                      {isTransportCollapsed
                        ? <ChevronRight className="w-3.5 h-3.5 text-muted-foreground" />
                        : <ChevronDown className="w-3.5 h-3.5 text-muted-foreground" />
                      }
                    </button>
                    {!isTransportCollapsed && (
                      <div className="px-4 pb-3 grid grid-cols-3 gap-3">
                        <div className="space-y-1">
                          <Label className="text-[11px] font-semibold text-muted-foreground">운송업체</Label>
                          <Input value={formCarrier} onChange={(e) => setFormCarrier(e.target.value)} className="h-9" />
                        </div>
                        <div className="space-y-1">
                          <Label className="text-[11px] font-semibold text-muted-foreground">차량번호</Label>
                          <Input value={formVehicle} onChange={(e) => setFormVehicle(e.target.value)} className="h-9" />
                        </div>
                        <div className="space-y-1">
                          <Label className="text-[11px] font-semibold text-muted-foreground">기사명</Label>
                          <Input value={formDriver} onChange={(e) => setFormDriver(e.target.value)} className="h-9" />
                        </div>
                        <div className="space-y-1">
                          <Label className="text-[11px] font-semibold text-muted-foreground">연락처</Label>
                          <Input value={formDriverPhone} onChange={(e) => setFormDriverPhone(e.target.value)} className="h-9" />
                        </div>
                        <div className="space-y-1">
                          <Label className="text-[11px] font-semibold text-muted-foreground">도착예정일시</Label>
                          <Input
                            type="datetime-local"
                            className="h-9"
                            value={formArrival}
                            onChange={(e) => setFormArrival(e.target.value)}
                          />
                        </div>
                        <div className="space-y-1">
                          <Label className="text-[11px] font-semibold text-muted-foreground">배송지</Label>
                          <Input value={formAddress} onChange={(e) => setFormAddress(e.target.value)} className="h-9" />
                        </div>
                      </div>
                    )}
                  </div>

                  {/* 선택된 품목 */}
                  <div className="border rounded-lg p-4 flex-1 flex flex-col min-h-[200px]">
                    <p className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wide mb-2 flex items-center gap-2">
                      선택된 품목
                      <span className="text-[11px] font-semibold text-primary bg-primary/10 border border-primary/15 px-2 py-0.5 rounded-full font-mono">
                        {selectedItems.length}
                      </span>
                    </p>
                    <div className="flex-1 overflow-auto min-h-0">
                      {selectedItems.length === 0 ? (
                        <div className="flex flex-col items-center justify-center py-8 text-muted-foreground border-2 border-dashed rounded-lg gap-2">
                          <div className="w-10 h-10 rounded-full border-2 border-dashed border-muted-foreground/20 flex items-center justify-center">
                            <Inbox className="w-4 h-4 text-muted-foreground/30" />
                          </div>
                          <p className="text-sm">왼쪽에서 데이터를 선택해주세요</p>
                        </div>
                      ) : (
                        <Table>
                          <TableHeader className="sticky top-0 z-10">
                            <TableRow className="bg-muted hover:bg-muted">
                              <TableHead className="w-[40px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">소스</TableHead>
                              <TableHead className="w-[90px] 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-[90px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">출하수량</TableHead>
                              <TableHead className="w-[70px] text-right text-[11px] font-bold uppercase tracking-wide text-muted-foreground">계획수량</TableHead>
                              <TableHead className="w-[40px] text-center text-[11px] font-bold uppercase tracking-wide text-muted-foreground">삭제</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {selectedItems.map((item, idx) => {
                              const b = getSourceBadge(item.sourceType);
                              return (
                                <TableRow key={`${item.sourceType}-${item.id}-${idx}`}>
                                  <TableCell className="text-center">
                                    <span className={cn("px-1.5 py-0.5 rounded text-[10px] font-medium", b.cls)}>
                                      {b.label.charAt(0)}
                                    </span>
                                  </TableCell>
                                  <TableCell className="text-[13px]">{item.itemCode}</TableCell>
                                  <TableCell className="text-sm font-medium">{item.itemName}</TableCell>
                                  <TableCell className="text-center">
                                    <Input
                                      type="number"
                                      value={item.orderQty}
                                      onChange={(e) => updateOrderQty(idx, parseInt(e.target.value) || 0)}
                                      min={1}
                                      className="h-7 w-[70px] text-xs text-right mx-auto"
                                    />
                                  </TableCell>
                                  <TableCell className="text-right text-[13px]">
                                    {item.planQty ? item.planQty.toLocaleString() : "-"}
                                  </TableCell>
                                  <TableCell className="text-center">
                                    <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => removeSelectedItem(idx)}>
                                      <X className="w-3.5 h-3.5 text-destructive" />
                                    </Button>
                                  </TableCell>
                                </TableRow>
                              );
                            })}
                          </TableBody>
                        </Table>
                      )}
                    </div>
                  </div>

                  {/* 메모 */}
                  <div className="border rounded-lg p-4 shrink-0">
                    <p className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wide mb-2">메모</p>
                    <Textarea
                      value={formMemo}
                      onChange={(e) => setFormMemo(e.target.value)}
                      placeholder="출하지시 관련 메모를 입력해주세요"
                      rows={2}
                      className="resize-y"
                    />
                  </div>
                </div>
              </ResizablePanel>
            </ResizablePanelGroup>
          </div>

          {/* 모달 하단 버튼 */}
          <div className="flex items-center justify-end gap-2 px-4 py-3 border-t shrink-0">
            <Button variant="outline" onClick={() => setIsModalOpen(false)}>취소</Button>
            <Button onClick={handleSave} disabled={saving}>
              {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
              저장
            </Button>
          </div>
        </DialogContent>
      </Dialog>

      {/* 엑셀 업로드 모달 */}
      <ExcelUploadModal
        open={excelUploadOpen}
        onOpenChange={setExcelUploadOpen}
        tableName="shipping-order"
        onSuccess={() => { fetchOrders(); }}
      />

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