"use client";

import React, { useState, useMemo, useEffect, useCallback, useRef } 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 { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import { Plus, Trash2, RotateCcw, Save, X, ChevronDown, ChevronRight, ChevronLeft, Truck, Search, Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { FormDatePicker } from "@/components/screen/filters/FormDatePicker";
import {
  getShippingOrderList,
  saveShippingOrder,
  deleteShippingOrders,
  previewShippingOrderNo,
  getShipmentPlanSource,
  getSalesOrderSource,
  getItemSource,
} from "@/lib/api/shipping";

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-amber-100 text-amber-800 border-amber-200";
    case "IN_PROGRESS": return "bg-blue-100 text-blue-800 border-blue-200";
    case "COMPLETED": return "bg-emerald-100 text-emerald-800 border-emerald-200";
    default: return "bg-gray-100 text-gray-800 border-gray-200";
  }
};

const getSourceBadge = (s: string) => {
  switch (s) {
    case "shipmentPlan": return { label: "출하계획", cls: "bg-blue-100 text-blue-700" };
    case "salesOrder": return { label: "수주", cls: "bg-emerald-100 text-emerald-700" };
    case "itemInfo": return { label: "품목", cls: "bg-purple-100 text-purple-700" };
    default: return { label: s, cls: "bg-gray-100 text-gray-700" };
  }
};

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 [orders, setOrders] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [checkedIds, setCheckedIds] = useState<number[]>([]);

  // 검색
  const [searchKeyword, setSearchKeyword] = useState("");
  const [searchCustomer, setSearchCustomer] = useState("");
  const [debouncedKeyword, setDebouncedKeyword] = useState("");
  const [debouncedCustomer, setDebouncedCustomer] = useState("");
  const [searchStatus, setSearchStatus] = useState("all");
  const [searchDateFrom, setSearchDateFrom] = useState("");
  const [searchDateTo, setSearchDateTo] = useState("");

  // 모달
  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] = useState(20);
  const [sourceTotalCount, setSourceTotalCount] = useState(0);

  // 텍스트 입력 debounce (500ms)
  useEffect(() => {
    const t = setTimeout(() => setDebouncedKeyword(searchKeyword), 500);
    return () => clearTimeout(t);
  }, [searchKeyword]);

  useEffect(() => {
    const t = setTimeout(() => setDebouncedCustomer(searchCustomer), 500);
    return () => clearTimeout(t);
  }, [searchCustomer]);

  // 초기 날짜
  useEffect(() => {
    const today = new Date();
    const from = new Date(today);
    from.setMonth(from.getMonth() - 1);
    setSearchDateFrom(from.toISOString().split("T")[0]);
    setSearchDateTo(today.toISOString().split("T")[0]);
  }, []);

  // 데이터 조회
  const fetchOrders = useCallback(async () => {
    setLoading(true);
    try {
      const params: any = {};
      if (searchDateFrom) params.dateFrom = searchDateFrom;
      if (searchDateTo) params.dateTo = searchDateTo;
      if (searchStatus !== "all") params.status = searchStatus;
      if (debouncedCustomer.trim()) params.customer = debouncedCustomer.trim();
      if (debouncedKeyword.trim()) params.keyword = debouncedKeyword.trim();

      const result = await getShippingOrderList(params);
      if (result.success) setOrders(result.data || []);
    } catch (err) {
      console.error("출하지시 조회 실패:", err);
    } finally {
      setLoading(false);
    }
  }, [searchDateFrom, searchDateTo, searchStatus, debouncedCustomer, debouncedKeyword]);

  useEffect(() => {
    if (searchDateFrom && searchDateTo) fetchOrders();
  }, [fetchOrders]);

  // 소스 데이터 조회
  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 handleResetSearch = () => {
    setSearchKeyword("");
    setSearchCustomer("");
    setDebouncedKeyword("");
    setDebouncedCustomer("");
    setSearchStatus("all");
    const today = new Date();
    const from = new Date(today);
    from.setMonth(from.getMonth() - 1);
    setSearchDateFrom(from.toISOString().split("T")[0]);
    setSearchDateTo(today.toISOString().split("T")[0]);
  };

  const handleCheckAll = (checked: boolean) => {
    setCheckedIds(checked ? orders.map((o: any) => o.id) : []);
  };

  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";
        // 소스 데이터와 매칭할 수 있도록 원래 소스 id를 사용
        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 => {
      // 같은 소스 타입에서 id 매칭
      if (s.sourceType === dataSource) {
        if (dataSource === "itemInfo") return s.itemCode === key;
        return String(s.id) === String(key);
      }
      // 다른 소스 타입이라도 원래 소스 id로 매칭
      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.planQty,
          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] : "-";

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

  return (
    <div className="flex flex-col h-[calc(100vh-4rem)] bg-muted/30 p-4 gap-4">
      {/* 검색 */}
      <Card className="shrink-0">
        <CardContent className="p-4 flex flex-wrap items-end gap-4">
          <div className="space-y-1.5">
            <Label className="text-xs text-muted-foreground">출하지시번호</Label>
            <Input placeholder="검색" className="w-[160px] h-9" value={searchKeyword}
              onChange={(e) => setSearchKeyword(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && handleSearch()} />
          </div>
          <div className="space-y-1.5">
            <Label className="text-xs text-muted-foreground">거래처</Label>
            <Input placeholder="거래처 검색" className="w-[140px] h-9" value={searchCustomer}
              onChange={(e) => setSearchCustomer(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && handleSearch()} />
          </div>
          <div className="space-y-1.5">
            <Label className="text-xs text-muted-foreground">상태</Label>
            <Select value={searchStatus} onValueChange={setSearchStatus}>
              <SelectTrigger className="w-[110px] h-9"><SelectValue placeholder="전체" /></SelectTrigger>
              <SelectContent>
                {STATUS_OPTIONS.map(o => <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>)}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label className="text-xs text-muted-foreground">출하일자</Label>
            <div className="flex items-center gap-2">
              <div className="w-[160px]">
                <FormDatePicker value={searchDateFrom} onChange={setSearchDateFrom} placeholder="시작일" />
              </div>
              <span className="text-muted-foreground">~</span>
              <div className="w-[160px]">
                <FormDatePicker value={searchDateTo} onChange={setSearchDateTo} placeholder="종료일" />
              </div>
            </div>
          </div>
          <div className="flex-1" />
          <div className="flex items-center gap-2">
            {loading && <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />}
            <Button variant="outline" size="sm" className="h-9" onClick={handleResetSearch}>
              <RotateCcw className="w-4 h-4 mr-2" /> 초기화
            </Button>
          </div>
        </CardContent>
      </Card>

      {/* 메인 테이블 */}
      <div className="flex-1 overflow-hidden border rounded-lg bg-background shadow-sm flex flex-col">
        <div className="flex items-center justify-between p-3 border-b bg-muted/10 shrink-0">
          <div className="font-semibold flex items-center gap-2 text-sm">
            <Truck className="w-5 h-5" /> 출하지시 관리
            <Badge variant="secondary" className="font-normal">{orders.length}건</Badge>
          </div>
          <div className="flex items-center gap-2">
            <Button size="sm" onClick={() => openModal()}>
              <Plus className="w-4 h-4 mr-1.5" /> 출하지시 등록
            </Button>
            <Button variant="destructive" size="sm" disabled={checkedIds.length === 0} onClick={handleDeleteSelected}>
              <Trash2 className="w-4 h-4 mr-1.5" /> 선택삭제 {checkedIds.length > 0 && `(${checkedIds.length})`}
            </Button>
          </div>
        </div>

        <div className="flex-1 overflow-auto">
          {loading ? (
            <div className="flex items-center justify-center h-32">
              <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
            </div>
          ) : (
            <Table>
              <TableHeader className="sticky top-0 bg-background z-10 shadow-sm">
                <TableRow>
                  <TableHead className="w-[40px] text-center">
                    <Checkbox checked={orders.length > 0 && checkedIds.length === orders.length} onCheckedChange={handleCheckAll} />
                  </TableHead>
                  <TableHead className="w-[140px]">출하지시번호</TableHead>
                  <TableHead className="w-[100px] text-center">출하일자</TableHead>
                  <TableHead className="w-[120px]">거래처명</TableHead>
                  <TableHead className="w-[100px]">운송업체</TableHead>
                  <TableHead className="w-[90px]">차량번호</TableHead>
                  <TableHead className="w-[80px]">기사명</TableHead>
                  <TableHead className="w-[80px] text-center">상태</TableHead>
                  <TableHead className="w-[100px]">품번</TableHead>
                  <TableHead className="w-[130px]">품명</TableHead>
                  <TableHead className="w-[70px] text-right">수량</TableHead>
                  <TableHead className="w-[80px] text-center">소스</TableHead>
                  <TableHead>비고</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {orders.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={13} className="h-40 text-center text-muted-foreground">
                      <div className="flex flex-col items-center gap-2">
                        <Truck className="w-12 h-12 text-muted-foreground/30" />
                        <div className="font-medium">등록된 출하지시가 없습니다</div>
                        <div className="text-sm">출하지시 등록 버튼으로 등록하세요</div>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : (
                  orders.map((order: any) => {
                    const items = Array.isArray(order.items) ? order.items.filter((it: any) => it.id) : [];
                    if (items.length === 0) {
                      return (
                        <TableRow key={order.id} className="cursor-pointer hover:bg-muted/50" onClick={() => openModal(order)}>
                          <TableCell className="text-center" onClick={e => e.stopPropagation()}>
                            <Checkbox checked={checkedIds.includes(order.id)} onCheckedChange={(c) => {
                              if (c) setCheckedIds(p => [...p, order.id]);
                              else setCheckedIds(p => p.filter(i => i !== order.id));
                            }} />
                          </TableCell>
                          <TableCell className="font-medium">{order.instruction_no}</TableCell>
                          <TableCell className="text-center">{formatDate(order.instruction_date)}</TableCell>
                          <TableCell>{order.customer_name || "-"}</TableCell>
                          <TableCell>{order.carrier_name || "-"}</TableCell>
                          <TableCell>{order.vehicle_no || "-"}</TableCell>
                          <TableCell>{order.driver_name || "-"}</TableCell>
                          <TableCell className="text-center">
                            <span className={cn("px-2 py-1 rounded-full text-[11px] font-medium border", getStatusColor(order.status))}>{getStatusLabel(order.status)}</span>
                          </TableCell>
                          <TableCell>-</TableCell>
                          <TableCell>-</TableCell>
                          <TableCell className="text-right">0</TableCell>
                          <TableCell className="text-center">-</TableCell>
                          <TableCell className="text-xs text-muted-foreground truncate max-w-[100px]">{order.memo || "-"}</TableCell>
                        </TableRow>
                      );
                    }
                    return items.map((item: any, itemIdx: number) => (
                      <TableRow key={`${order.id}-${item.id}`} className="cursor-pointer hover:bg-muted/50" onClick={() => openModal(order)}>
                        <TableCell className="text-center" onClick={e => e.stopPropagation()}>
                          {itemIdx === 0 && <Checkbox checked={checkedIds.includes(order.id)} onCheckedChange={(c) => {
                            if (c) setCheckedIds(p => [...p, order.id]);
                            else setCheckedIds(p => p.filter(i => i !== order.id));
                          }} />}
                        </TableCell>
                        <TableCell className="font-medium">{itemIdx === 0 ? order.instruction_no : ""}</TableCell>
                        <TableCell className="text-center">{itemIdx === 0 ? formatDate(order.instruction_date) : ""}</TableCell>
                        <TableCell>{itemIdx === 0 ? (order.customer_name || "-") : ""}</TableCell>
                        <TableCell>{itemIdx === 0 ? (order.carrier_name || "-") : ""}</TableCell>
                        <TableCell>{itemIdx === 0 ? (order.vehicle_no || "-") : ""}</TableCell>
                        <TableCell>{itemIdx === 0 ? (order.driver_name || "-") : ""}</TableCell>
                        <TableCell className="text-center">
                          {itemIdx === 0 && <span className={cn("px-2 py-1 rounded-full text-[11px] font-medium border", getStatusColor(order.status))}>{getStatusLabel(order.status)}</span>}
                        </TableCell>
                        <TableCell className="text-xs text-muted-foreground">{item.item_code}</TableCell>
                        <TableCell className="font-medium text-sm">{item.item_name}</TableCell>
                        <TableCell className="text-right">{Number(item.order_qty || 0).toLocaleString()}</TableCell>
                        <TableCell className="text-center">
                          {(() => { const b = getSourceBadge(item.source_type || ""); return <span className={cn("px-2 py-0.5 rounded-full text-[10px]", b.cls)}>{b.label}</span>; })()}
                        </TableCell>
                        <TableCell className="text-xs text-muted-foreground truncate max-w-[100px]">{itemIdx === 0 ? (order.memo || "-") : ""}</TableCell>
                      </TableRow>
                    ));
                  })
                )}
              </TableBody>
            </Table>
          )}
        </div>
      </div>

      {/* 등록/수정 모달 */}
      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
        <DialogContent className="max-w-[90vw] max-h-[90vh] w-[1400px] p-0 flex flex-col overflow-hidden">
          <DialogHeader className="p-5 pb-4 border-b bg-primary text-primary-foreground shrink-0">
            <DialogTitle className="text-lg">{isEditMode ? "출하지시 수정" : "출하지시 등록"}</DialogTitle>
            <DialogDescription className="text-primary-foreground/70">
              {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="p-3 border-b bg-muted/30 flex flex-wrap items-center gap-2 shrink-0">
                    <Select value={dataSource} onValueChange={(v) => setDataSource(v as DataSourceType)}>
                      <SelectTrigger className="w-[130px] h-8 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-8 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-4 py-2 flex items-center justify-between border-b shrink-0">
                    <div className="text-sm font-medium">
                      {dataSourceTitle[dataSource]}
                      <span className="text-muted-foreground ml-2 font-normal">
                        선택: <span className="text-primary font-semibold">{selectedItems.length}</span>개
                      </span>
                    </div>
                  </div>

                  <div className="flex-1 overflow-auto">
                    {sourceLoading ? (
                      <div className="flex items-center justify-center py-12"><Loader2 className="w-6 h-6 animate-spin text-muted-foreground" /></div>
                    ) : sourceData.length === 0 ? (
                      <div className="flex flex-col items-center justify-center py-12 text-muted-foreground">
                        <div className="text-sm">조회 버튼을 눌러 데이터를 불러오세요</div>
                      </div>
                    ) : (
                      <Table>
                        <TableHeader className="sticky top-0 bg-background z-10">
                          <TableRow>
                            <TableHead className="w-[40px] text-center">선택</TableHead>
                            <TableHead className="w-[100px]">품번</TableHead>
                            <TableHead>품명</TableHead>
                            <TableHead className="w-[100px]">규격</TableHead>
                            <TableHead className="w-[100px]">거래처</TableHead>
                            <TableHead className="w-[70px] text-right">수량</TableHead>
                            {dataSource === "shipmentPlan" && <TableHead className="w-[70px] text-center">상태</TableHead>}
                          </TableRow>
                        </TableHeader>
                        <TableBody>
                          {sourceData.map((item: any, idx: number) => {
                            const itemId = dataSource === "itemInfo" ? item.item_code : item.id;
                            const isSelected = selectedItems.some(s => {
                              // 같은 소스 타입에서 id 매칭
                              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 hover:bg-muted/50", 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-xs">{item.item_code || "-"}</TableCell>
                                <TableCell className="text-sm font-medium">{item.item_name || "-"}</TableCell>
                                <TableCell className="text-xs text-muted-foreground">{item.spec || "-"}</TableCell>
                                <TableCell className="text-xs">{item.customer_name || "-"}</TableCell>
                                <TableCell className="text-right text-xs">{Number(item.plan_qty || item.qty || item.balance_qty || 0).toLocaleString()}</TableCell>
                                {dataSource === "shipmentPlan" && (
                                  <TableCell className="text-center">
                                    <Badge variant="secondary" className="text-[10px]">{getStatusLabel(item.status)}</Badge>
                                  </TableCell>
                                )}
                              </TableRow>
                            );
                          })}
                        </TableBody>
                      </Table>
                    )}
                  </div>

                  {/* 페이징 */}
                  {sourceTotalCount > 0 && (
                    <div className="px-4 py-2 border-t bg-muted/10 flex items-center justify-between shrink-0">
                      <span className="text-xs text-muted-foreground">
                        총 {sourceTotalCount}건 중 {(sourcePage - 1) * sourcePageSize + 1}-{Math.min(sourcePage * sourcePageSize, sourceTotalCount)}건
                      </span>
                      <div className="flex items-center gap-1">
                        <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>
                      </div>
                    </div>
                  )}
                </div>
              </ResizablePanel>

              <ResizableHandle withHandle />

              {/* 오른쪽: 폼 */}
              <ResizablePanel defaultSize={45} minSize={30}>
                <div className="flex flex-col h-full overflow-auto p-5 bg-muted/20 gap-5">
                  {/* 기본 정보 */}
                  <div className="bg-background border rounded-lg p-5 shrink-0">
                    <h3 className="text-sm font-semibold mb-4">기본 정보</h3>
                    <div className="grid grid-cols-2 gap-4">
                      <div className="space-y-1.5">
                        <Label className="text-xs">출하지시번호</Label>
                        <Input value={formOrderNumber} readOnly className="h-9 bg-muted/50 text-muted-foreground" />
                      </div>
                      <div className="space-y-1.5">
                        <Label className="text-xs">출하지시일 <span className="text-destructive">*</span></Label>
                        <FormDatePicker value={formOrderDate} onChange={setFormOrderDate} placeholder="날짜 선택" />
                      </div>
                      <div className="space-y-1.5">
                        <Label className="text-xs">거래처</Label>
                        <Input value={formCustomer} readOnly placeholder="품목 선택 시 자동" className="h-9 bg-muted/50" />
                      </div>
                      <div className="space-y-1.5">
                        <Label className="text-xs">상태</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-amber-50 border border-amber-200 rounded-lg overflow-hidden shrink-0">
                    <button className="w-full px-5 py-3 flex items-center justify-between text-left" onClick={() => setIsTransportCollapsed(!isTransportCollapsed)}>
                      <h3 className="text-sm font-semibold text-amber-900 flex items-center gap-2">
                        <Truck className="w-4 h-4" /> 운송 정보 <span className="text-[11px] font-normal text-muted-foreground">(선택사항)</span>
                      </h3>
                      {isTransportCollapsed ? <ChevronRight className="w-4 h-4 text-amber-700" /> : <ChevronDown className="w-4 h-4 text-amber-700" />}
                    </button>
                    {!isTransportCollapsed && (
                      <div className="px-5 pb-4 grid grid-cols-3 gap-3">
                        <div className="space-y-1.5"><Label className="text-xs">운송업체</Label><Input value={formCarrier} onChange={(e) => setFormCarrier(e.target.value)} className="h-9" /></div>
                        <div className="space-y-1.5"><Label className="text-xs">차량번호</Label><Input value={formVehicle} onChange={(e) => setFormVehicle(e.target.value)} className="h-9" /></div>
                        <div className="space-y-1.5"><Label className="text-xs">기사명</Label><Input value={formDriver} onChange={(e) => setFormDriver(e.target.value)} className="h-9" /></div>
                        <div className="space-y-1.5"><Label className="text-xs">연락처</Label><Input value={formDriverPhone} onChange={(e) => setFormDriverPhone(e.target.value)} className="h-9" /></div>
                        <div className="space-y-1.5"><Label className="text-xs">도착예정일시</Label><FormDatePicker value={formArrival} onChange={setFormArrival} placeholder="도착예정일시" includeTime /></div>
                        <div className="space-y-1.5"><Label className="text-xs">배송지</Label><Input value={formAddress} onChange={(e) => setFormAddress(e.target.value)} className="h-9" /></div>
                      </div>
                    )}
                  </div>

                  {/* 선택된 품목 */}
                  <div className="bg-background border rounded-lg p-5 flex-1 flex flex-col min-h-[200px]">
                    <h3 className="text-sm font-semibold mb-3 flex items-center gap-2">
                      선택된 품목 <Badge variant="default" className="text-[10px]">{selectedItems.length}</Badge>
                    </h3>
                    <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">
                          <div className="text-sm">왼쪽에서 데이터를 선택하세요</div>
                        </div>
                      ) : (
                        <Table>
                          <TableHeader className="sticky top-0 bg-background z-10">
                            <TableRow>
                              <TableHead className="w-[40px] text-center">소스</TableHead>
                              <TableHead className="w-[90px]">품번</TableHead>
                              <TableHead>품명</TableHead>
                              <TableHead className="w-[90px] text-center">출하수량</TableHead>
                              <TableHead className="w-[70px] text-right">계획수량</TableHead>
                              <TableHead className="w-[40px] text-center">삭제</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]", b.cls)}>{b.label.charAt(0)}</span>
                                  </TableCell>
                                  <TableCell className="text-xs">{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-xs">{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="bg-background border rounded-lg p-5 shrink-0">
                    <h3 className="text-sm font-semibold mb-3">메모</h3>
                    <Textarea value={formMemo} onChange={(e) => setFormMemo(e.target.value)} placeholder="출하지시 관련 메모" rows={2} className="resize-y" />
                  </div>
                </div>
              </ResizablePanel>
            </ResizablePanelGroup>
          </div>

          <DialogFooter className="p-4 border-t bg-muted/30 shrink-0">
            <Button variant="outline" onClick={() => setIsModalOpen(false)}>취소</Button>
            <Button onClick={handleSave} disabled={saving}>
              {saving ? <Loader2 className="w-4 h-4 mr-1.5 animate-spin" /> : <Save className="w-4 h-4 mr-1.5" />} 저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
