"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { cn } from "@/lib/utils";
import {
  Loader2, Save, RotateCcw, Plus, Trash2, Pencil, ClipboardCheck,
  GripVertical, AlertCircle, ClipboardList,
} from "lucide-react";
import { toast } from "sonner";
import {
  getWIWorkStandard, saveWIWorkStandard, resetWIWorkStandard,
  WIWorkItem, WIWorkItemDetail, WIWorkStandardProcess,
} from "@/lib/api/workInstruction";
import { getBomMaterials, BomMaterial } from "@/lib/api/processInfo";
import { apiClient } from "@/lib/api/client";

interface WorkStandardEditModalProps {
  open: boolean;
  onClose: () => void;
  workInstructionNo: string;
  routingVersionId: string;
  routingName: string;
  itemName: string;
  itemCode: string;
}

const PHASES = [
  { key: "PRE", label: "작업 전 (Pre-Work)" },
  { key: "IN", label: "작업 중 (In-Work)" },
  { key: "POST", label: "작업 후 (Post-Work)" },
];

const DETAIL_TYPES = [
  { value: "checklist", label: "체크리스트" },
  { value: "inspection", label: "검사항목" },
  { value: "procedure", label: "작업절차" },
  { value: "input", label: "직접입력" },
  { value: "lookup", label: "문서참조" },
  { value: "equip_inspection", label: "설비점검" },
  { value: "equip_condition", label: "설비조건" },
  { value: "production_result", label: "실적등록" },
  { value: "material_input", label: "자재투입" },
];

const INPUT_TYPES = [
  { value: "text", label: "텍스트" },
  { value: "number", label: "숫자" },
  { value: "date", label: "날짜" },
  { value: "textarea", label: "장문 텍스트" },
];

const UNIT_OPTIONS = [
  "mm", "cm", "m", "μm", "℃", "℉", "bar", "Pa", "MPa", "psi",
  "RPM", "kg", "N", "N·m", "m/s", "m/min", "A", "V", "kW", "%",
  "L/min", "Hz", "dB", "ea", "g", "mg", "ml", "L",
];

// PLC 데이터 옵션 (원본 DetailFormModal과 동일)
const PLC_DATA_OPTIONS = [
  { value: "PLC_TEMP_01", label: "온도 (PLC_TEMP_01)" },
  { value: "PLC_PRES_01", label: "압력 (PLC_PRES_01)" },
  { value: "PLC_RPM_01", label: "회전수 (PLC_RPM_01)" },
  { value: "PLC_TORQ_01", label: "토크 (PLC_TORQ_01)" },
  { value: "PLC_SPD_01", label: "속도 (PLC_SPD_01)" },
  { value: "PLC_CUR_01", label: "전류 (PLC_CUR_01)" },
  { value: "PLC_VOLT_01", label: "전압 (PLC_VOLT_01)" },
  { value: "PLC_VIB_01", label: "진동 (PLC_VIB_01)" },
  { value: "PLC_HUM_01", label: "습도 (PLC_HUM_01)" },
  { value: "PLC_FLOW_01", label: "유량 (PLC_FLOW_01)" },
];

const PLC_PRODUCTION_OPTIONS: Record<string, { value: string; label: string }[]> = {
  work_qty: [
    { value: "PLC_CNT_01", label: "생산카운터 (PLC_CNT_01)" },
    { value: "PLC_CNT_02", label: "완료카운터 (PLC_CNT_02)" },
    { value: "PLC_QTY_01", label: "작업수량 (PLC_QTY_01)" },
  ],
  defect_qty: [
    { value: "PLC_NG_01", label: "불량카운터 (PLC_NG_01)" },
    { value: "PLC_NG_02", label: "NG감지기 (PLC_NG_02)" },
    { value: "PLC_REJ_01", label: "리젝트수 (PLC_REJ_01)" },
  ],
  good_qty: [
    { value: "PLC_OK_01", label: "양품카운터 (PLC_OK_01)" },
    { value: "PLC_OK_02", label: "합격카운터 (PLC_OK_02)" },
    { value: "PLC_GOOD_01", label: "양품수량 (PLC_GOOD_01)" },
  ],
};

const getDetailTypeLabel = (type: string) =>
  DETAIL_TYPES.find(d => d.value === type)?.label || type;

// 원본 WorkItemDetailList의 getContentSummary를 그대로 이식
const getContentSummary = (detail: WIWorkItemDetail): string => {
  const type = detail.detail_type;
  if (type === "inspection") {
    if (detail.process_inspection_apply === "apply") return detail.content || "품목별 검사정보 (자동 연동)";
    const parts = [detail.content];
    if (detail.inspection_method) parts.push(`[${detail.inspection_method}]`);
    if (detail.base_value) {
      parts.push(`(기준: ${detail.base_value}${detail.tolerance ? ` ±${detail.tolerance}` : ""} ${detail.unit || ""})`);
    }
    return parts.join(" ");
  }
  if (type === "procedure" && detail.duration_minutes) {
    return `${detail.content} (${detail.duration_minutes}분)`;
  }
  if (type === "input" && detail.input_type) {
    const typeMap: Record<string, string> = { text: "텍스트", number: "숫자", date: "날짜", textarea: "장문" };
    return `${detail.content} [${typeMap[detail.input_type] || detail.input_type}]`;
  }
  if (type === "lookup") return "품목 등록 문서 (자동 연동)";
  if (type === "equip_inspection") {
    return detail.content || (detail.equip_inspection_apply === "apply" ? "설비 점검항목 (설비정보 연동)" : "설비점검");
  }
  if (type === "equip_condition") {
    const parts = [detail.content];
    if (detail.condition_base_value) {
      parts.push(`(기준: ${detail.condition_base_value}${detail.condition_tolerance ? ` ±${detail.condition_tolerance}` : ""} ${detail.condition_unit || ""})`);
    }
    return parts.join(" ");
  }
  if (type === "production_result") return "작업수량 / 불량수량 / 양품수량";
  if (type === "material_input") return detail.content || "BOM 구성 자재 (자동 연동)";
  return detail.content || "-";
};

// ============================================================
// 상세 항목 추가/수정 모달 — 원본 DetailFormModal을 내부에 이식
// 원본: frontend/lib/registry/components/v2-process-work-standard/components/DetailFormModal.tsx
// ============================================================
interface DetailFormModalInnerProps {
  open: boolean;
  onClose: () => void;
  onSubmit: (data: Partial<WIWorkItemDetail>) => void;
  editData?: WIWorkItemDetail | null;
  mode: "add" | "edit";
  selectedItemCode?: string;
  selectedProcessCode?: string;
}

