"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { GitBranch, Loader2, PackagePlus, Pencil, Plus, Save, Search, Star, Trash2 } from "lucide-react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";

import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
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 {
  createRoutingVersion,
  getProcessList,
  getRegisteredItems,
  getRoutingDetails,
  getRoutingVersions,
  registerItemsBatch,
  saveRoutingDetails,
  searchAllItems,
  unregisterItem,
  type ItemForRouting,
  type ProcessMaster,
  type RegisteredItem,
  type RoutingDetail,
  type RoutingVersion,
} from "@/lib/api/processInfo";
import { cn } from "@/lib/utils";

function normalizeDefaultFlag(v: RoutingVersion): boolean {
  const raw = v.is_default as unknown;
  if (typeof raw === "boolean") return raw;
  if (raw === "t" || raw === true || raw === "Y" || raw === "true") return true;
  return false;
}

function sortDetailsBySeq(rows: RoutingDetail[]): RoutingDetail[] {
  return [...rows].sort((a, b) => {
    const na = parseInt(String(a.seq_no), 10) || 0;
    const nb = parseInt(String(b.seq_no), 10) || 0;
    return na - nb;
  });
}

export function ItemRoutingTab() {
  const [searchInput, setSearchInput] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [items, setItems] = useState<RegisteredItem[]>([]);
  const [itemsLoading, setItemsLoading] = useState(false);
  const [selectedItem, setSelectedItem] = useState<RegisteredItem | null>(null);

  const [versions, setVersions] = useState<RoutingVersion[]>([]);
  const [versionsLoading, setVersionsLoading] = useState(false);
  const [selectedVersionId, setSelectedVersionId] = useState<string | null>(null);

  const [details, setDetails] = useState<RoutingDetail[]>([]);
  const [detailsLoading, setDetailsLoading] = useState(false);
  const [saving, setSaving] = useState(false);

  const [selectedDetailIds, setSelectedDetailIds] = useState<Set<string>>(new Set());

  const [processes, setProcesses] = useState<ProcessMaster[]>([]);
  const [processesLoading, setProcessesLoading] = useState(false);

  const [versionDialogOpen, setVersionDialogOpen] = useState(false);
  const [versionName, setVersionName] = useState("");
  const [versionDescription, setVersionDescription] = useState("");
  const [versionIsDefault, setVersionIsDefault] = useState(false);
  const [versionSubmitting, setVersionSubmitting] = useState(false);

  const [detailDialogOpen, setDetailDialogOpen] = useState(false);
  const [detailDialogMode, setDetailDialogMode] = useState<"add" | "edit">("add");
  const [editingDetailId, setEditingDetailId] = useState<string | null>(null);
  const [formProcessCode, setFormProcessCode] = useState("");
  const [formSeqNo, setFormSeqNo] = useState("");
  const [formRequired, setFormRequired] = useState("Y");
  const [formFixedOrder, setFormFixedOrder] = useState("Y");
  const [formWorkType, setFormWorkType] = useState("내부");
  const [formStandardTime, setFormStandardTime] = useState("");
  const [formOutsource, setFormOutsource] = useState("");
  const [detailSubmitting, setDetailSubmitting] = useState(false);

  const [registerDialogOpen, setRegisterDialogOpen] = useState(false);
  const [registerSearch, setRegisterSearch] = useState("");
  const [registerSearchDebounced, setRegisterSearchDebounced] = useState("");
  const [registerItems, setRegisterItems] = useState<ItemForRouting[]>([]);
  const [registerLoading, setRegisterLoading] = useState(false);
  const [registerSelectedIds, setRegisterSelectedIds] = useState<Set<string>>(new Set());
  const [registerSubmitting, setRegisterSubmitting] = useState(false);

  useEffect(() => {
    const t = window.setTimeout(() => setDebouncedSearch(searchInput.trim()), 300);
    return () => window.clearTimeout(t);
  }, [searchInput]);

  useEffect(() => {
    const t = window.setTimeout(() => setRegisterSearchDebounced(registerSearch.trim()), 300);
    return () => window.clearTimeout(t);
  }, [registerSearch]);

  const loadItems = useCallback(async (search: string) => {
    setItemsLoading(true);
    try {
      const res = await getRegisteredItems(search || undefined);
      if (res.success && res.data) {
        setItems(res.data);
      } else {
        toast.error(res.message || "품목 목록을 불러오지 못했어요");
        setItems([]);
      }
    } finally {
      setItemsLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadItems(debouncedSearch);
  }, [debouncedSearch, loadItems]);

  const loadProcesses = useCallback(async () => {
    setProcessesLoading(true);
    try {
      const procRes = await getProcessList({ useYn: "Y" });
      if (!procRes.success || !procRes.data) {
        toast.error(procRes.message || "공정 목록을 불러오지 못했어요");
        setProcesses([]);
        return;
      }
      setProcesses(procRes.data);
    } finally {
      setProcessesLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadProcesses();
  }, [loadProcesses]);

  const loadRegisterItems = useCallback(async (search: string) => {
    setRegisterLoading(true);
    try {
      const res = await searchAllItems(search || undefined);
      if (res.success && res.data) {
        setRegisterItems(res.data);
      } else {
        setRegisterItems([]);
      }
    } finally {
      setRegisterLoading(false);
    }
  }, []);

  useEffect(() => {
    if (!registerDialogOpen) return;
    void loadRegisterItems(registerSearchDebounced);
  }, [registerSearchDebounced, registerDialogOpen, loadRegisterItems]);

  const registeredItemCodes = useMemo(() => new Set(items.map((i) => i.item_code)), [items]);

  const handleRegisterItems = async () => {
    if (registerSelectedIds.size === 0) {
      toast.error("등록할 품목을 선택해주세요");
      return;
    }
    setRegisterSubmitting(true);
    try {
      const selected = registerItems.filter((ri) => registerSelectedIds.has(ri.id));
      const batchItems = selected.map((item) => ({
        itemId: item.id,
        itemCode: item.item_number,
      }));
      const res = await registerItemsBatch(batchItems);
      if (res.success) {
        toast.success(`${batchItems.length}건 품목이 등록되었어요`);
        setRegisterDialogOpen(false);
        setRegisterSearch("");
        setRegisterSelectedIds(new Set());
        void loadItems(debouncedSearch);
      } else {
        toast.error(res.message || "품목 등록에 실패했어요");
      }
    } finally {
      setRegisterSubmitting(false);
    }
  };

  const loadVersions = useCallback(async (item: RegisteredItem, preferVersionId?: string) => {
    setVersionsLoading(true);
    setVersions([]);
    setSelectedVersionId(null);
    setDetails([]);
    setSelectedDetailIds(new Set());
    try {
      const res = await getRoutingVersions(item.item_code);
      if (!res.success || !res.data) {
        toast.error(res.message || "라우팅 버전을 불러오지 못했어요");
        return;
      }
      const list = res.data.map((v) => ({ ...v, is_default: normalizeDefaultFlag(v) }));
      setVersions(list);
      const preferred = preferVersionId ? list.find((v) => v.id === preferVersionId) : undefined;
      const def = list.find((v) => v.is_default);
      const pick = preferred ?? def ?? list[0];
      if (pick) setSelectedVersionId(pick.id);
    } finally {
      setVersionsLoading(false);
    }
  }, []);

  useEffect(() => {
    if (!selectedItem) return;
    void loadVersions(selectedItem);
  }, [selectedItem, loadVersions]);

  const loadDetails = useCallback(async (versionId: string) => {
    setDetailsLoading(true);
    setSelectedDetailIds(new Set());
    try {
      const res = await getRoutingDetails(versionId);
      if (res.success && res.data) {
        setDetails(sortDetailsBySeq(res.data));
      } else {
        toast.error(res.message || "라우팅 공정을 불러오지 못했어요");
        setDetails([]);
      }
    } finally {
      setDetailsLoading(false);
    }
  }, []);

  useEffect(() => {
    if (!selectedVersionId) {
      setDetails([]);
      return;
    }
    void loadDetails(selectedVersionId);
  }, [selectedVersionId, loadDetails]);

  const showOutsourceField = formWorkType === "외주" || formWorkType === "선택가능";

  const openAddDetailDialog = () => {
    if (!selectedVersionId) {
      toast.error("먼저 라우팅 버전을 선택해주세요");
      return;
    }
    setDetailDialogMode("add");
    setEditingDetailId(null);
    setFormProcessCode("");
    const nextSeq = details.length === 0 ? 1 : Math.max(...details.map((d) => parseInt(String(d.seq_no), 10) || 0)) + 1;
    setFormSeqNo(String(nextSeq));
    setFormRequired("Y");
    setFormFixedOrder("Y");
    setFormWorkType("내부");
    setFormStandardTime("");
    setFormOutsource("");
    setDetailDialogOpen(true);
  };

  const openEditDetailDialog = () => {
    if (!selectedVersionId) {
      toast.error("먼저 라우팅 버전을 선택해주세요");
      return;
    }
    if (selectedDetailIds.size !== 1) {
      toast.error("수정할 공정 한 건만 선택해주세요");
      return;
    }
    const id = [...selectedDetailIds][0];
    const row = details.find((d) => d.id === id);
    if (!row) {
      toast.error("선택한 공정을 찾을 수 없어요");
      return;
    }
    setDetailDialogMode("edit");
    setEditingDetailId(row.id);
    setFormProcessCode(row.process_code);
    setFormSeqNo(String(row.seq_no));
    setFormRequired(row.is_required === "N" ? "N" : "Y");
    setFormFixedOrder(row.is_fixed_order === "N" ? "N" : "Y");
    setFormWorkType(row.work_type || "내부");
    setFormStandardTime(row.standard_time || "");
    setFormOutsource(row.outsource_supplier || "");
    setDetailDialogOpen(true);
  };

  const submitDetailForm = () => {
    if (!selectedVersionId) return;
    if (!formProcessCode) {
      toast.error("공정을 선택해주세요");
      return;
    }
    const seq = parseInt(formSeqNo, 10);
    if (Number.isNaN(seq) || seq < 1) {
      toast.error("올바른 순번을 입력해주세요");
      return;
    }
    const st = formStandardTime.trim();
    if (st !== "" && Number.isNaN(Number(st))) {
      toast.error("표준작업시간은 숫자로 입력해주세요");
      return;
    }
    const proc = processes.find((p) => p.process_code === formProcessCode);
    const outsource = showOutsourceField ? formOutsource.trim() : "";

    setDetailSubmitting(true);
    try {
      if (detailDialogMode === "add") {
        const newRow: RoutingDetail = {
          id: `new-${crypto.randomUUID()}`,
          routing_version_id: selectedVersionId,
          seq_no: String(seq),
          process_code: formProcessCode,
          process_name: proc?.process_name,
          is_required: formRequired,
          is_fixed_order: formFixedOrder,
          work_type: formWorkType,
          standard_time: st || "0",
          outsource_supplier: outsource,
        };
        setDetails((prev) => sortDetailsBySeq([...prev, newRow]));
        toast.success("공정이 추가되었어요. 저장을 눌러 반영해주세요");
      } else if (editingDetailId) {
        setDetails((prev) =>
          sortDetailsBySeq(
            prev.map((d) =>
              d.id === editingDetailId
                ? {
                    ...d,
                    seq_no: String(seq),
                    process_code: formProcessCode,
                    process_name: proc?.process_name ?? d.process_name,
                    is_required: formRequired,
                    is_fixed_order: formFixedOrder,
                    work_type: formWorkType,
                    standard_time: st || "0",
                    outsource_supplier: outsource,
                  }
                : d,
            ),
          ),
        );
        toast.success("공정이 수정되었어요. 저장을 눌러 반영해주세요");
      }
      setDetailDialogOpen(false);
    } finally {
      setDetailSubmitting(false);
    }
  };

  const deleteSelectedDetails = () => {
    if (selectedDetailIds.size === 0) {
      toast.error("삭제할 공정을 선택해주세요");
      return;
    }
    setDetails((prev) => prev.filter((d) => !selectedDetailIds.has(d.id)));
    setSelectedDetailIds(new Set());
    toast.success("선택한 공정이 제거되었어요. 저장을 눌러 반영해주세요");
  };

  const persistDetails = async () => {
    if (!selectedVersionId) {
      toast.error("저장할 버전이 없어요");
      return;
    }
    const payload = details.map((d) => ({
      seq_no: String(d.seq_no),
      process_code: d.process_code,
      is_required: d.is_required || "Y",
      is_fixed_order: d.is_fixed_order || "Y",
      work_type: d.work_type || "내부",
      standard_time: String(d.standard_time ?? "0"),
      outsource_supplier: d.outsource_supplier || "",
    }));

    setSaving(true);
    try {
      const res = await saveRoutingDetails(selectedVersionId, payload);
      if (res.success) {
        toast.success("저장되었어요");
        await loadDetails(selectedVersionId);
      } else {
        toast.error(res.message || "저장에 실패했어요");
      }
    } finally {
      setSaving(false);
    }
  };

  const submitNewVersion = async () => {
    if (!selectedItem) return;
    const name = versionName.trim();
    if (!name) {
      toast.error("버전명을 입력해주세요");
      return;
    }
    setVersionSubmitting(true);
    try {
      const res = await createRoutingVersion({
        item_code: selectedItem.item_code,
        version_name: name,
        description: versionDescription.trim() || undefined,
        is_default: versionIsDefault || undefined,
      });
      if (res.success && res.data) {
        toast.success("버전이 추가되었어요");
        setVersionDialogOpen(false);
        setVersionName("");
        setVersionDescription("");
        setVersionIsDefault(false);
        const created = res.data as RoutingVersion;
        await loadVersions(selectedItem, created?.id);
      } else {
        toast.error(res.message || "버전 추가에 실패했어요");
      }
    } finally {
      setVersionSubmitting(false);
    }
  };

  const detailsGridData = useMemo(
    () =>
      details.map((d) => ({
        ...d,
        process_display: d.process_name || d.process_code,
        outsource_display: d.outsource_supplier || "—",
      })),
    [details],
  );

  return (
    <div className="flex h-full flex-col">
      <ResizablePanelGroup direction="horizontal" className="min-h-0 flex-1">
        {/* 좌측: 등록 품목 */}
        <ResizablePanel defaultSize={30} minSize={18}>
          <div className="flex h-full flex-col">
            <div className="flex items-center gap-2 border-b bg-muted/30 px-4 py-2">
              <PackagePlus className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-semibold">등록 품목</span>
              <Badge variant="secondary" className="font-mono text-xs">
                {items.length}건
              </Badge>
              <div className="ml-auto">
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={() => {
                    setRegisterSearch("");
                    setRegisterSelectedIds(new Set());
                    setRegisterItems([]);
                    setRegisterDialogOpen(true);
                  }}
                >
                  <Plus className="mr-1 h-3.5 w-3.5" />
                  품목 등록
                </Button>
              </div>
            </div>

            <div className="border-b px-3 py-2">
              <div className="relative">
                <Search className="pointer-events-none absolute top-1/2 left-2.5 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
                <Input
                  value={searchInput}
                  onChange={(e) => setSearchInput(e.target.value)}
                  placeholder="품목코드 / 품목명 검색"
                  className="h-8 pl-8 text-xs"
                  aria-label="품목 검색"
                />
              </div>
            </div>

            <div className="min-h-0 flex-1 overflow-auto p-3">
              {itemsLoading ? (
                <div className="flex items-center justify-center gap-2 py-12 text-muted-foreground">
                  <Loader2 className="h-5 w-5 animate-spin text-primary" />
                  <span className="text-sm">불러오는 중...</span>
                </div>
              ) : items.length === 0 ? (
                <div className="flex flex-col items-center justify-center gap-3 py-12">
                  <p className="text-sm text-muted-foreground">등록된 품목이 없어요</p>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                      setRegisterSearch("");
                      setRegisterSelectedIds(new Set());
                      setRegisterItems([]);
                      setRegisterDialogOpen(true);
                    }}
                  >
                    <PackagePlus className="mr-1 h-3.5 w-3.5" />
                    품목 등록하기
                  </Button>
                </div>
              ) : (
                <div className="space-y-2">
                  {items.map((item) => {
                    const active = selectedItem?.id === item.id;
                    return (
                      <button
                        key={item.id}
                        type="button"
                        onClick={() => setSelectedItem(item)}
                        className={cn(
                          "w-full rounded-lg border p-3 text-left transition-colors",
                          "border-border bg-card hover:bg-muted/30",
                          active && "border-primary ring-2 ring-ring/30",
                        )}
                      >
                        <p className="text-sm font-medium text-foreground">{item.item_code}</p>
                        <p className="mt-0.5 line-clamp-2 text-xs text-muted-foreground">{item.item_name}</p>
                      </button>
                    );
                  })}
                </div>
              )}
            </div>
          </div>
        </ResizablePanel>

        <ResizableHandle withHandle />

        {/* 우측: 버전 + 라우팅 상세 */}
        <ResizablePanel defaultSize={70} minSize={35}>
          <div className="flex h-full flex-col">
            {!selectedItem ? (
              <div className="flex flex-1 flex-col items-center justify-center gap-2 text-center text-muted-foreground">
                <GitBranch className="h-10 w-10 opacity-40" />
                <p className="text-sm font-medium text-foreground">좌측에서 품목을 선택해주세요</p>
                <p className="max-w-xs text-xs">품목을 선택하면 라우팅 버전과 공정을 관리할 수 있어요</p>
              </div>
            ) : (
              <>
                {/* 패널 헤더 */}
                <div className="flex items-center gap-3 border-b bg-muted/30 px-4 py-2">
                  <GitBranch className="h-4 w-4 shrink-0 text-muted-foreground" />
                  <div className="min-w-0 flex-1">
                    <p className="truncate text-sm font-semibold">{selectedItem.item_name}</p>
                    <p className="text-xs text-muted-foreground">품목코드 {selectedItem.item_code}</p>
                  </div>
                  <div className="flex shrink-0 gap-2">
                    <Button
                      variant="destructive"
                      size="sm"
                      onClick={async () => {
                        if (!selectedItem.registered_id) return;
                        const res = await unregisterItem(selectedItem.registered_id);
                        if (res.success) {
                          toast.success("품목 등록이 해제되었어요");
                          setSelectedItem(null);
                          void loadItems(debouncedSearch);
                        } else {
                          toast.error(res.message || "등록 해제에 실패했어요");
                        }
                      }}
                    >
                      <Trash2 className="mr-1 h-3.5 w-3.5" />
                      등록 해제
                    </Button>
                    <Button
                      size="sm"
                      onClick={() => {
                        setVersionName("");
                        setVersionDescription("");
                        setVersionIsDefault(false);
                        setVersionDialogOpen(true);
                      }}
                    >
                      <Plus className="mr-1 h-3.5 w-3.5" />
                      버전 추가
                    </Button>
                  </div>
                </div>

                {/* 버전 pills */}
                <div className="border-b bg-muted/30 px-4 py-2">
                  {versionsLoading ? (
                    <div className="flex items-center gap-2 text-sm text-muted-foreground">
                      <Loader2 className="h-4 w-4 animate-spin text-primary" />
                      버전 불러오는 중...
                    </div>
                  ) : versions.length === 0 ? (
                    <p className="text-sm text-muted-foreground">
                      등록된 버전이 없어요. 버전을 추가해주세요.
                    </p>
                  ) : (
                    <div className="flex flex-wrap items-center gap-2">
                      {versions.map((v) => {
                        const selected = v.id === selectedVersionId;
                        const def = normalizeDefaultFlag(v);
                        return (
                          <button
                            key={v.id}
                            type="button"
                            onClick={() => setSelectedVersionId(v.id)}
                            className={cn(
                              "inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors",
                              selected
                                ? "border-primary bg-primary text-primary-foreground"
                                : "border-border bg-secondary text-secondary-foreground hover:bg-secondary/80",
                            )}
                          >
                            {def && (
                              <Star
                                className={cn(
                                  "h-3.5 w-3.5",
                                  selected ? "fill-primary-foreground" : "fill-warning text-warning",
                                )}
                                aria-label="기본 버전"
                              />
                            )}
                            {v.version_name}
                          </button>
                        );
                      })}
                    </div>
                  )}
                </div>

                {/* 액션 바 */}
                <div className="flex items-center justify-between border-b bg-muted/30 px-4 py-2">
                  <div className="flex items-center gap-2">
                    <span className="text-sm font-semibold">라우팅 공정</span>
                    <Badge variant="secondary" className="font-mono text-xs">
                      {details.length}건
                    </Badge>
                  </div>
                  <div className="flex gap-2">
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={openAddDetailDialog}
                    disabled={!selectedVersionId || detailsLoading}
                  >
                    <Plus className="mr-1 h-3.5 w-3.5" />
                    공정 추가
                  </Button>
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={openEditDetailDialog}
                    disabled={!selectedVersionId || detailsLoading}
                  >
                    <Pencil className="mr-1 h-3.5 w-3.5" />
                    수정
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={deleteSelectedDetails}
                    disabled={!selectedVersionId || detailsLoading}
                  >
                    <Trash2 className="mr-1 h-3.5 w-3.5" />
                    선택 삭제
                  </Button>
                  <Button
                    size="sm"
                    onClick={() => void persistDetails()}
                    disabled={!selectedVersionId || detailsLoading || saving}
                  >
                    {saving ? (
                      <Loader2 className="mr-1 h-3.5 w-3.5 animate-spin" />
                    ) : (
                      <Save className="mr-1 h-3.5 w-3.5" />
                    )}
                    저장
                  </Button>
                  </div>
                </div>

                {/* 라우팅 공정 테이블 */}
                <div className="min-h-0 flex-1 overflow-auto">
                  {!selectedVersionId ? (
                    <p className="py-8 text-center text-sm text-muted-foreground">버전을 선택해주세요</p>
                  ) : detailsLoading ? (
                    <div className="flex flex-col items-center justify-center py-12 text-muted-foreground">
                      <Loader2 className="h-7 w-7 animate-spin" />
                      <p className="mt-2 text-sm">불러오는 중...</p>
                    </div>
                  ) : detailsGridData.length === 0 ? (
                    <p className="py-8 text-center text-sm text-muted-foreground">등록된 공정이 없어요</p>
                  ) : (
                    <Table>
                      <TableHeader className="sticky top-0 bg-muted/90 z-10">
                        <TableRow>
                          <TableHead className="w-10 text-muted-foreground">
                            <Checkbox
                              checked={selectedDetailIds.size === detailsGridData.length && detailsGridData.length > 0}
                              onCheckedChange={(checked) => {
                                if (checked) setSelectedDetailIds(new Set(detailsGridData.map((r) => r.id)));
                                else setSelectedDetailIds(new Set());
                              }}
                            />
                          </TableHead>
                          <TableHead className="w-[80px] text-center text-muted-foreground">순번</TableHead>
                          <TableHead className="text-muted-foreground">공정명</TableHead>
                          <TableHead className="w-[80px] text-center text-muted-foreground">필수</TableHead>
                          <TableHead className="w-[90px] text-center text-muted-foreground">순서고정</TableHead>
                          <TableHead className="w-[100px] text-muted-foreground">작업구분</TableHead>
                          <TableHead className="w-[90px] text-right text-muted-foreground">표준시간</TableHead>
                          <TableHead className="text-muted-foreground">외주업체</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {detailsGridData.map((row) => (
                          <TableRow key={row.id} className="hover:bg-muted/30">
                            <TableCell onClick={(e) => e.stopPropagation()}>
                              <Checkbox
                                checked={selectedDetailIds.has(row.id)}
                                onCheckedChange={(checked) => {
                                  setSelectedDetailIds((prev) => {
                                    const next = new Set(prev);
                                    if (checked) next.add(row.id);
                                    else next.delete(row.id);
                                    return next;
                                  });
                                }}
                              />
                            </TableCell>
                            <TableCell className="text-center">{row.seq_no}</TableCell>
                            <TableCell>{row.process_display}</TableCell>
                            <TableCell className="text-center">{row.is_required}</TableCell>
                            <TableCell className="text-center">{row.is_fixed_order}</TableCell>
                            <TableCell>{row.work_type}</TableCell>
                            <TableCell className="text-right">{row.standard_time}</TableCell>
                            <TableCell>{row.outsource_display}</TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  )}
                </div>
              </>
            )}
          </div>
        </ResizablePanel>
      </ResizablePanelGroup>

      {/* 버전 추가 모달 */}
      <Dialog open={versionDialogOpen} onOpenChange={setVersionDialogOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>라우팅 버전 추가</DialogTitle>
            <DialogDescription>선택한 품목에 새 라우팅 버전을 추가해요</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-1">
              <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                버전명 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={versionName}
                onChange={(e) => setVersionName(e.target.value)}
                placeholder="예: Rev.A"
                className="h-9"
              />
            </div>
            <div className="space-y-1">
              <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">설명</Label>
              <Input
                value={versionDescription}
                onChange={(e) => setVersionDescription(e.target.value)}
                placeholder="선택 입력"
                className="h-9"
              />
            </div>
            <div className="flex items-center gap-2">
              <Checkbox
                id="versionDefault"
                checked={versionIsDefault}
                onCheckedChange={(c) => setVersionIsDefault(c === true)}
              />
              <Label htmlFor="versionDefault" className="text-sm font-normal">
                기본 버전으로 설정
              </Label>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setVersionDialogOpen(false)} disabled={versionSubmitting}>
              취소
            </Button>
            <Button onClick={() => void submitNewVersion()} disabled={versionSubmitting}>
              {versionSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              추가해요
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 공정 추가/수정 모달 */}
      <Dialog open={detailDialogOpen} onOpenChange={setDetailDialogOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>{detailDialogMode === "add" ? "공정 추가" : "공정 수정"}</DialogTitle>
            <DialogDescription>라우팅 공정 순서에 반영할 내용을 입력해주세요</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-1">
              <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                공정 <span className="text-destructive">*</span>
              </Label>
              <Select value={formProcessCode} onValueChange={setFormProcessCode}>
                <SelectTrigger className="h-9" size="sm">
                  <SelectValue placeholder={processesLoading ? "불러오는 중..." : "공정 선택"} />
                </SelectTrigger>
                <SelectContent>
                  {processes.map((p) => (
                    <SelectItem key={p.id} value={p.process_code}>
                      {p.process_name} ({p.process_code})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                순번 <span className="text-destructive">*</span>
              </Label>
              <Input
                type="number"
                min={1}
                value={formSeqNo}
                onChange={(e) => setFormSeqNo(e.target.value)}
                className="h-9"
              />
            </div>
            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1">
                <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">필수여부</Label>
                <Select value={formRequired} onValueChange={setFormRequired}>
                  <SelectTrigger className="h-9" size="sm">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="Y">Y</SelectItem>
                    <SelectItem value="N">N</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-1">
                <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">순서고정여부</Label>
                <Select value={formFixedOrder} onValueChange={setFormFixedOrder}>
                  <SelectTrigger className="h-9" size="sm">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="Y">Y</SelectItem>
                    <SelectItem value="N">N</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>
            <div className="space-y-1">
              <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">작업구분</Label>
              <Select value={formWorkType} onValueChange={setFormWorkType}>
                <SelectTrigger className="h-9" size="sm">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="내부">내부</SelectItem>
                  <SelectItem value="외주">외주</SelectItem>
                  <SelectItem value="선택가능">선택가능</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">표준작업시간(분)</Label>
              <Input
                type="number"
                min={0}
                step={1}
                value={formStandardTime}
                onChange={(e) => setFormStandardTime(e.target.value)}
                placeholder="0"
                className="h-9"
              />
            </div>
            {showOutsourceField && (
              <div className="space-y-1">
                <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">외주업체</Label>
                <Input
                  value={formOutsource}
                  onChange={(e) => setFormOutsource(e.target.value)}
                  placeholder="외주 업체명"
                  className="h-9"
                />
              </div>
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDetailDialogOpen(false)} disabled={detailSubmitting}>
              취소
            </Button>
            <Button onClick={submitDetailForm} disabled={detailSubmitting}>
              {detailSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              확인
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* 품목 등록 모달 */}
      <Dialog open={registerDialogOpen} onOpenChange={setRegisterDialogOpen}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>품목 등록</DialogTitle>
            <DialogDescription>라우팅에 추가할 품목을 검색하고 선택해주세요</DialogDescription>
          </DialogHeader>
        <div className="space-y-3">
          <div className="relative">
            <Search className="pointer-events-none absolute top-1/2 left-2.5 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
            <Input
              value={registerSearch}
              onChange={(e) => setRegisterSearch(e.target.value)}
              placeholder="품목코드 / 품목명으로 검색"
              className="h-9 pl-8 text-xs"
              aria-label="품목 검색"
            />
          </div>
          <div className="max-h-[400px] overflow-auto rounded-md border">
            {registerLoading ? (
              <div className="flex items-center justify-center gap-2 py-12 text-sm text-muted-foreground">
                <Loader2 className="h-5 w-5 animate-spin text-primary" />
                검색 중...
              </div>
            ) : registerItems.length === 0 ? (
              <p className="py-8 text-center text-sm text-muted-foreground">
                {registerSearchDebounced ? "검색 결과가 없어요" : "품목을 검색해주세요"}
              </p>
            ) : (
              <Table>
                <TableHeader className="sticky top-0 bg-background z-10">
                  <TableRow>
                    <TableHead className="w-10 text-center text-muted-foreground">
                      <Checkbox
                        checked={
                          registerItems.filter((ri) => !registeredItemCodes.has(ri.item_number)).length > 0 &&
                          registerItems
                            .filter((ri) => !registeredItemCodes.has(ri.item_number))
                            .every((ri) => registerSelectedIds.has(ri.id))
                        }
                        onCheckedChange={(checked) => {
                          const next = new Set(registerSelectedIds);
                          const available = registerItems.filter((ri) => !registeredItemCodes.has(ri.item_number));
                          if (checked) {
                            available.forEach((ri) => next.add(ri.id));
                          } else {
                            available.forEach((ri) => next.delete(ri.id));
                          }
                          setRegisterSelectedIds(next);
                        }}
                      />
                    </TableHead>
                    <TableHead className="text-xs text-muted-foreground">품목코드</TableHead>
                    <TableHead className="text-xs text-muted-foreground">품목명</TableHead>
                    <TableHead className="text-xs text-muted-foreground">상태</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {registerItems.map((ri) => {
                    const alreadyRegistered = registeredItemCodes.has(ri.item_number);
                    return (
                      <TableRow key={ri.id} className={cn("hover:bg-muted/30", alreadyRegistered && "opacity-50")}>
                        <TableCell className="text-center">
                          <Checkbox
                            checked={registerSelectedIds.has(ri.id)}
                            disabled={alreadyRegistered}
                            onCheckedChange={(checked) => {
                              const next = new Set(registerSelectedIds);
                              if (checked) next.add(ri.id);
                              else next.delete(ri.id);
                              setRegisterSelectedIds(next);
                            }}
                          />
                        </TableCell>
                        <TableCell className="text-xs">{ri.item_number}</TableCell>
                        <TableCell className="text-xs">{ri.item_name}</TableCell>
                        <TableCell className="text-xs">
                          {alreadyRegistered ? (
                            <span className="text-muted-foreground">등록됨</span>
                          ) : (
                            <span className="text-primary">미등록</span>
                          )}
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            )}
          </div>
          </div>
          <DialogFooter className="flex-row items-center justify-between sm:justify-between">
            {registerSelectedIds.size > 0 ? (
              <p className="text-xs text-muted-foreground">{registerSelectedIds.size}건 선택됨</p>
            ) : (
              <div />
            )}
            <div className="flex gap-2">
              <Button variant="outline" onClick={() => setRegisterDialogOpen(false)}>
                취소
              </Button>
              <Button
                onClick={() => void handleRegisterItems()}
                disabled={registerSubmitting || registerSelectedIds.size === 0}
              >
                {registerSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                등록 ({registerSelectedIds.size}건)
              </Button>
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