function DetailFormModalInner({
  open,
  onClose,
  onSubmit,
  editData,
  mode,
  selectedItemCode,
  selectedProcessCode,
}: DetailFormModalInnerProps) {
  const [formData, setFormData] = useState<Partial<WIWorkItemDetail>>({});
  const [bomMaterials, setBomMaterials] = useState<BomMaterial[]>([]);
  const [bomLoading, setBomLoading] = useState(false);
  const [bomChecked, setBomChecked] = useState<Set<string>>(new Set());

  // 품목검사정보 연동
  const [itemInspections, setItemInspections] = useState<any[]>([]);
  const [itemInspLoading, setItemInspLoading] = useState(false);

  // 품목 카테고리 (type 코드→라벨)
  const [itemTypeCatMap, setItemTypeCatMap] = useState<Record<string, string>>({});

  // 설비 점검항목 연동
  const [equipInspItems, setEquipInspItems] = useState<any[]>([]);
  const [equipInspLoading, setEquipInspLoading] = useState(false);

  const loadBomMaterials = useCallback(async () => {
    if (!selectedItemCode) {
      setBomMaterials([]);
      return;
    }
    setBomLoading(true);
    try {
      const res = await getBomMaterials(selectedItemCode);
      if (res.success && res.data) {
        setBomMaterials(res.data);
      } else {
        setBomMaterials([]);
      }
    } catch {
      setBomMaterials([]);
    } finally {
      setBomLoading(false);
    }
  }, [selectedItemCode]);

  // BOM 자재 로드 완료 후 체크 상태 초기화
  useEffect(() => {
    if (!open || bomMaterials.length === 0) return;
    if (mode === "edit" && editData?.selected_bom_items) {
      const savedBom = editData.selected_bom_items;
      const parsedBom = typeof savedBom === "string" ? JSON.parse(savedBom) : savedBom;
      if (Array.isArray(parsedBom)) {
        const matIds = new Set(bomMaterials.map((m) => m.id));
        const restored = new Set<string>();
        const seenChildForLegacy = new Set<string>();
        for (const saved of parsedBom) {
          if (matIds.has(saved)) {
            restored.add(saved);
          } else {
            const legacyKey = String(saved);
            if (seenChildForLegacy.has(legacyKey)) continue;
            const firstMat = bomMaterials.find((m) => m.child_item_id === legacyKey);
            if (firstMat) {
              restored.add(firstMat.id);
              seenChildForLegacy.add(legacyKey);
            }
          }
        }
        setBomChecked(restored);
        return;
      }
    }
    setBomChecked(new Set());
  }, [open, bomMaterials, mode, editData]);

  useEffect(() => {
    if (open) {
      if (mode === "edit" && editData) {
        setFormData({ ...editData });
      } else {
        setFormData({
          detail_type: DETAIL_TYPES[0]?.value || "",
          content: "",
          is_required: "Y",
        });
      }
    }
  }, [open, mode, editData]);

  useEffect(() => {
    if (open && formData.detail_type === "material_input") {
      loadBomMaterials();
      if (Object.keys(itemTypeCatMap).length === 0) {
        apiClient.get("/table-categories/item_info/type/values").then(res => {
          if (res.data?.success && res.data.data?.length) {
            const map: Record<string, string> = {};
            const flatten = (arr: any[]) => { for (const v of arr) { map[v.valueCode] = v.valueLabel; if (v.children?.length) flatten(v.children); } };
            flatten(res.data.data);
            setItemTypeCatMap(map);
          }
        }).catch(() => {});
      }
    }
  }, [open, formData.detail_type, loadBomMaterials, itemTypeCatMap]);

  // 검사항목 적용 시 품목검사정보 로드
  useEffect(() => {
    if (!open || formData.detail_type !== "inspection" || formData.process_inspection_apply !== "apply" || !selectedItemCode) {
      setItemInspections([]);
      return;
    }
    (async () => {
      setItemInspLoading(true);
      try {
        const res = await apiClient.post("/table-management/tables/item_inspection_info/data", {
          page: 1, size: 100,
          dataFilter: { enabled: true, filters: [{ columnName: "item_code", operator: "equals", value: selectedItemCode }] },
          autoFilter: true,
        });
        setItemInspections(res.data?.data?.data || res.data?.data?.rows || []);
      } catch { setItemInspections([]); } finally { setItemInspLoading(false); }
    })();
  }, [open, formData.detail_type, formData.process_inspection_apply, selectedItemCode]);

  // 설비점검 적용 시 해당 공정의 설비 점검항목 로드
  useEffect(() => {
    if (!open || formData.detail_type !== "equip_inspection" || formData.equip_inspection_apply !== "apply" || !selectedProcessCode) {
      setEquipInspItems([]);
      return;
    }
    (async () => {
      setEquipInspLoading(true);
      try {
        // 1. 해당 공정의 설비 목록 조회
        const equipRes = await apiClient.post("/table-management/tables/process_equipment/data", {
          page: 1, size: 100,
          dataFilter: { enabled: true, filters: [{ columnName: "process_code", operator: "equals", value: selectedProcessCode }] },
          autoFilter: true,
        });
        const equipCodes = (equipRes.data?.data?.data || equipRes.data?.data?.rows || []).map((e: any) => e.equipment_code).filter(Boolean);
        if (equipCodes.length === 0) { setEquipInspItems([]); return; }
        // 2. 각 설비의 점검항목 조회
        const inspRes = await apiClient.post("/table-management/tables/equipment_inspection_item/data", {
          page: 1, size: 500,
          dataFilter: { enabled: true, filters: [{ columnName: "equipment_code", operator: "in", value: equipCodes }] },
          autoFilter: true,
        });
        setEquipInspItems(inspRes.data?.data?.data || inspRes.data?.data?.rows || []);
      } catch { setEquipInspItems([]); } finally { setEquipInspLoading(false); }
    })();
  }, [open, formData.detail_type, formData.equip_inspection_apply, selectedProcessCode]);

  const updateField = (field: string, value: any) => {
    setFormData((prev) => ({ ...prev, [field]: value }));
  };

  const handleSubmit = () => {
    if (!formData.detail_type) return;

    const type = formData.detail_type;

    if (type === "checklist" && !formData.content?.trim()) return;
    if (type === "inspection") {
      if (!formData.process_inspection_apply) return;
      if (formData.process_inspection_apply === "none" && !formData.content?.trim()) return;
    }
    if (type === "procedure" && !formData.content?.trim()) return;
    if (type === "input" && !formData.content?.trim()) return;
    if (type === "equip_inspection" && !formData.equip_inspection_apply) return;
    if (type === "equip_condition" && !formData.content?.trim()) return;

    const submitData = { ...formData };

    // 검사항목 적용 → 품목검사정보 각각 개별 등록 (다중행 자동생성)
    if (type === "inspection" && submitData.process_inspection_apply === "apply") {
      if (itemInspections.length > 0) {
        for (const insp of itemInspections) {
          onSubmit({
            ...submitData,
            detail_type: "inspection",
            content: `${insp.inspection_item_name || insp.inspection_standard || "-"} | ${insp.pass_criteria || ""}`.trim(),
            is_required: submitData.is_required || "Y",
          });
        }
        onClose();
        return;
      }
      submitData.content = submitData.content || "품목별 검사정보 (자동 연동)";
    }
    if (type === "lookup") {
      submitData.content = submitData.content || "품목 등록 문서 (자동 연동)";
    }
    // 설비점검 적용 → 점검항목 각각 개별 등록 (다중행 자동생성)
    if (type === "equip_inspection" && submitData.equip_inspection_apply === "apply") {
      if (equipInspItems.length > 0) {
        for (const item of equipInspItems) {
          const range = (item.lower_limit || item.upper_limit) ? `${item.lower_limit || ""} ~ ${item.upper_limit || ""}${item.unit ? ` ${item.unit}` : ""}` : "";
          onSubmit({
            ...submitData,
            detail_type: "equip_inspection",
            content: `${item.inspection_item || "-"}${range ? ` | ${range}` : ""}`.trim(),
            is_required: submitData.is_required || "Y",
          });
        }
        onClose();
        return;
      }
      submitData.content = submitData.content || "설비 점검항목 (설비정보 연동)";
    }
    if (type === "production_result") {
      submitData.content = submitData.content || "작업수량 / 불량수량 / 양품수량";
    }
    if (type === "material_input") {
      // 선택된 BOM 자재를 각각 개별 상세 항목으로 등록 (다중행 자동생성)
      const checkedMats = bomMaterials.filter(m => bomChecked.has(m.id));
      if (checkedMats.length > 0) {
        const resolveType = (code: string) => itemTypeCatMap[code] || code || "";
        for (const mat of checkedMats) {
          const typeLabel = resolveType(mat.child_item_type || "");
          const unitLabel = mat.detail_unit || mat.item_unit || "";
          onSubmit({
            ...submitData,
            detail_type: "material_input",
            content: `${mat.child_item_name || mat.child_item_id}${typeLabel ? ` ${typeLabel}` : ""} | ${mat.quantity || 1} ${unitLabel}`.trim(),
            is_required: submitData.is_required || "Y",
            bom_item_id: mat.child_item_id,
            bom_item_name: mat.child_item_name || "",
            bom_qty: String(mat.quantity || 1),
            bom_unit: unitLabel,
          });
        }
        onClose();
        return;
      }
      submitData.content = submitData.content || "BOM 구성 자재 (자동 연동)";
      submitData.selected_bom_items = Array.from(bomChecked);
    }

    onSubmit(submitData);
    onClose();
  };

  const currentType = formData.detail_type || "";

  return (
    <Dialog open={open} onOpenChange={(v) => !v && onClose()}>
      <DialogContent className="max-w-[95vw] sm:max-w-[600px] max-h-[90vh] overflow-y-auto" onClick={(e) => e.stopPropagation()}>
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">
            상세 항목 {mode === "add" ? "추가" : "수정"}
          </DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            상세 항목의 유형을 선택하고 내용을 입력하세요
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* 유형 선택 */}
          <div>
            <Label className="text-xs sm:text-sm">
              유형 <span className="text-destructive">*</span>
            </Label>
            <Select
              value={currentType}
              onValueChange={(v) => {
                setFormData({
                  detail_type: v,
                  is_required: formData.is_required || "Y",
                });
              }}
            >
              <SelectTrigger className="mt-1 h-8 text-xs sm:h-10 sm:text-sm">
                <SelectValue placeholder="선택하세요" />
              </SelectTrigger>
              <SelectContent>
                {DETAIL_TYPES.map((t) => (
                  <SelectItem key={t.value} value={t.value}>
                    {t.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* ============ 체크리스트 ============ */}
          {currentType === "checklist" && (
            <div>
              <Label className="text-xs sm:text-sm">
                체크 내용 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={formData.content || ""}
                onChange={(e) => updateField("content", e.target.value)}
                placeholder="예: 전원 상태 확인"
                className="mt-1 h-8 text-xs sm:h-10 sm:text-sm"
              />
            </div>
          )}

          {/* ============ 검사항목 ============ */}
          {currentType === "inspection" && (
            <>
              {/* 공정검사 적용 여부 */}
              <div>
                <Label className="text-xs sm:text-sm">
                  공정검사 적용 <span className="text-destructive">*</span>
                </Label>
                <div className="mt-2 flex gap-4">
                  <label className="flex cursor-pointer items-center gap-2 text-xs sm:text-sm">
                    <input
                      type="radio"
                      name="processInspection"
                      checked={formData.process_inspection_apply === "apply"}
                      onChange={() => updateField("process_inspection_apply", "apply")}
                      className="h-4 w-4 accent-primary"
                    />
                    적용
                  </label>
                  <label className="flex cursor-pointer items-center gap-2 text-xs sm:text-sm">
                    <input
                      type="radio"
                      name="processInspection"
                      checked={formData.process_inspection_apply === "none"}
                      onChange={() => updateField("process_inspection_apply", "none")}
                      className="h-4 w-4 accent-primary"
                    />
                    미적용
                  </label>
                </div>
              </div>

              {/* 적용 시: 품목검사정보에서 등록된 검사항목 표시 */}
              {formData.process_inspection_apply === "apply" && (
                <div className="rounded-lg border border-sky-200 bg-sky-50 p-3 space-y-2">
                  <p className="text-xs font-semibold text-sky-800">
                    품목별 검사정보 (자동 연동)
                  </p>
                  {itemInspLoading ? (
                    <div className="flex items-center gap-2 py-2"><Loader2 className="h-3.5 w-3.5 animate-spin" /><span className="text-[11px] text-muted-foreground">조회 중...</span></div>
                  ) : itemInspections.length === 0 ? (
                    <p className="text-[11px] text-muted-foreground">등록된 검사항목이 없습니다. 품목검사정보에서 먼저 등록해주세요.</p>
                  ) : (
                    <table className="w-full text-[11px]">
                      <thead>
                        <tr className="border-b">
                          <th className="py-1 text-left font-medium text-sky-700">검사항목</th>
                          <th className="py-1 text-left font-medium text-sky-700">검사유형</th>
                          <th className="py-1 text-left font-medium text-sky-700">합격기준</th>
                        </tr>
                      </thead>
                      <tbody>
                        {itemInspections.map((insp, idx) => (
                          <tr key={insp.id || idx} className="border-b border-sky-100">
                            <td className="py-1">{insp.inspection_item_name || insp.inspection_standard || "-"}</td>
                            <td className="py-1">{insp.inspection_type || "-"}</td>
                            <td className="py-1 font-mono">{insp.pass_criteria || "-"}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  )}
                </div>
              )}

              {/* 미적용 시: 수동 입력 */}
              {formData.process_inspection_apply === "none" && (
                <>
                  <div>
                    <Label className="text-xs sm:text-sm">
                      검사 항목명 <span className="text-destructive">*</span>
                    </Label>
                    <Input
                      value={formData.content || ""}
                      onChange={(e) => updateField("content", e.target.value)}
                      placeholder="예: 외경 치수"
                      className="mt-1 h-8 text-xs sm:h-10 sm:text-sm"
                    />
                  </div>
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <Label className="text-xs sm:text-sm">검사 방법</Label>
                      <Input
                        value={formData.inspection_method || ""}
                        onChange={(e) => updateField("inspection_method", e.target.value)}
                        placeholder="예: 마이크로미터"
                        className="mt-1 h-8 text-xs sm:h-10 sm:text-sm"
                      />
                    </div>
                    <div>
                      <Label className="text-xs sm:text-sm">단위</Label>
                      <Select
                        value={formData.unit || ""}
                        onValueChange={(v) => updateField("unit", v)}
                      >
                        <SelectTrigger className="mt-1 h-8 text-xs sm:h-10 sm:text-sm">
                          <SelectValue placeholder="단위 선택" />
                        </SelectTrigger>
                        <SelectContent>
                          {UNIT_OPTIONS.map((u) => (
                            <SelectItem key={u} value={u}>{u}</SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  </div>

                  {/* 기준값 ± 오차범위 + 자동수집 + PLC */}
                  <div className="rounded-lg border bg-muted/30 p-3">
                    <div className="flex items-center gap-2">
                      <div className="flex-1">
                        <Input
                          type="number"
                          step="any"
                          value={formData.base_value || ""}
                          onChange={(e) => updateField("base_value", e.target.value)}
                          placeholder="기준값"
                          className="h-8 text-xs sm:h-10 sm:text-sm"
                        />
                      </div>
                      <span className="text-sm font-semibold text-muted-foreground">±</span>
                      <div className="flex-1">
                        <Input
                          type="number"
                          step="any"
                          value={formData.tolerance || ""}
                          onChange={(e) => updateField("tolerance", e.target.value)}
                          placeholder="오차범위"
                          className="h-8 text-xs sm:h-10 sm:text-sm"
                        />
                      </div>
                    </div>

                    <div className="mt-3 flex items-center gap-3 border-t pt-3">
                      <label className="flex shrink-0 cursor-pointer items-center gap-2 text-xs font-medium sm:text-sm">
                        <Checkbox
                          checked={formData.auto_collect === "Y"}
                          onCheckedChange={(checked) => {
                            updateField("auto_collect", checked ? "Y" : "N");
                            if (!checked) updateField("plc_data", "");
                          }}
                        />
                        자동수집
                      </label>
                      <Select
                        value={formData.plc_data || ""}
                        onValueChange={(v) => updateField("plc_data", v)}
                        disabled={formData.auto_collect !== "Y"}
                      >
                        <SelectTrigger className={`h-8 flex-1 text-xs sm:h-10 sm:text-sm ${formData.auto_collect !== "Y" ? "opacity-50" : ""}`}>
                          <SelectValue placeholder="수집데이터 선택" />
                        </SelectTrigger>
                        <SelectContent>
                          {PLC_DATA_OPTIONS.map((p) => (
                            <SelectItem key={p.value} value={p.value}>{p.label}</SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  </div>
                </>
              )}
            </>
          )}

          {/* ============ 작업절차 ============ */}
          {currentType === "procedure" && (
            <>
              <div>
                <Label className="text-xs sm:text-sm">
                  작업 내용 <span className="text-destructive">*</span>
                </Label>
                <Input
                  value={formData.content || ""}
                  onChange={(e) => updateField("content", e.target.value)}
                  placeholder="예: 자재 투입"
                  className="mt-1 h-8 text-xs sm:h-10 sm:text-sm"
                />
              </div>
              <div>
                <Label className="text-xs sm:text-sm">소요 시간 (분)</Label>
                <Input
                  type="number"
                  value={formData.duration_minutes ?? ""}
                  onChange={(e) =>
                    updateField("duration_minutes", e.target.value ? Number(e.target.value) : undefined)
                  }
                  placeholder="예: 5"
                  className="mt-1 h-8 text-xs sm:h-10 sm:text-sm"
                />
              </div>
            </>
          )}

          {/* ============ 직접입력 ============ */}
          {currentType === "input" && (
            <>
              <div>
                <Label className="text-xs sm:text-sm">
                  입력 항목명 <span className="text-destructive">*</span>
                </Label>
                <Input
                  value={formData.content || ""}
                  onChange={(e) => updateField("content", e.target.value)}
                  placeholder="예: 작업자 의견"
                  className="mt-1 h-8 text-xs sm:h-10 sm:text-sm"
                />
              </div>
              <div>
                <Label className="text-xs sm:text-sm">입력 타입</Label>
                <Select
                  value={formData.input_type || "text"}
                  onValueChange={(v) => updateField("input_type", v)}
                >
                  <SelectTrigger className="mt-1 h-8 text-xs sm:h-10 sm:text-sm">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {INPUT_TYPES.map((t) => (
                      <SelectItem key={t.value} value={t.value}>{t.label}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </>
          )}

          {/* ============ 문서참조 ============ */}
          {currentType === "lookup" && (
            <>
              <div className="flex items-center gap-2 rounded-lg border border-blue-200 bg-blue-50 px-3 py-2.5">
                <span className="text-sm">📄</span>
                <span className="text-xs text-blue-800">
                  해당 품목에 등록된 문서를 자동으로 불러옵니다.
                </span>
              </div>
              <div>
                <Label className="text-xs sm:text-sm">참조 문서 목록</Label>
                <div className="mt-1 rounded-lg border p-3">
                  <p className="text-center text-xs text-muted-foreground">
                    품목이 선택되지 않았습니다.
                  </p>
                </div>
              </div>
            </>
          )}

          {/* ============ 설비점검 ============ */}
          {currentType === "equip_inspection" && (
            <>
              <div className="flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-3 py-2.5">
                <span className="text-sm">🏭</span>
                <span className="text-xs text-green-800">
                  공정에 지정된 설비를 자동 참조합니다.
                </span>
              </div>

              <div>
                <Label className="text-xs sm:text-sm">
                  설비점검 적용 <span className="text-destructive">*</span>
                </Label>
                <div className="mt-2 flex gap-4">
                  <label className="flex cursor-pointer items-center gap-2 text-xs sm:text-sm">
                    <input
                      type="radio"
                      name="equipInspApply"
                      checked={formData.equip_inspection_apply === "apply"}
                      onChange={() => updateField("equip_inspection_apply", "apply")}
                      className="h-4 w-4 accent-primary"
                    />
                    적용
                  </label>
                  <label className="flex cursor-pointer items-center gap-2 text-xs sm:text-sm">
                    <input
                      type="radio"
                      name="equipInspApply"
                      checked={formData.equip_inspection_apply === "none"}
                      onChange={() => updateField("equip_inspection_apply", "none")}
                      className="h-4 w-4 accent-primary"
                    />
                    미적용
                  </label>
                </div>
              </div>

              {/* 적용 시: 설비 점검항목 표시 */}
              {formData.equip_inspection_apply === "apply" && (
                <div className="rounded-lg border border-amber-200 bg-amber-50 p-3 space-y-2">
                  <p className="text-xs font-semibold text-amber-800">
                    설비 점검항목 (설비정보 연동)
                  </p>
                  {equipInspLoading ? (
                    <div className="flex items-center gap-2 py-2"><Loader2 className="h-3.5 w-3.5 animate-spin" /><span className="text-[11px] text-muted-foreground">조회 중...</span></div>
                  ) : equipInspItems.length === 0 ? (
                    <p className="text-[11px] text-muted-foreground">해당 공정에 지정된 설비의 점검항목이 없습니다.</p>
                  ) : (
                    <table className="w-full text-[11px]">
                      <thead>
                        <tr className="border-b">
                          <th className="py-1 text-left font-medium text-amber-700">설비코드</th>
                          <th className="py-1 text-left font-medium text-amber-700">점검항목</th>
                          <th className="py-1 text-left font-medium text-amber-700">점검방법</th>
                          <th className="py-1 text-left font-medium text-amber-700">기준범위</th>
                        </tr>
                      </thead>
                      <tbody>
                        {equipInspItems.map((item, idx) => (
                          <tr key={item.id || idx} className="border-b border-amber-100">
                            <td className="py-1 font-mono">{item.equipment_code || "-"}</td>
                            <td className="py-1">{item.inspection_item || "-"}</td>
                            <td className="py-1">{item.inspection_method || "-"}</td>
                            <td className="py-1 font-mono">{item.lower_limit || item.upper_limit ? `${item.lower_limit || ""} ~ ${item.upper_limit || ""}${item.unit ? ` ${item.unit}` : ""}` : "-"}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  )}
                </div>
              )}
            </>
          )}

          {/* ============ 설비조건 ============ */}
          {currentType === "equip_condition" && (
            <>
              <div className="flex items-center gap-2 rounded-lg border border-green-200 bg-green-50 px-3 py-2.5">
                <span className="text-sm">🏭</span>
                <span className="text-xs text-green-800">
                  공정에 지정된 설비를 자동 참조합니다.
                </span>
              </div>

              <div>
                <Label className="text-xs sm:text-sm">
                  설비조건 <span className="text-destructive">*</span>
                </Label>
                <div className="mt-2 rounded-lg border bg-muted/30 p-3 space-y-3">
                  {/* 조건명 + 단위 */}
                  <div className="flex gap-2">
                    <div className="flex-[1.2]">
                      <Input
                        value={formData.content || ""}
                        onChange={(e) => updateField("content", e.target.value)}
                        placeholder="조건명 (예: 온도, 압력, RPM)"
                        className="h-8 text-xs sm:h-10 sm:text-sm"
                      />
                    </div>
                    <div className="flex-[0.6]">
                      <Select
                        value={formData.condition_unit || ""}
                        onValueChange={(v) => updateField("condition_unit", v)}
                      >
                        <SelectTrigger className="h-8 text-xs sm:h-10 sm:text-sm">
                          <SelectValue placeholder="단위" />
                        </SelectTrigger>
                        <SelectContent>
                          {UNIT_OPTIONS.map((u) => (
                            <SelectItem key={u} value={u}>{u}</SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                  </div>

                  {/* 기준값 ± 오차범위 */}
                  <div className="flex items-center gap-2">
                    <div className="flex-1">
                      <Input
                        type="number"
                        step="any"
                        value={formData.condition_base_value || ""}
                        onChange={(e) => updateField("condition_base_value", e.target.value)}
                        placeholder="기준값"
                        className="h-8 text-xs sm:h-10 sm:text-sm"
                      />
                    </div>
                    <span className="text-sm font-semibold text-muted-foreground">±</span>
                    <div className="flex-1">
                      <Input
                        type="number"
                        step="any"
                        value={formData.condition_tolerance || ""}
                        onChange={(e) => updateField("condition_tolerance", e.target.value)}
                        placeholder="오차범위"
                        className="h-8 text-xs sm:h-10 sm:text-sm"
                      />
                    </div>
                  </div>

                  {/* 자동수집 */}
                  <div className="flex items-center gap-3 border-t pt-3">
                    <label className="flex shrink-0 cursor-pointer items-center gap-2 text-xs font-medium sm:text-sm">
                      <Checkbox
                        checked={formData.condition_auto_collect === "Y"}
                        onCheckedChange={(checked) => {
                          updateField("condition_auto_collect", checked ? "Y" : "N");
                          if (!checked) updateField("condition_plc_data", "");
                        }}
                      />
                      자동수집
                    </label>
                    <Select
                      value={formData.condition_plc_data || ""}
                      onValueChange={(v) => updateField("condition_plc_data", v)}
                      disabled={formData.condition_auto_collect !== "Y"}
                    >
                      <SelectTrigger className={`h-8 flex-1 text-xs sm:h-10 sm:text-sm ${formData.condition_auto_collect !== "Y" ? "opacity-50" : ""}`}>
                        <SelectValue placeholder="수집데이터 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {PLC_DATA_OPTIONS.map((p) => (
                          <SelectItem key={p.value} value={p.value}>{p.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              </div>
            </>
          )}

          {/* ============ 실적등록 ============ */}
          {currentType === "production_result" && (
            <div>
              <Label className="text-xs sm:text-sm">실적등록 항목 설정</Label>
              <div className="mt-2 rounded-lg border bg-muted/30 p-3 space-y-0 divide-y">
                {/* 작업수량 */}
                <div className="flex items-center justify-between py-3 first:pt-0">
                  <div className="flex-1">
                    <span className="text-sm font-semibold">📦 작업수량</span>
                    <span className="ml-2 text-[11px] text-muted-foreground">생산된 전체 수량</span>
                  </div>
                  <div className="flex items-center gap-3">
                    <label className="flex shrink-0 cursor-pointer items-center gap-2 text-xs font-medium">
                      <Checkbox
                        checked={formData.work_qty_auto_collect === "Y"}
                        onCheckedChange={(checked) => {
                          updateField("work_qty_auto_collect", checked ? "Y" : "N");
                          if (!checked) updateField("work_qty_plc_data", "");
                        }}
                      />
                      자동수집
                    </label>
                    <Select
                      value={formData.work_qty_plc_data || ""}
                      onValueChange={(v) => updateField("work_qty_plc_data", v)}
                      disabled={formData.work_qty_auto_collect !== "Y"}
                    >
                      <SelectTrigger className={`h-8 w-[180px] text-xs ${formData.work_qty_auto_collect !== "Y" ? "opacity-50" : ""}`}>
                        <SelectValue placeholder="수집데이터 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {PLC_PRODUCTION_OPTIONS.work_qty.map((p) => (
                          <SelectItem key={p.value} value={p.value}>{p.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>

                {/* 불량수량 */}
                <div className="flex items-center justify-between py-3">
                  <div className="flex-1">
                    <span className="text-sm font-semibold">🚫 불량수량</span>
                    <span className="ml-2 text-[11px] text-muted-foreground">불량으로 판정된 수량</span>
                  </div>
                  <div className="flex items-center gap-3">
                    <label className="flex shrink-0 cursor-pointer items-center gap-2 text-xs font-medium">
                      <Checkbox
                        checked={formData.defect_qty_auto_collect === "Y"}
                        onCheckedChange={(checked) => {
                          updateField("defect_qty_auto_collect", checked ? "Y" : "N");
                          if (!checked) updateField("defect_qty_plc_data", "");
                        }}
                      />
                      자동수집
                    </label>
                    <Select
                      value={formData.defect_qty_plc_data || ""}
                      onValueChange={(v) => updateField("defect_qty_plc_data", v)}
                      disabled={formData.defect_qty_auto_collect !== "Y"}
                    >
                      <SelectTrigger className={`h-8 w-[180px] text-xs ${formData.defect_qty_auto_collect !== "Y" ? "opacity-50" : ""}`}>
                        <SelectValue placeholder="수집데이터 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {PLC_PRODUCTION_OPTIONS.defect_qty.map((p) => (
                          <SelectItem key={p.value} value={p.value}>{p.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>

                {/* 양품수량 */}
                <div className="flex items-center justify-between py-3 last:pb-0">
                  <div className="flex-1">
                    <span className="text-sm font-semibold">✅ 양품수량</span>
                    <span className="ml-2 text-[11px] text-muted-foreground">작업수량 - 불량수량</span>
                  </div>
                  <div className="flex items-center gap-3">
                    <label className="flex shrink-0 cursor-pointer items-center gap-2 text-xs font-medium">
                      <Checkbox
                        checked={formData.good_qty_auto_collect === "Y"}
                        onCheckedChange={(checked) => {
                          updateField("good_qty_auto_collect", checked ? "Y" : "N");
                          if (!checked) updateField("good_qty_plc_data", "");
                        }}
                      />
                      자동수집
                    </label>
                    <Select
                      value={formData.good_qty_plc_data || ""}
                      onValueChange={(v) => updateField("good_qty_plc_data", v)}
                      disabled={formData.good_qty_auto_collect !== "Y"}
                    >
                      <SelectTrigger className={`h-8 w-[180px] text-xs ${formData.good_qty_auto_collect !== "Y" ? "opacity-50" : ""}`}>
                        <SelectValue placeholder="수집데이터 선택" />
                      </SelectTrigger>
                      <SelectContent>
                        {PLC_PRODUCTION_OPTIONS.good_qty.map((p) => (
                          <SelectItem key={p.value} value={p.value}>{p.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* ============ 자재투입 ============ */}
          {currentType === "material_input" && (
            <div>
              <Label className="text-xs sm:text-sm">자재투입 설정</Label>
              <div className="mt-2 rounded-lg border border-sky-200 bg-sky-50 p-3">
                <div className="mb-2 flex items-center justify-between">
                  <p className="text-xs font-semibold text-sky-800">
                    📦 BOM 구성 자재 (자동 연동)
                  </p>
                  <span className="text-[11px] text-muted-foreground">
                    {bomMaterials.length > 0 ? `${bomMaterials.length}건` : ""}
                  </span>
                </div>
                {bomMaterials.length > 0 && (
                  <div className="mb-2 flex items-center gap-2 rounded border bg-white px-3 py-2">
                    <Checkbox
                      checked={
                        bomChecked.size === bomMaterials.length
                          ? true
                          : bomChecked.size > 0
                          ? "indeterminate"
                          : false
                      }
                      onCheckedChange={(checked) => {
                        if (checked) {
                          setBomChecked(new Set(bomMaterials.map((m) => m.id)));
                        } else {
                          setBomChecked(new Set());
                        }
                      }}
                    />
                    <span className="text-xs font-medium">
                      전체 선택 ({bomChecked.size} / {bomMaterials.length})
                    </span>
                  </div>
                )}
                <div className="max-h-[300px] overflow-y-auto rounded-lg border bg-white">
                  {bomLoading ? (
                    <div className="flex items-center justify-center gap-2 py-6">
                      <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
                      <span className="text-xs text-muted-foreground">BOM 데이터를 불러오는 중...</span>
                    </div>
                  ) : !selectedItemCode ? (
                    <div className="py-5 text-center text-xs text-muted-foreground">
                      품목을 먼저 선택하세요.
                    </div>
                  ) : bomMaterials.length === 0 ? (
                    <div className="py-5 text-center text-xs text-muted-foreground">
                      해당 품목의 BOM 구성 자재가 없습니다.
                    </div>
                  ) : (
                    bomMaterials.map((mat) => {
                      const resolvedType = itemTypeCatMap[mat.child_item_type || ""] || mat.child_item_type || "";
                      const typeColor =
                        resolvedType.includes("원자재") ? "#16a34a"
                        : resolvedType.includes("반제품") ? "#2563eb"
                        : resolvedType.includes("제품") ? "#9333ea"
                        : "#6b7280";
                      return (
                        <div
                          key={mat.id}
                          className="flex items-center gap-2.5 border-b px-3 py-2.5 last:border-b-0 hover:bg-sky-50/50"
                        >
                          <Checkbox
                            checked={bomChecked.has(mat.id)}
                            onCheckedChange={(checked) => {
                              setBomChecked((prev) => {
                                const next = new Set(prev);
                                if (checked) next.add(mat.id);
                                else next.delete(mat.id);
                                return next;
                              });
                            }}
                          />
                          <div className="min-w-0 flex-1">
                            <div className="flex items-center gap-1.5">
                              {mat.child_item_type && (
                                <span
                                  className="rounded px-1.5 py-0.5 text-[10px] font-semibold text-white"
                                  style={{ backgroundColor: typeColor }}
                                >
                                  {resolvedType}
                                </span>
                              )}
                              <span className="text-[11px] text-muted-foreground">
                                {mat.child_item_code || "-"}
                              </span>
                              <span className="text-xs font-medium">
                                {mat.child_item_name || "(이름 없음)"}
                              </span>
                            </div>
                            <div className="mt-0.5 text-[11px] text-muted-foreground">
                              소요량: {mat.quantity || "0"} {mat.detail_unit || mat.item_unit || ""}
                              {mat.process_type ? ` | 공정: ${mat.process_type}` : ""}
                            </div>
                          </div>
                        </div>
                      );
                    })
                  )}
                </div>
              </div>
            </div>
          )}

          {/* 필수 여부 (모든 유형 공통) */}
          {currentType && (
            <div>
              <Label className="text-xs sm:text-sm">필수 여부</Label>
              <Select
                value={formData.is_required || "Y"}
                onValueChange={(v) => updateField("is_required", v)}
              >
                <SelectTrigger className="mt-1 h-8 text-xs sm:h-10 sm:text-sm">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="Y">필수</SelectItem>
                  <SelectItem value="N">선택</SelectItem>
                </SelectContent>
              </Select>
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={onClose}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            취소
          </Button>
          <Button
            onClick={handleSubmit}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            {mode === "add" ? "추가" : "수정"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ============================================================
// 메인 모달
// ============================================================
export function WorkStandardEditModal({
  open,
  onClose,
  workInstructionNo,
  routingVersionId,
  routingName,
  itemName,
  itemCode,
}: WorkStandardEditModalProps) {
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [processes, setProcesses] = useState<WIWorkStandardProcess[]>([]);
  const [isCustom, setIsCustom] = useState(false);
  const [selectedProcessIdx, setSelectedProcessIdx] = useState(0);
  const [selectedWorkItemIdByPhase, setSelectedWorkItemIdByPhase] = useState<Record<string, string | null>>({});
  const [dirty, setDirty] = useState(false);

  // 작업항목 추가/수정 모달
  const [addItemOpen, setAddItemOpen] = useState(false);
  const [addItemPhase, setAddItemPhase] = useState("PRE");
  const [addItemTitle, setAddItemTitle] = useState("");
  const [addItemRequired, setAddItemRequired] = useState("Y");
  const [editingWorkItem, setEditingWorkItem] = useState<WIWorkItem | null>(null);

  // 상세 추가/수정 모달
  const [detailModalOpen, setDetailModalOpen] = useState(false);
  const [detailModalMode, setDetailModalMode] = useState<"add" | "edit">("add");
  const [detailModalPhase, setDetailModalPhase] = useState("PRE");
  const [editingDetail, setEditingDetail] = useState<WIWorkItemDetail | null>(null);

  // 드래그 정렬용 state (phase + workItem 조합으로 스코프 관리)
  const [dragIdx, setDragIdx] = useState<number | null>(null);
  const [overIdx, setOverIdx] = useState<number | null>(null);

  // 데이터 로드
  const loadData = useCallback(async () => {
    if (!workInstructionNo || !routingVersionId) return;
    setLoading(true);
    try {
      const res = await getWIWorkStandard(workInstructionNo, routingVersionId);
      if (res.success && res.data) {
        setProcesses(res.data.processes);
        setIsCustom(res.data.isCustom);
        setSelectedProcessIdx(0);
        setSelectedWorkItemIdByPhase({});
        setDirty(false);
      }
    } catch (err) {
      console.error("공정작업기준 로드 실패", err);
    } finally {
      setLoading(false);
    }
  }, [workInstructionNo, routingVersionId]);

  useEffect(() => {
    if (open) loadData();
  }, [open, loadData]);

  const currentProcess = processes[selectedProcessIdx] || null;

  // Phase별 작업항목 그룹핑 (MAIN을 IN으로 매핑)
  const workItemsByPhase = useMemo(() => {
    if (!currentProcess) return {};
    const map: Record<string, WIWorkItem[]> = {};
    for (const phase of PHASES) {
      map[phase.key] = currentProcess.workItems.filter(
        wi => wi.work_phase === phase.key || (phase.key === "IN" && wi.work_phase === "MAIN")
      );
    }
    return map;
  }, [currentProcess]);

  // 커스텀 전환 — 로컬 마킹만 수행 (TASK:ERP-012 수정분 보존)
  // 기존에는 copyWorkStandard API 호출 + loadData()로 state 전면 재로딩을 해서
  //   closure로 잡은 workItem id / detail id가 모두 stale해져서
  //   ① 삭제가 무효화되어 UI상 상세가 0개로 보이고
  //   ② 추가 state 변경이 반영되지 않아 저장이 먹통이 됨.
  // saveWIWorkStandard는 DELETE→INSERT 방식으로 전체 덮어쓰므로 사전 복사 불필요.
  const ensureCustom = useCallback(async () => {
    if (!isCustom) setIsCustom(true);
    return true;
  }, [isCustom]);

  // 작업항목 추가 모달 열기
  const openAddWorkItem = useCallback((phaseKey: string) => {
    setAddItemPhase(phaseKey);
    setAddItemTitle("");
    setAddItemRequired("N");
    setEditingWorkItem(null);
    setAddItemOpen(true);
  }, []);

  // 작업항목 수정 모달 열기
  const openEditWorkItem = useCallback((item: WIWorkItem) => {
    setAddItemPhase(item.work_phase);
    setAddItemTitle(item.title);
    setAddItemRequired(item.is_required);
    setEditingWorkItem(item);
    setAddItemOpen(true);
  }, []);

  // 작업항목 추가/수정 처리
  const handleSaveWorkItem = useCallback(async () => {
    if (!addItemTitle.trim()) { toast.error("제목을 입력하세요"); return; }
    const ok = await ensureCustom();
    if (!ok || !currentProcess) return;

    if (editingWorkItem) {
      setProcesses(prev => {
        const next = [...prev];
        const workItems = [...next[selectedProcessIdx].workItems];
        const idx = workItems.findIndex(wi => wi.id === editingWorkItem.id);
        if (idx >= 0) {
          workItems[idx] = { ...workItems[idx], title: addItemTitle.trim(), is_required: addItemRequired };
        }
        next[selectedProcessIdx] = { ...next[selectedProcessIdx], workItems };
        return next;
      });
    } else {
      const phaseKey = addItemPhase === "IN" ? "IN" : addItemPhase;
      const phaseItems = currentProcess.workItems.filter(
        wi => wi.work_phase === phaseKey || (phaseKey === "IN" && wi.work_phase === "MAIN")
      );
      const newItem: WIWorkItem = {
        id: `temp-${Date.now()}`,
        routing_detail_id: currentProcess.routing_detail_id,
        work_phase: phaseKey,
        title: addItemTitle.trim(),
        is_required: addItemRequired,
        sort_order: phaseItems.length + 1,
        details: [],
      };

      setProcesses(prev => {
        const next = [...prev];
        next[selectedProcessIdx] = {
          ...next[selectedProcessIdx],
          workItems: [...next[selectedProcessIdx].workItems, newItem],
        };
        return next;
      });

      setSelectedWorkItemIdByPhase(prev => ({ ...prev, [addItemPhase]: newItem.id! }));
    }

    setAddItemOpen(false);
    setDirty(true);
  }, [addItemTitle, addItemRequired, addItemPhase, ensureCustom, currentProcess, selectedProcessIdx, editingWorkItem]);

  // 작업항목 삭제
  const handleDeleteWorkItem = useCallback(async (id: string, phaseKey: string) => {
    const ok = await ensureCustom();
    if (!ok) return;

    setProcesses(prev => {
      const next = [...prev];
      next[selectedProcessIdx] = {
        ...next[selectedProcessIdx],
        workItems: next[selectedProcessIdx].workItems.filter(wi => wi.id !== id),
      };
      return next;
    });
    if (selectedWorkItemIdByPhase[phaseKey] === id) {
      setSelectedWorkItemIdByPhase(prev => ({ ...prev, [phaseKey]: null }));
    }
    setDirty(true);
  }, [ensureCustom, selectedProcessIdx, selectedWorkItemIdByPhase]);

  // 상세 추가 모달 열기
  const openAddDetail = useCallback((phaseKey: string) => {
    setDetailModalPhase(phaseKey);
    setDetailModalMode("add");
    setEditingDetail(null);
    setDetailModalOpen(true);
  }, []);

  // 상세 수정 모달 열기
  const openEditDetail = useCallback((detail: WIWorkItemDetail, phaseKey: string) => {
    setDetailModalPhase(phaseKey);
    setDetailModalMode("edit");
    setEditingDetail(detail);
    setDetailModalOpen(true);
  }, []);

  // 상세 추가 처리 — 다중행 자동생성 대응 (DetailFormModalInner의 onSubmit이 for-loop로 여러 번 호출)
  const handleAddDetailRow = useCallback((data: Partial<WIWorkItemDetail>) => {
    const workItemId = selectedWorkItemIdByPhase[detailModalPhase];
    if (!workItemId) return;

    setProcesses(prev => {
      const next = [...prev];
      const workItems = [...next[selectedProcessIdx].workItems];
      const wiIdx = workItems.findIndex(wi => wi.id === workItemId);
      if (wiIdx < 0) return prev;

      const currentDetails = workItems[wiIdx].details || [];
      const newDetail: WIWorkItemDetail = {
        ...data,
        id: `temp-detail-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
        work_item_id: workItemId,
        sort_order: currentDetails.length + 1,
      };
      workItems[wiIdx] = {
        ...workItems[wiIdx],
        details: [...currentDetails, newDetail],
        detail_count: currentDetails.length + 1,
      };
      next[selectedProcessIdx] = { ...next[selectedProcessIdx], workItems };
      return next;
    });
    setDirty(true);
  }, [detailModalPhase, selectedWorkItemIdByPhase, selectedProcessIdx]);

  // 상세 수정 처리
  const handleUpdateDetailRow = useCallback((data: Partial<WIWorkItemDetail>) => {
    const workItemId = selectedWorkItemIdByPhase[detailModalPhase];
    if (!workItemId || !editingDetail) return;

    setProcesses(prev => {
      const next = [...prev];
      const workItems = [...next[selectedProcessIdx].workItems];
      const wiIdx = workItems.findIndex(wi => wi.id === workItemId);
      if (wiIdx < 0) return prev;

      // 같은 유형의 apply 그룹 전체 일괄 업데이트 (필수여부 등) — 원본 WorkItemDetailList 로직과 동일
      const isApplyGroup =
        (editingDetail.detail_type === "inspection" && editingDetail.process_inspection_apply === "apply") ||
        (editingDetail.detail_type === "equip_inspection" && editingDetail.equip_inspection_apply === "apply") ||
        editingDetail.detail_type === "material_input";

      if (isApplyGroup && data.is_required !== undefined) {
        const details = (workItems[wiIdx].details || []).map(d => {
          const isSibling =
            d.detail_type === editingDetail.detail_type && (
              d.detail_type === "inspection" ? d.process_inspection_apply === "apply" :
              d.detail_type === "equip_inspection" ? d.equip_inspection_apply === "apply" :
              d.detail_type === "material_input"
            );
          return isSibling ? { ...d, is_required: data.is_required! } : d;
        });
        workItems[wiIdx] = { ...workItems[wiIdx], details };
      } else {
        const details = (workItems[wiIdx].details || []).map(d =>
          d.id === editingDetail.id ? { ...d, ...data } : d
        );
        workItems[wiIdx] = { ...workItems[wiIdx], details };
      }
      next[selectedProcessIdx] = { ...next[selectedProcessIdx], workItems };
      return next;
    });
    setDirty(true);
  }, [detailModalPhase, selectedWorkItemIdByPhase, selectedProcessIdx, editingDetail]);

  // DetailFormModalInner onSubmit 분기 진입점
  const handleDetailSubmit = useCallback(async (data: Partial<WIWorkItemDetail>) => {
    const ok = await ensureCustom();
    if (!ok) return;
    if (detailModalMode === "add") {
      handleAddDetailRow(data);
    } else {
      handleUpdateDetailRow(data);
    }
  }, [detailModalMode, handleAddDetailRow, handleUpdateDetailRow, ensureCustom]);

  // 상세 삭제
  const handleDeleteDetail = useCallback(async (detailId: string, phaseKey: string) => {
    const workItemId = selectedWorkItemIdByPhase[phaseKey];
    if (!workItemId) return;
    const ok = await ensureCustom();
    if (!ok) return;

    setProcesses(prev => {
      const next = [...prev];
      const workItems = [...next[selectedProcessIdx].workItems];
      const wiIdx = workItems.findIndex(wi => wi.id === workItemId);
      if (wiIdx >= 0) {
        workItems[wiIdx] = {
          ...workItems[wiIdx],
          details: (workItems[wiIdx].details || []).filter(d => d.id !== detailId),
          detail_count: Math.max(0, (workItems[wiIdx].detail_count || 1) - 1),
        };
      }
      next[selectedProcessIdx] = { ...next[selectedProcessIdx], workItems };
      return next;
    });
    setDirty(true);
  }, [selectedWorkItemIdByPhase, ensureCustom, selectedProcessIdx]);

  // 드래그 정렬 — 상세 목록 순서 변경
  const handleReorderDetails = useCallback((phaseKey: string, reordered: WIWorkItemDetail[]) => {
    const workItemId = selectedWorkItemIdByPhase[phaseKey];
    if (!workItemId) return;
    setProcesses(prev => {
      const next = [...prev];
      const workItems = [...next[selectedProcessIdx].workItems];
      const wiIdx = workItems.findIndex(wi => wi.id === workItemId);
      if (wiIdx >= 0) {
        // sort_order 재할당
        const withOrder = reordered.map((d, i) => ({ ...d, sort_order: i + 1 }));
        workItems[wiIdx] = { ...workItems[wiIdx], details: withOrder };
      }
      next[selectedProcessIdx] = { ...next[selectedProcessIdx], workItems };
      return next;
    });
    setDirty(true);
  }, [selectedWorkItemIdByPhase, selectedProcessIdx]);

  // 저장
  const handleSave = useCallback(async () => {
    if (!currentProcess) return;
    setSaving(true);
    try {
      const ok = await ensureCustom();
      if (!ok) return;

      const res = await saveWIWorkStandard(
        workInstructionNo,
        currentProcess.routing_detail_id,
        currentProcess.workItems
      );
      if (res.success) {
        toast.success("공정작업기준이 저장되었습니다");
        setDirty(false);
        await loadData();
      } else {
        toast.error("저장에 실패했습니다");
      }
    } catch {
      toast.error("저장 중 오류가 발생했습니다");
    } finally {
      setSaving(false);
    }
  }, [currentProcess, ensureCustom, workInstructionNo, loadData]);

  // 원본으로 초기화
  const handleReset = useCallback(async () => {
    if (!confirm("커스터마이징한 내용을 모두 삭제하고 원본으로 되돌리시겠습니까?")) return;
    try {
      const res = await resetWIWorkStandard(workInstructionNo);
      if (res.success) {
        toast.success("원본으로 초기화되었습니다");
        await loadData();
      }
    } catch {
      toast.error("초기화에 실패했습니다");
    }
  }, [workInstructionNo, loadData]);

  return (
    <Dialog open={open} onOpenChange={v => { if (!v) onClose(); }}>
      <DialogContent className="max-w-[95vw] sm:max-w-[1200px] h-[85vh] flex flex-col p-0 gap-0">
        <DialogHeader className="px-6 py-4 border-b shrink-0">
          <DialogTitle className="text-base flex items-center gap-2">
            <ClipboardCheck className="w-4 h-4" />
            공정작업기준 수정 - {itemName}
            {routingName && <Badge variant="secondary" className="text-xs ml-2">{routingName}</Badge>}
            {isCustom && <Badge variant="outline" className="text-xs ml-1 border-amber-300 text-amber-700">커스텀</Badge>}
          </DialogTitle>
          <DialogDescription className="text-xs">
            작업지시 [{workInstructionNo}]에 대한 공정작업기준을 수정합니다. 원본에 영향을 주지 않습니다.
          </DialogDescription>
        </DialogHeader>

        {loading ? (
          <div className="flex-1 flex items-center justify-center">
            <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
          </div>
        ) : processes.length === 0 ? (
          <div className="flex-1 flex flex-col items-center justify-center text-muted-foreground">
            <AlertCircle className="w-10 h-10 mb-3 opacity-30" />
            <p className="text-sm">라우팅에 등록된 공정이 없습니다</p>
          </div>
        ) : (
          <div className="flex-1 flex flex-col overflow-hidden">
            {/* 공정 탭 */}
            <div className="flex items-center gap-1 px-4 py-2 border-b bg-muted/30 overflow-x-auto shrink-0">
              {processes.map((proc, idx) => (
                <Button
                  key={proc.routing_detail_id}
                  variant={selectedProcessIdx === idx ? "default" : "ghost"}
                  size="sm"
                  className={cn("text-xs shrink-0 h-8", selectedProcessIdx === idx && "shadow-sm")}
                  onClick={() => {
                    setSelectedProcessIdx(idx);
                    setSelectedWorkItemIdByPhase({});
                  }}
                >
                  <span className="mr-1.5 font-mono text-[10px] opacity-70">{proc.seq_no}.</span>
                  {proc.process_name}
                  {proc.workItems.length > 0 && (
                    <Badge variant="secondary" className="ml-1.5 text-[10px] h-4 px-1">{proc.workItems.length}</Badge>
                  )}
                </Button>
              ))}
            </div>

            {/* Phase별 세로 섹션 */}
            <div className="flex-1 overflow-y-auto space-y-4 p-4">
              {PHASES.map(phase => {
                const phaseItems = workItemsByPhase[phase.key] || [];
                const selectedWiId = selectedWorkItemIdByPhase[phase.key] || null;
                const selectedWi = phaseItems.find(wi => wi.id === selectedWiId) || null;
                const selectedDetails = selectedWi?.details || [];

                return (
                  <div key={phase.key} className="rounded-lg border bg-card">
                    {/* 섹션 헤더 */}
                    <div className="flex items-center justify-between border-b px-4 py-2.5">
                      <div className="flex items-center gap-2">
                        <h3 className="text-sm font-semibold">{phase.label}</h3>
                        <Badge variant="secondary" className="h-5 rounded-full px-2 text-[10px]">
                          {phaseItems.length}개 항목
                        </Badge>
                      </div>
                      <Button
                        variant="outline"
                        size="sm"
                        className="h-7 gap-1 text-xs"
                        onClick={() => openAddWorkItem(phase.key)}
                      >
                        <Plus className="h-3 w-3" />
                        작업항목 추가
                      </Button>
                    </div>

                    {/* 좌우 분할 */}
                    <div className="flex min-h-[140px]">
                      {/* 좌측: 240px 작업항목 카드 */}
                      <div className="w-[240px] shrink-0 border-r p-2">
                        {phaseItems.length === 0 ? (
                          <div className="flex flex-col items-center justify-center py-6 text-center">
                            <ClipboardList className="mb-1 h-6 w-6 text-muted-foreground/40" />
                            <p className="text-[11px] text-muted-foreground">등록된 항목이 없습니다</p>
                          </div>
                        ) : (
                          <div className="space-y-1.5">
                            {phaseItems.map(item => (
                              <div
                                key={item.id}
                                onClick={() => setSelectedWorkItemIdByPhase(prev => ({ ...prev, [phase.key]: item.id! }))}
                                className={cn(
                                  "group flex cursor-pointer items-start gap-2 rounded-lg border p-3 transition-all",
                                  "hover:border-primary/30 hover:shadow-sm",
                                  selectedWiId === item.id
                                    ? "border-primary bg-primary/5 shadow-sm"
                                    : "border-border bg-card"
                                )}
                              >
                                <GripVertical className="mt-0.5 h-4 w-4 shrink-0 text-muted-foreground/50" />
                                <div className="min-w-0 flex-1">
                                  <div className="flex items-center gap-2">
                                    <span className="truncate text-sm font-medium">{item.title}</span>
                                  </div>
                                  <div className="mt-1 flex items-center gap-2">
                                    <Badge variant="secondary" className="h-5 px-1.5 text-[10px] font-normal">
                                      {item.details?.length || item.detail_count || 0}개
                                    </Badge>
                                  </div>
                                </div>
                                <div className="flex shrink-0 gap-0.5 opacity-0 transition-opacity group-hover:opacity-100">
                                  <Button
                                    variant="ghost" size="icon" className="h-6 w-6"
                                    onClick={e => { e.stopPropagation(); openEditWorkItem(item); }}
                                  >
                                    <Pencil className="h-3 w-3" />
                                  </Button>
                                  <Button
                                    variant="ghost" size="icon" className="h-6 w-6 text-destructive hover:text-destructive"
                                    onClick={e => { e.stopPropagation(); handleDeleteWorkItem(item.id!, phase.key); }}
                                  >
                                    <Trash2 className="h-3 w-3" />
                                  </Button>
                                </div>
                              </div>
                            ))}
                          </div>
                        )}
                      </div>

                      {/* 우측: 상세 테이블 — 드래그 정렬 지원 */}
                      <div className="flex-1 flex flex-col">
                        {!selectedWi ? (
                          <div className="flex h-full flex-col items-center justify-center text-center">
                            <p className="text-sm text-muted-foreground">왼쪽에서 항목을 선택하세요</p>
                          </div>
                        ) : (
                          <>
                            {/* 상세 헤더 */}
                            <div className="flex items-center justify-between border-b px-4 py-2">
                              <div className="flex items-center gap-2">
                                <span className="text-sm font-semibold">{selectedWi.title}</span>
                                <Badge variant="secondary" className="text-[10px]">
                                  {selectedDetails.length}개
                                </Badge>
                              </div>
                              <Button
                                variant="outline" size="sm" className="h-7 gap-1 text-xs"
                                onClick={() => openAddDetail(phase.key)}
                              >
                                <Plus className="h-3 w-3" />
                                상세 추가
                              </Button>
                            </div>

                            {/* 테이블 */}
                            <div className="flex-1 overflow-y-auto">
                              <table className="w-full text-xs">
                                <thead className="sticky top-0 bg-muted/50">
                                  <tr className="border-b">
                                    <th className="w-8 px-1 py-2"></th>
                                    <th className="w-12 px-2 py-2 text-center font-medium text-muted-foreground">순서</th>
                                    <th className="w-24 px-2 py-2 text-left font-medium text-muted-foreground">유형</th>
                                    <th className="px-2 py-2 text-left font-medium text-muted-foreground">내용</th>
                                    <th className="w-14 px-2 py-2 text-center font-medium text-muted-foreground">필수</th>
                                    <th className="w-16 px-2 py-2 text-center font-medium text-muted-foreground">관리</th>
                                  </tr>
                                </thead>
                                <tbody>
                                  {selectedDetails.map((detail, idx) => (
                                    <tr
                                      key={detail.id || idx}
                                      draggable
                                      onDragStart={() => setDragIdx(idx)}
                                      onDragOver={(e) => {
                                        e.preventDefault();
                                        if (dragIdx !== null && dragIdx !== idx) setOverIdx(idx);
                                      }}
                                      onDrop={(e) => {
                                        e.preventDefault();
                                        if (dragIdx === null || dragIdx === idx) {
                                          setDragIdx(null); setOverIdx(null); return;
                                        }
                                        const next = [...selectedDetails];
                                        const [moved] = next.splice(dragIdx, 1);
                                        next.splice(idx, 0, moved);
                                        handleReorderDetails(phase.key, next);
                                        setDragIdx(null); setOverIdx(null);
                                      }}
                                      onDragEnd={() => { setDragIdx(null); setOverIdx(null); }}
                                      className={cn(
                                        "border-b transition-colors hover:bg-muted/30",
                                        dragIdx === idx && "opacity-50",
                                        overIdx === idx && "bg-primary/5"
                                      )}
                                    >
                                      <td className="px-1 py-1.5 text-center">
                                        <GripVertical className="inline-block h-3 w-3 cursor-grab text-muted-foreground/50" />
                                      </td>
                                      <td className="px-2 py-1.5 text-center text-muted-foreground">{idx + 1}</td>
                                      <td className="px-2 py-1.5">
                                        <Badge variant="outline" className="text-[10px] font-normal whitespace-nowrap">
                                          {getDetailTypeLabel(detail.detail_type || "checklist")}
                                        </Badge>
                                      </td>
                                      <td className="px-2 py-1.5">{getContentSummary(detail)}</td>
                                      <td className="px-2 py-1.5 text-center">
                                        <Badge
                                          variant={detail.is_required === "Y" ? "default" : "secondary"}
                                          className="text-[10px] font-normal"
                                        >
                                          {detail.is_required === "Y" ? "필수" : "선택"}
                                        </Badge>
                                      </td>
                                      <td className="px-2 py-1.5 text-center">
                                        <div className="flex justify-center gap-0.5">
                                          <Button
                                            variant="ghost" size="icon" className="h-6 w-6"
                                            onClick={() => openEditDetail(detail, phase.key)}
                                          >
                                            <Pencil className="h-3 w-3" />
                                          </Button>
                                          <Button
                                            variant="ghost" size="icon" className="h-6 w-6 text-destructive hover:text-destructive"
                                            onClick={() => handleDeleteDetail(detail.id!, phase.key)}
                                          >
                                            <Trash2 className="h-3 w-3" />
                                          </Button>
                                        </div>
                                      </td>
                                    </tr>
                                  ))}
                                </tbody>
                              </table>

                              {selectedDetails.length === 0 && (
                                <div className="flex flex-col items-center justify-center py-8 text-center">
                                  <p className="text-xs text-muted-foreground">
                                    상세 항목이 없습니다. &quot;상세 추가&quot; 버튼을 클릭하여 추가하세요.
                                  </p>
                                </div>
                              )}
                            </div>
                          </>
                        )}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        <DialogFooter className="px-6 py-3 border-t shrink-0 flex items-center justify-between">
          <div>
            {isCustom && (
              <Button variant="outline" size="sm" className="text-xs" onClick={handleReset}>
                <RotateCcw className="w-3.5 h-3.5 mr-1.5" /> 원본으로 초기화
              </Button>
            )}
          </div>
          <div className="flex items-center gap-2">
            <Button variant="outline" onClick={onClose}>닫기</Button>
            <Button onClick={handleSave} disabled={saving || (!dirty && isCustom)}>
              {saving ? <Loader2 className="w-4 h-4 mr-1.5 animate-spin" /> : <Save className="w-4 h-4 mr-1.5" />}
              저장
            </Button>
          </div>
        </DialogFooter>

        {/* 작업항목 추가/수정 다이얼로그 */}
        <Dialog open={addItemOpen} onOpenChange={setAddItemOpen}>
          <DialogContent className="max-w-[95vw] sm:max-w-[400px]" onClick={e => e.stopPropagation()}>
            <DialogHeader>
              <DialogTitle className="text-base">
                작업항목 {editingWorkItem ? "수정" : "추가"}
              </DialogTitle>
              <DialogDescription className="text-xs">
                {PHASES.find(p => p.key === addItemPhase)?.label} 단계에 작업항목을 {editingWorkItem ? "수정" : "추가"}합니다.
              </DialogDescription>
            </DialogHeader>
            <div className="space-y-3">
              <div>
                <Label className="text-xs">제목 *</Label>
                <Input value={addItemTitle} onChange={e => setAddItemTitle(e.target.value)} placeholder="작업항목 제목" className="h-8 text-xs mt-1" />
              </div>
            </div>
            <DialogFooter className="gap-2">
              <Button variant="outline" size="sm" onClick={() => setAddItemOpen(false)}>취소</Button>
              <Button size="sm" onClick={handleSaveWorkItem}>{editingWorkItem ? "수정" : "추가"}</Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>

        {/* 상세 추가/수정 다이얼로그 — 원본 DetailFormModal 로직을 이식 */}
        <DetailFormModalInner
          open={detailModalOpen}
          onClose={() => setDetailModalOpen(false)}
          onSubmit={handleDetailSubmit}
          editData={editingDetail}
          mode={detailModalMode}
          selectedItemCode={itemCode}
          selectedProcessCode={currentProcess?.process_code}
        />
      </DialogContent>
    </Dialog>
  );
}
