"use client";

/**
 * 금형정보 — Type E 카드리스트형
 *
 * 좌측: 금형 카드 리스트 (이미지 + 코드 + 이름 + 유형뱃지 + 수명진행률)
 * 우측: 금형 상세 + 탭 3개 (일련번호 / 점검항목 / 부품)
 * 전용 API: /molds/*
 */

import React, { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import {
  Plus, Trash2, Loader2, Pencil, Box, Inbox, Search,
  Wrench, ClipboardCheck, Package, LayoutGrid, List,
  Image as ImageIcon, Upload, X as XIcon,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { previewNumberingCode, allocateNumberingCode } from "@/lib/api/numberingRule";
import { ImageUpload } from "@/components/common/ImageUpload";
import { useAuth } from "@/hooks/useAuth";
import { toast } from "sonner";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";

// ─── API base ───
const API = "/mold";

// ─── 상태/유형 매핑 ───
const STATUS_MAP: Record<string, { label: string; variant: "default" | "secondary" | "destructive" | "outline" }> = {
  ACTIVE: { label: "사용중", variant: "default" },
  INSPECTION: { label: "점검중", variant: "secondary" },
  REPAIR: { label: "수리중", variant: "outline" },
  DISPOSED: { label: "폐기", variant: "destructive" },
};

const SERIAL_STATUS_MAP: Record<string, { label: string; variant: "default" | "secondary" | "destructive" | "outline" }> = {
  IN_USE: { label: "사용중", variant: "default" },
  STORED: { label: "보관중", variant: "secondary" },
  REPAIR: { label: "수리중", variant: "outline" },
  DISPOSED: { label: "폐기", variant: "destructive" },
};

// ─── 수명 진행률 색상 ───
function getProgressColor(pct: number) {
  if (pct < 60) return "bg-success";
  if (pct < 85) return "bg-warning";
  return "bg-destructive";
}

function getProgressTextColor(pct: number) {
  if (pct < 60) return "text-success";
  if (pct < 85) return "text-warning";
  return "text-destructive";
}

export default function MoldInfoPage() {
  const { user } = useAuth();
  const { confirm, ConfirmDialogComponent } = useConfirmDialog();

  // ─── 좌측: 금형 목록 ───
  const [molds, setMolds] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [selectedMoldCode, setSelectedMoldCode] = useState<string | null>(null);
  const [viewMode, setViewMode] = useState<"list" | "grid">("list");

  // ─── 검색 필터 ───
  const [filterCode, setFilterCode] = useState("");
  const [filterName, setFilterName] = useState("");
  const [filterType, setFilterType] = useState("");
  const [filterStatus, setFilterStatus] = useState("");

  // ─── 우측: 상세 ───
  const [detail, setDetail] = useState<any>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [serialSummary, setSerialSummary] = useState<any>(null);
  const [rightTab, setRightTab] = useState("serial");

  // ─── 일련번호 ───
  const [serials, setSerials] = useState<any[]>([]);
  const [serialLoading, setSerialLoading] = useState(false);

  // ─── 점검항목 ───
  const [inspections, setInspections] = useState<any[]>([]);
  const [inspectionLoading, setInspectionLoading] = useState(false);

  // ─── 부품 ───
  const [parts, setParts] = useState<any[]>([]);
  const [partLoading, setPartLoading] = useState(false);

  // ─── 모달 ───
  const [moldModalOpen, setMoldModalOpen] = useState(false);
  const [moldEditMode, setMoldEditMode] = useState(false);
  const [moldForm, setMoldForm] = useState<Record<string, any>>({});
  const [numberingRuleId, setNumberingRuleId] = useState<string | null>(null);
  const [previewCode, setPreviewCode] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  // moldImagePreview는 상세 표시용으로 유지 (ImageUpload는 모달에서만 사용)
  const [moldImagePreview, setMoldImagePreview] = useState<string | null>(null);

  const [serialModalOpen, setSerialModalOpen] = useState(false);
  const [serialForm, setSerialForm] = useState<Record<string, any>>({});

  const [inspectionModalOpen, setInspectionModalOpen] = useState(false);
  const [inspectionForm, setInspectionForm] = useState<Record<string, any>>({});

  const [partModalOpen, setPartModalOpen] = useState(false);
  const [partForm, setPartForm] = useState<Record<string, any>>({});

  // ─── 금형 목록 조회 ───
  const fetchMolds = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string> = {};
      if (filterCode) params.mold_code = filterCode;
      if (filterName) params.mold_name = filterName;
      if (filterType) params.mold_type = filterType;
      if (filterStatus) params.operation_status = filterStatus;

      const res = await apiClient.get(API, { params });
      setMolds(res.data?.data || []);
    } catch {
      toast.error("금형 목록을 불러올 수 없어요.");
    } finally {
      setLoading(false);
    }
  }, [filterCode, filterName, filterType, filterStatus]);

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

  // ─── 금형 상세 + 하위 데이터 ───
  const fetchDetail = useCallback(async (code: string) => {
    setDetailLoading(true);
    try {
      const [detailRes, summaryRes] = await Promise.all([
        apiClient.get(`${API}/${code}`),
        apiClient.get(`${API}/${code}/serial-summary`),
      ]);
      setDetail(detailRes.data?.data || null);
      setSerialSummary(summaryRes.data?.data || null);
    } catch {
      toast.error("금형 상세를 불러올 수 없어요.");
    } finally {
      setDetailLoading(false);
    }
  }, []);

  const fetchSerials = useCallback(async (code: string) => {
    setSerialLoading(true);
    try {
      const res = await apiClient.get(`${API}/${code}/serials`);
      setSerials(res.data?.data || []);
    } catch {
      toast.error("일련번호를 불러올 수 없어요.");
    } finally {
      setSerialLoading(false);
    }
  }, []);

  const fetchInspections = useCallback(async (code: string) => {
    setInspectionLoading(true);
    try {
      const res = await apiClient.get(`${API}/${code}/inspections`);
      setInspections(res.data?.data || []);
    } catch {
      toast.error("점검항목을 불러올 수 없어요.");
    } finally {
      setInspectionLoading(false);
    }
  }, []);

  const fetchParts = useCallback(async (code: string) => {
    setPartLoading(true);
    try {
      const res = await apiClient.get(`${API}/${code}/parts`);
      setParts(res.data?.data || []);
    } catch {
      toast.error("부품을 불러올 수 없어요.");
    } finally {
      setPartLoading(false);
    }
  }, []);

  // 금형 선택
  const handleSelectMold = useCallback((code: string) => {
    setSelectedMoldCode(code);
    setRightTab("serial");
    fetchDetail(code);
    fetchSerials(code);
    fetchInspections(code);
    fetchParts(code);
  }, [fetchDetail, fetchSerials, fetchInspections, fetchParts]);

  // 탭 변경 시 재조회
  useEffect(() => {
    if (!selectedMoldCode) return;
    if (rightTab === "serial") fetchSerials(selectedMoldCode);
    else if (rightTab === "inspection") fetchInspections(selectedMoldCode);
    else if (rightTab === "part") fetchParts(selectedMoldCode);
  }, [rightTab, selectedMoldCode, fetchSerials, fetchInspections, fetchParts]);

  // ─── 금형 CRUD ───
  const handleOpenRegister = async () => {
    setMoldEditMode(false);
    setMoldForm({});
    setMoldImagePreview(null);
    setNumberingRuleId(null);
    setPreviewCode(null);
    setMoldModalOpen(true);

    // 채번 규칙 조회 (mold_mng.mold_code)
    try {
      const ruleRes = await apiClient.get(`/numbering-rules/by-column/mold_mng/mold_code`);
      const ruleData = ruleRes.data;
      if (ruleData?.success && ruleData?.data?.ruleId) {
        const ruleId = ruleData.data.ruleId;
        setNumberingRuleId(ruleId);
        const previewRes = await previewNumberingCode(ruleId);
        if (previewRes.success && previewRes.data?.generatedCode) {
          setPreviewCode(previewRes.data.generatedCode);
        }
      }
    } catch {
      // 채번 규칙 없으면 무시 — 수동 입력 모드
    }
  };

  const handleOpenEdit = () => {
    if (!detail) return;
    setMoldEditMode(true);
    setMoldForm({ ...detail });
    setMoldImagePreview(detail.image_path || null);
    setMoldModalOpen(true);
  };

  // 이미지 업로드는 ImageUpload 컴포넌트가 처리 → objid를 image_path에 저장

  const handleSaveMold = async () => {
    // 등록 모드에서 채번이 없으면 수동 입력 필수
    if (!moldEditMode && !numberingRuleId && !moldForm.mold_code) {
      toast.error("금형코드와 금형명은 필수예요.");
      return;
    }
    if (!moldForm.mold_name) {
      toast.error("금형명은 필수예요.");
      return;
    }
    if (moldEditMode && !moldForm.mold_code) {
      toast.error("금형코드가 없어요.");
      return;
    }
    setSaving(true);
    try {
      if (moldEditMode) {
        await apiClient.put(`${API}/${moldForm.mold_code}`, moldForm);
        toast.success("금형이 수정되었어요.");
      } else {
        // 채번 규칙이 있으면 allocate로 실제 코드 할당
        let saveData = { ...moldForm };
        if (numberingRuleId) {
          const allocRes = await allocateNumberingCode(numberingRuleId);
          if (allocRes.success && allocRes.data?.generatedCode) {
            saveData.mold_code = allocRes.data.generatedCode;
          } else {
            toast.error("채번 코드 할당에 실패했어요.");
            return;
          }
        }
        await apiClient.post(API, saveData);
        toast.success("금형이 등록되었어요.");
      }
      setMoldModalOpen(false);
      fetchMolds();
      if (moldEditMode && selectedMoldCode === moldForm.mold_code) {
        fetchDetail(moldForm.mold_code);
      }
    } catch (err: any) {
      toast.error(err?.response?.data?.message || "저장에 실패했어요.");
    } finally {
      setSaving(false);
    }
  };

  const handleDeleteMold = async () => {
    if (!selectedMoldCode || !detail) return;
    const ok = await confirm(
      "금형을 삭제하시겠어요?",
      { description: `"${detail.mold_name}" 금형과 하위 일련번호, 점검항목, 부품이 모두 삭제돼요.`, variant: "destructive" },
    );
    if (!ok) return;
    try {
      await apiClient.delete(`${API}/${selectedMoldCode}`);
      toast.success("금형이 삭제되었어요.");
      setSelectedMoldCode(null);
      setDetail(null);
      fetchMolds();
    } catch {
      toast.error("삭제에 실패했어요.");
    }
  };

  // ─── 일련번호 CRUD ───
  const handleSaveSerial = async () => {
    if (!selectedMoldCode) return;
    setSaving(true);
    try {
      if (serialForm.id) {
        await apiClient.put(`${API}/serials/${serialForm.id}`, serialForm);
        toast.success("일련번호가 수정되었어요.");
      } else {
        await apiClient.post(`${API}/${selectedMoldCode}/serials`, serialForm);
        toast.success("일련번호가 등록되었어요.");
      }
      setSerialModalOpen(false);
      setSerialForm({});
      fetchSerials(selectedMoldCode);
      fetchDetail(selectedMoldCode);
    } catch (err: any) {
      toast.error(err?.response?.data?.message || "저장에 실패했어요.");
    } finally {
      setSaving(false);
    }
  };

  const handleDeleteSerial = async (id: number) => {
    const ok = await confirm("이 일련번호를 삭제하시겠어요?", { variant: "destructive" });
    if (!ok) return;
    try {
      await apiClient.delete(`${API}/serials/${id}`);
      toast.success("삭제되었어요.");
      if (selectedMoldCode) {
        fetchSerials(selectedMoldCode);
        fetchDetail(selectedMoldCode);
      }
    } catch {
      toast.error("삭제에 실패했어요.");
    }
  };

  // ─── 점검항목 CRUD ───
  const handleAddInspection = async () => {
    if (!selectedMoldCode) return;
    if (!inspectionForm.inspection_item) {
      toast.error("점검항목명은 필수예요.");
      return;
    }
    setSaving(true);
    try {
      await apiClient.post(`${API}/${selectedMoldCode}/inspections`, inspectionForm);
      toast.success("점검항목이 등록되었어요.");
      setInspectionModalOpen(false);
      setInspectionForm({});
      fetchInspections(selectedMoldCode);
    } catch {
      toast.error("등록에 실패했어요.");
    } finally {
      setSaving(false);
    }
  };

  const handleDeleteInspection = async (id: number) => {
    const ok = await confirm("이 점검항목을 삭제하시겠어요?", { variant: "destructive" });
    if (!ok) return;
    try {
      await apiClient.delete(`${API}/inspections/${id}`);
      toast.success("삭제되었어요.");
      if (selectedMoldCode) fetchInspections(selectedMoldCode);
    } catch {
      toast.error("삭제에 실패했어요.");
    }
  };

  // ─── 부품 CRUD ───
  const handleAddPart = async () => {
    if (!selectedMoldCode) return;
    if (!partForm.part_name) {
      toast.error("부품명은 필수예요.");
      return;
    }
    if (!partForm.replacement_cycle) {
      toast.error("교체주기는 필수예요.");
      return;
    }
    setSaving(true);
    try {
      await apiClient.post(`${API}/${selectedMoldCode}/parts`, partForm);
      toast.success("부품이 등록되었어요.");
      setPartModalOpen(false);
      setPartForm({});
      fetchParts(selectedMoldCode);
    } catch {
      toast.error("등록에 실패했어요.");
    } finally {
      setSaving(false);
    }
  };

  const handleDeletePart = async (id: number) => {
    const ok = await confirm("이 부품을 삭제하시겠어요?", { variant: "destructive" });
    if (!ok) return;
    try {
      await apiClient.delete(`${API}/parts/${id}`);
      toast.success("삭제되었어요.");
      if (selectedMoldCode) fetchParts(selectedMoldCode);
    } catch {
      toast.error("삭제에 실패했어요.");
    }
  };

  // ─── 수명 진행률 계산 ───
  const calcLifePct = (mold: any) => {
    const max = Number(mold.shot_count) || 0;
    const current = Number(mold.current_shot_count) || 0;
    if (max <= 0) return 0;
    return Math.min(Math.round((current / max) * 100), 100);
  };

  // ─── 카드 렌더링 ───
  const renderCard = (mold: any) => {
    const pct = calcLifePct(mold);
    const st = STATUS_MAP[mold.operation_status] || { label: mold.operation_status || "-", variant: "secondary" as const };
    const isSelected = selectedMoldCode === mold.mold_code;

    return (
      <div
        key={mold.mold_code}
        onClick={() => handleSelectMold(mold.mold_code)}
        className={cn(
          "rounded-lg border cursor-pointer transition-all overflow-hidden",
          "hover:shadow-md hover:-translate-y-0.5",
          isSelected
            ? "border-primary ring-2 ring-primary/25"
            : "border-border hover:border-border",
          viewMode === "list" ? "flex flex-row" : "",
        )}
      >
        {/* 이미지 영역 */}
        <div className={cn(
          "bg-muted flex items-center justify-center relative",
          viewMode === "list"
            ? "w-[120px] min-w-[120px] min-h-[100px]"
            : "h-[160px]",
        )}>
          {mold.image_path ? (
            <img
              src={String(mold.image_path).startsWith("http") || String(mold.image_path).startsWith("/") ? mold.image_path : `/api/files/preview/${mold.image_path}`}
              alt={mold.mold_name}
              className="w-full h-full object-cover"
              onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
            />
          ) : (
            <Box className="w-8 h-8 text-muted-foreground/50" />
          )}
          <div className="absolute top-2 right-2">
            <Badge variant={st.variant} className="text-[10px]">{st.label}</Badge>
          </div>
        </div>

        {/* 본문 */}
        <div className={cn("flex-1 p-3", viewMode === "list" && "flex items-center gap-4")}>
          <div className="flex-1 min-w-0">
            <p className="text-xs text-muted-foreground font-mono truncate">{mold.mold_code}</p>
            <p className="text-sm font-semibold truncate">{mold.mold_name}</p>
            {mold.mold_type && (
              <Badge variant="outline" className="text-[10px] mt-1">{mold.mold_type}</Badge>
            )}
          </div>

          {/* 수명 진행률 */}
          <div className={cn("mt-2", viewMode === "list" && "mt-0 min-w-[140px]")}>
            <div className="flex items-center justify-between mb-1">
              <span className="text-[11px] text-muted-foreground">수명</span>
              <span className={cn("text-[11px] font-mono font-semibold", getProgressTextColor(pct))}>
                {pct}%
              </span>
            </div>
            <div className="h-1 bg-muted rounded-full overflow-hidden">
              <div
                className={cn("h-full rounded-full transition-all", getProgressColor(pct))}
                style={{ width: `${pct}%` }}
              />
            </div>
          </div>
        </div>
      </div>
    );
  };

  // ─── 선택 금형 상세 ───
  const selectedMold = detail;
  const lifePct = selectedMold ? calcLifePct(selectedMold) : 0;

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

      {/* 검색 필터 */}
      <div className="rounded-lg border bg-card p-3">
        <div className="flex flex-wrap items-end gap-3">
          <div className="flex flex-col gap-1">
            <Label className="text-[11px] text-muted-foreground">금형코드</Label>
            <Input
              className="h-9 w-[160px] text-sm"
              placeholder="코드를 입력해주세요"
              value={filterCode}
              onChange={(e) => setFilterCode(e.target.value)}
            />
          </div>
          <div className="flex flex-col gap-1">
            <Label className="text-[11px] text-muted-foreground">금형명</Label>
            <Input
              className="h-9 w-[160px] text-sm"
              placeholder="금형명을 입력해주세요"
              value={filterName}
              onChange={(e) => setFilterName(e.target.value)}
            />
          </div>
          <div className="flex flex-col gap-1">
            <Label className="text-[11px] text-muted-foreground">금형유형</Label>
            <Select value={filterType || "__all__"} onValueChange={(v) => setFilterType(v === "__all__" ? "" : v)}>
              <SelectTrigger className="h-9 w-[140px] text-sm">
                <SelectValue placeholder="전체" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__all__">전체</SelectItem>
                <SelectItem value="사출금형">사출금형</SelectItem>
                <SelectItem value="프레스금형">프레스금형</SelectItem>
                <SelectItem value="다이캐스팅">다이캐스팅</SelectItem>
                <SelectItem value="단조금형">단조금형</SelectItem>
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-1">
            <Label className="text-[11px] text-muted-foreground">상태</Label>
            <Select value={filterStatus || "__all__"} onValueChange={(v) => setFilterStatus(v === "__all__" ? "" : v)}>
              <SelectTrigger className="h-9 w-[140px] text-sm">
                <SelectValue placeholder="전체" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__all__">전체</SelectItem>
                <SelectItem value="ACTIVE">사용중</SelectItem>
                <SelectItem value="INSPECTION">점검중</SelectItem>
                <SelectItem value="REPAIR">수리중</SelectItem>
                <SelectItem value="DISPOSED">폐기</SelectItem>
              </SelectContent>
            </Select>
          </div>
          <Button size="sm" className="h-9" onClick={fetchMolds}>
            <Search className="w-4 h-4 mr-1" />
            조회
          </Button>
        </div>
      </div>

      {/* 메인 분할 패널 */}
      <ResizablePanelGroup direction="horizontal" className="flex-1 rounded-lg border bg-card overflow-hidden">
        {/* ─── 좌측: 카드 리스트 ─── */}
        <ResizablePanel defaultSize={35} minSize={20} maxSize={50}>
          <div className="flex flex-col h-full">
            {/* 패널 헤더 */}
            <div className="flex items-center justify-between px-4 py-3 border-b">
              <div className="flex items-center gap-2">
                <h3 className="text-sm font-semibold">금형 목록</h3>
                <span className="text-xs font-mono font-semibold text-primary bg-primary/10 border border-primary/15 px-2 py-0.5 rounded-full">
                  {molds.length}
                </span>
              </div>
              <div className="flex items-center gap-1.5">
                {/* 뷰 토글 */}
                <div className="flex border rounded overflow-hidden">
                  <button
                    onClick={() => setViewMode("grid")}
                    className={cn(
                      "p-1.5 transition-colors",
                      viewMode === "grid"
                        ? "bg-primary/10 text-primary"
                        : "text-muted-foreground/50 hover:text-muted-foreground hover:bg-accent",
                    )}
                  >
                    <LayoutGrid className="w-3.5 h-3.5" />
                  </button>
                  <button
                    onClick={() => setViewMode("list")}
                    className={cn(
                      "p-1.5 transition-colors border-l",
                      viewMode === "list"
                        ? "bg-primary/10 text-primary"
                        : "text-muted-foreground/50 hover:text-muted-foreground hover:bg-accent",
                    )}
                  >
                    <List className="w-3.5 h-3.5" />
                  </button>
                </div>
                <Button size="sm" className="h-8" onClick={handleOpenRegister}>
                  <Plus className="w-4 h-4 mr-1" />
                  등록
                </Button>
              </div>
            </div>

            {/* 카드 스크롤 영역 */}
            <div className="flex-1 overflow-y-auto p-2">
              {loading ? (
                <div className="flex items-center justify-center h-40">
                  <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
                </div>
              ) : molds.length === 0 ? (
                <div className="flex flex-col items-center justify-center h-40 gap-2 text-muted-foreground">
                  <Inbox className="w-10 h-10 opacity-40" />
                  <p className="text-sm">등록된 금형이 없어요.</p>
                </div>
              ) : (
                <div className={cn(
                  "grid gap-2",
                  viewMode === "grid"
                    ? "grid-cols-[repeat(auto-fill,minmax(200px,1fr))]"
                    : "grid-cols-1",
                )}>
                  {molds.map(renderCard)}
                </div>
              )}
            </div>
          </div>
        </ResizablePanel>

        <ResizableHandle withHandle />

        {/* ─── 우측: 상세 ─── */}
        <ResizablePanel defaultSize={65} minSize={40}>
          <div className="flex flex-col h-full overflow-y-auto">
            {!selectedMoldCode ? (
              <div className="flex flex-col items-center justify-center h-full gap-3 text-muted-foreground">
                <Box className="w-14 h-14 opacity-30" />
                <p className="text-sm font-medium">좌측에서 금형을 선택해주세요</p>
                <p className="text-xs text-muted-foreground/60">금형을 선택하면 상세 정보를 확인할 수 있어요</p>
              </div>
            ) : detailLoading ? (
              <div className="flex items-center justify-center h-full">
                <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
              </div>
            ) : selectedMold ? (
              <div className="p-5">
                {/* 상세 헤더 */}
                <div className="flex gap-5 pb-5 border-b mb-4">
                  {/* 이미지 */}
                  <div className="w-[200px] min-w-[200px] h-[200px] bg-muted rounded-lg flex items-center justify-center border">
                    {selectedMold.image_path ? (
                      <img
                        src={String(selectedMold.image_path).startsWith("http") || String(selectedMold.image_path).startsWith("/") ? selectedMold.image_path : `/api/files/preview/${selectedMold.image_path}`}
                        alt={selectedMold.mold_name}
                        className="w-full h-full object-cover rounded-lg"
                        onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
                      />
                    ) : (
                      <ImageIcon className="w-16 h-16 text-muted-foreground/40" />
                    )}
                  </div>

                  {/* 메타 정보 */}
                  <div className="flex-1 flex flex-col justify-center min-w-0">
                    <p className="text-xs text-muted-foreground font-mono mb-1">{selectedMold.mold_code}</p>
                    <h2 className="text-xl font-bold mb-2 truncate">{selectedMold.mold_name}</h2>
                    <div className="flex gap-1.5 mb-4 flex-wrap">
                      {selectedMold.mold_type && (
                        <Badge variant="outline">{selectedMold.mold_type}</Badge>
                      )}
                      {selectedMold.category && (
                        <Badge variant="secondary">{selectedMold.category}</Badge>
                      )}
                      <Badge variant={STATUS_MAP[selectedMold.operation_status]?.variant || "secondary"}>
                        {STATUS_MAP[selectedMold.operation_status]?.label || selectedMold.operation_status || "-"}
                      </Badge>
                    </div>

                    <div className="grid grid-cols-2 gap-x-5 gap-y-2 text-sm">
                      <div>
                        <span className="text-[11px] text-muted-foreground/60 uppercase tracking-wider font-semibold">제조사</span>
                        <p className="text-foreground">{selectedMold.manufacturer || "-"}</p>
                      </div>
                      <div>
                        <span className="text-[11px] text-muted-foreground/60 uppercase tracking-wider font-semibold">제작일</span>
                        <p className="text-foreground">{selectedMold.manufacturing_date || "-"}</p>
                      </div>
                      <div>
                        <span className="text-[11px] text-muted-foreground/60 uppercase tracking-wider font-semibold">캐비티수</span>
                        <p className="text-foreground font-mono">{selectedMold.cavity_count ?? "-"}</p>
                      </div>
                      <div>
                        <span className="text-[11px] text-muted-foreground/60 uppercase tracking-wider font-semibold">수량</span>
                        <p className="text-foreground font-mono">{selectedMold.mold_quantity ?? "-"}</p>
                      </div>
                      <div>
                        <span className="text-[11px] text-muted-foreground/60 uppercase tracking-wider font-semibold">최대수명</span>
                        <p className="text-foreground font-mono">{Number(selectedMold.shot_count || 0).toLocaleString()}회</p>
                      </div>
                      <div>
                        <span className="text-[11px] text-muted-foreground/60 uppercase tracking-wider font-semibold">보증수명</span>
                        <p className="text-foreground font-mono">{Number(selectedMold.warranty_shot_count || 0).toLocaleString()}회</p>
                      </div>
                    </div>

                    {/* 수명 진행률 바 */}
                    <div className="mt-3">
                      <div className="flex items-center justify-between mb-1">
                        <span className="text-xs text-muted-foreground">수명 사용률</span>
                        <span className={cn("text-sm font-mono font-semibold", getProgressTextColor(lifePct))}>
                          {lifePct}%
                        </span>
                      </div>
                      <div className="h-1.5 bg-muted rounded-full overflow-hidden">
                        <div
                          className={cn("h-full rounded-full transition-all", getProgressColor(lifePct))}
                          style={{ width: `${lifePct}%` }}
                        />
                      </div>
                    </div>
                  </div>

                  {/* 액션 버튼 */}
                  <div className="flex flex-col gap-2 flex-shrink-0">
                    <Button variant="outline" size="sm" className="h-8" onClick={handleOpenEdit}>
                      <Pencil className="w-3.5 h-3.5 mr-1" />
                      수정
                    </Button>
                    <Button variant="outline" size="sm" className="h-8 text-destructive hover:text-destructive" onClick={handleDeleteMold}>
                      <Trash2 className="w-3.5 h-3.5 mr-1" />
                      삭제
                    </Button>
                  </div>
                </div>

                {/* 탭 3개 */}
                <Tabs value={rightTab} onValueChange={setRightTab}>
                  <TabsList className="w-full justify-start border-b rounded-none bg-transparent h-auto p-0">
                    <TabsTrigger
                      value="serial"
                      className="rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:shadow-none"
                    >
                      <Wrench className="w-4 h-4 mr-1.5" />
                      일련번호
                      <span className="ml-1.5 text-xs font-mono bg-primary/10 text-primary px-1.5 rounded-full">
                        {serials.length}
                      </span>
                    </TabsTrigger>
                    <TabsTrigger
                      value="inspection"
                      className="rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:shadow-none"
                    >
                      <ClipboardCheck className="w-4 h-4 mr-1.5" />
                      점검항목
                      <span className="ml-1.5 text-xs font-mono bg-primary/10 text-primary px-1.5 rounded-full">
                        {inspections.length}
                      </span>
                    </TabsTrigger>
                    <TabsTrigger
                      value="part"
                      className="rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:shadow-none"
                    >
                      <Package className="w-4 h-4 mr-1.5" />
                      부품
                      <span className="ml-1.5 text-xs font-mono bg-primary/10 text-primary px-1.5 rounded-full">
                        {parts.length}
                      </span>
                    </TabsTrigger>
                  </TabsList>

                  {/* ─── 탭1: 일련번호 ─── */}
                  <TabsContent value="serial" className="mt-3">
                    <div className="flex items-center justify-between mb-3">
                      <span className="text-xs font-semibold text-muted-foreground">
                        {serialSummary && (
                          <>
                            사용중 {serialSummary.in_use || 0} · 보관중 {serialSummary.stored || 0} · 수리중 {serialSummary.repair || 0} · 폐기 {serialSummary.disposed || 0}
                          </>
                        )}
                      </span>
                      <Button size="sm" className="h-8" onClick={() => { setSerialForm({}); setSerialModalOpen(true); }}>
                        <Plus className="w-4 h-4 mr-1" />
                        일련번호 등록
                      </Button>
                    </div>
                    {serialLoading ? (
                      <div className="flex justify-center py-8">
                        <Loader2 className="w-5 h-5 animate-spin text-muted-foreground" />
                      </div>
                    ) : serials.length === 0 ? (
                      <div className="flex flex-col items-center justify-center py-10 gap-2 border-2 border-dashed rounded-lg text-muted-foreground">
                        <Wrench className="w-8 h-8 opacity-30" />
                        <p className="text-sm">등록된 일련번호가 없어요.</p>
                      </div>
                    ) : (
                      <div className="border rounded-lg overflow-hidden">
                        <Table>
                          <TableHeader className="sticky top-0 z-10">
                            <TableRow className="bg-muted hover:bg-muted">
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">일련번호</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">상태</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground min-w-[200px]">샷수 현황</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">보관위치</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">비고</TableHead>
                              <TableHead className="text-xs w-[80px]">작업</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {serials.map((s: any) => {
                              const ss = SERIAL_STATUS_MAP[s.status] || { label: s.status || "-", variant: "secondary" as const };
                              const maxShot = detail?.shot_count || 0;
                              const curShot = s.current_shot_count || 0;
                              const pct = maxShot > 0 ? Math.min(Math.round((curShot / maxShot) * 100), 100) : 0;
                              return (
                                <TableRow key={s.id}>
                                  <TableCell className="text-[13px] font-mono font-semibold">{s.serial_number}</TableCell>
                                  <TableCell>
                                    <Badge variant={ss.variant} className="text-[10px]">{ss.label}</Badge>
                                  </TableCell>
                                  <TableCell>
                                    {maxShot > 0 ? (
                                      <div className="space-y-1">
                                        <div className="flex items-center gap-2">
                                          <div className="flex-1 h-3 bg-muted rounded-full overflow-hidden">
                                            <div
                                              className={cn("h-full rounded-full transition-all", getProgressColor(pct))}
                                              style={{ width: `${pct}%` }}
                                            />
                                          </div>
                                          <span className={cn("text-xs font-bold min-w-[36px] text-right", getProgressTextColor(pct))}>
                                            {pct}%
                                          </span>
                                        </div>
                                        <p className="text-[11px] text-muted-foreground">
                                          {curShot.toLocaleString()} / {maxShot.toLocaleString()}
                                        </p>
                                      </div>
                                    ) : (
                                      <span className="text-xs text-muted-foreground">-</span>
                                    )}
                                  </TableCell>
                                  <TableCell className="text-[13px]">{s.storage_location || "-"}</TableCell>
                                  <TableCell className="text-[13px] text-muted-foreground">{s.remarks || "-"}</TableCell>
                                  <TableCell>
                                    <div className="flex items-center gap-1">
                                      <Button
                                        variant="ghost"
                                        size="sm"
                                        className="h-7 w-7 p-0"
                                        onClick={() => {
                                          setSerialForm(s);
                                          setSerialModalOpen(true);
                                        }}
                                      >
                                        <Pencil className="w-3.5 h-3.5" />
                                      </Button>
                                      <Button
                                        variant="ghost"
                                        size="sm"
                                        className="h-7 w-7 p-0 text-destructive hover:text-destructive"
                                        onClick={() => handleDeleteSerial(s.id)}
                                      >
                                        <Trash2 className="w-3.5 h-3.5" />
                                      </Button>
                                    </div>
                                  </TableCell>
                                </TableRow>
                              );
                            })}
                          </TableBody>
                        </Table>
                      </div>
                    )}
                  </TabsContent>

                  {/* ─── 탭2: 점검항목 ─── */}
                  <TabsContent value="inspection" className="mt-3">
                    <div className="flex items-center justify-between mb-3">
                      <span className="text-xs font-semibold text-muted-foreground">점검항목 목록</span>
                      <Button size="sm" className="h-8" onClick={() => { setInspectionForm({}); setInspectionModalOpen(true); }}>
                        <Plus className="w-4 h-4 mr-1" />
                        점검항목 등록
                      </Button>
                    </div>
                    {inspectionLoading ? (
                      <div className="flex justify-center py-8">
                        <Loader2 className="w-5 h-5 animate-spin text-muted-foreground" />
                      </div>
                    ) : inspections.length === 0 ? (
                      <div className="flex flex-col items-center justify-center py-10 gap-2 border-2 border-dashed rounded-lg text-muted-foreground">
                        <ClipboardCheck className="w-8 h-8 opacity-30" />
                        <p className="text-sm">등록된 점검항목이 없어요.</p>
                      </div>
                    ) : (
                      <div className="border rounded-lg overflow-hidden">
                        <Table>
                          <TableHeader className="sticky top-0 z-10">
                            <TableRow className="bg-muted hover:bg-muted">
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">점검항목</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">점검주기</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">점검방법</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">하한치</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">상한치</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">단위</TableHead>
                              <TableHead className="text-xs w-[60px]" />
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {inspections.map((ins: any) => (
                              <TableRow key={ins.id}>
                                <TableCell className="text-[13px] font-medium">{ins.inspection_item}</TableCell>
                                <TableCell className="text-[13px]">{ins.inspection_cycle || "-"}</TableCell>
                                <TableCell className="text-[13px]">{ins.inspection_method || "-"}</TableCell>
                                <TableCell className="text-[13px] font-mono">{ins.lower_limit || "-"}</TableCell>
                                <TableCell className="text-[13px] font-mono">{ins.upper_limit || "-"}</TableCell>
                                <TableCell className="text-[13px]">{ins.unit || "-"}</TableCell>
                                <TableCell>
                                  <Button
                                    variant="ghost"
                                    size="sm"
                                    className="h-7 w-7 p-0 text-destructive hover:text-destructive"
                                    onClick={() => handleDeleteInspection(ins.id)}
                                  >
                                    <Trash2 className="w-3.5 h-3.5" />
                                  </Button>
                                </TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      </div>
                    )}
                  </TabsContent>

                  {/* ─── 탭3: 부품 ─── */}
                  <TabsContent value="part" className="mt-3">
                    <div className="flex items-center justify-between mb-3">
                      <span className="text-xs font-semibold text-muted-foreground">부품 목록</span>
                      <Button size="sm" className="h-8" onClick={() => { setPartForm({}); setPartModalOpen(true); }}>
                        <Plus className="w-4 h-4 mr-1" />
                        부품 등록
                      </Button>
                    </div>
                    {partLoading ? (
                      <div className="flex justify-center py-8">
                        <Loader2 className="w-5 h-5 animate-spin text-muted-foreground" />
                      </div>
                    ) : parts.length === 0 ? (
                      <div className="flex flex-col items-center justify-center py-10 gap-2 border-2 border-dashed rounded-lg text-muted-foreground">
                        <Package className="w-8 h-8 opacity-30" />
                        <p className="text-sm">등록된 부품이 없어요.</p>
                      </div>
                    ) : (
                      <div className="border rounded-lg overflow-hidden">
                        <Table>
                          <TableHeader className="sticky top-0 z-10">
                            <TableRow className="bg-muted hover:bg-muted">
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">부품명</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">교체주기</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">단위</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">규격</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">제조사</TableHead>
                              <TableHead className="text-xs text-[11px] font-bold uppercase tracking-wide text-muted-foreground">비고</TableHead>
                              <TableHead className="text-xs w-[60px]" />
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {parts.map((p: any) => (
                              <TableRow key={p.id}>
                                <TableCell className="text-[13px] font-medium">{p.part_name}</TableCell>
                                <TableCell className="text-[13px]">{p.replacement_cycle || "-"}</TableCell>
                                <TableCell className="text-[13px]">{p.unit || "-"}</TableCell>
                                <TableCell className="text-[13px]">{p.specification || "-"}</TableCell>
                                <TableCell className="text-[13px]">{p.manufacturer || "-"}</TableCell>
                                <TableCell className="text-[13px] text-muted-foreground">{p.remarks || "-"}</TableCell>
                                <TableCell>
                                  <Button
                                    variant="ghost"
                                    size="sm"
                                    className="h-7 w-7 p-0 text-destructive hover:text-destructive"
                                    onClick={() => handleDeletePart(p.id)}
                                  >
                                    <Trash2 className="w-3.5 h-3.5" />
                                  </Button>
                                </TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      </div>
                    )}
                  </TabsContent>
                </Tabs>
              </div>
            ) : null}
          </div>
        </ResizablePanel>
      </ResizablePanelGroup>

      {/* ========== 금형 등록/수정 모달 ========== */}
      <Dialog open={moldModalOpen} onOpenChange={setMoldModalOpen}>
        <DialogContent className="max-w-3xl overflow-y-auto" style={{ maxHeight: "90vh" }}>
          <DialogHeader>
            <DialogTitle>{moldEditMode ? "금형 수정" : "금형 등록"}</DialogTitle>
            <DialogDescription>금형 기본 정보를 입력해주세요.</DialogDescription>
          </DialogHeader>
          <div className="space-y-6 py-2">
            <div className="grid grid-cols-2 gap-4">
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">금형코드 <span className="text-destructive">*</span></Label>
                <Input
                  className="h-9 text-sm"
                  value={moldEditMode ? (moldForm.mold_code || "") : (numberingRuleId ? (previewCode || "") : (moldForm.mold_code || ""))}
                  onChange={(e) => {
                    if (!moldEditMode && !numberingRuleId) {
                      setMoldForm({ ...moldForm, mold_code: e.target.value });
                    }
                  }}
                  readOnly={moldEditMode || !!numberingRuleId}
                  placeholder={moldEditMode ? "" : (numberingRuleId ? (previewCode ? "" : "자동 생성 중...") : "금형코드를 입력해주세요")}
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">금형명 <span className="text-destructive">*</span></Label>
                <Input
                  className="h-9 text-sm"
                  value={moldForm.mold_name || ""}
                  onChange={(e) => setMoldForm({ ...moldForm, mold_name: e.target.value })}
                  placeholder="금형명을 입력해주세요"
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">금형유형</Label>
                <Select
                  value={moldForm.mold_type || ""}
                  onValueChange={(v) => setMoldForm({ ...moldForm, mold_type: v })}
                >
                  <SelectTrigger className="h-9 text-sm">
                    <SelectValue placeholder="선택해주세요" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="사출금형">사출금형</SelectItem>
                    <SelectItem value="프레스금형">프레스금형</SelectItem>
                    <SelectItem value="다이캐스팅">다이캐스팅</SelectItem>
                    <SelectItem value="단조금형">단조금형</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">카테고리</Label>
                <Input
                  className="h-9 text-sm"
                  value={moldForm.category || ""}
                  onChange={(e) => setMoldForm({ ...moldForm, category: e.target.value })}
                  placeholder="카테고리"
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">제조사</Label>
                <Input
                  className="h-9 text-sm"
                  value={moldForm.manufacturer || ""}
                  onChange={(e) => setMoldForm({ ...moldForm, manufacturer: e.target.value })}
                  placeholder="제조사"
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">제작일</Label>
                <Input
                  type="date"
                  className="h-9 text-sm"
                  value={moldForm.manufacturing_date || ""}
                  onChange={(e) => setMoldForm({ ...moldForm, manufacturing_date: e.target.value })}
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">캐비티수</Label>
                <Input
                  type="number"
                  className="h-9 text-sm font-mono"
                  value={moldForm.cavity_count ?? ""}
                  onChange={(e) => setMoldForm({ ...moldForm, cavity_count: e.target.value })}
                  min={0}
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">최대수명 (샷수)</Label>
                <Input
                  type="number"
                  className="h-9 text-sm font-mono"
                  value={moldForm.shot_count ?? ""}
                  onChange={(e) => setMoldForm({ ...moldForm, shot_count: e.target.value })}
                  min={0}
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">금형수량</Label>
                <Input
                  type="number"
                  className="h-9 text-sm font-mono"
                  value={moldForm.mold_quantity ?? ""}
                  onChange={(e) => setMoldForm({ ...moldForm, mold_quantity: e.target.value })}
                  min={1}
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">가동상태</Label>
                <Select
                  value={moldForm.operation_status || ""}
                  onValueChange={(v) => setMoldForm({ ...moldForm, operation_status: v })}
                >
                  <SelectTrigger className="h-9 text-sm">
                    <SelectValue placeholder="선택해주세요" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="ACTIVE">사용중</SelectItem>
                    <SelectItem value="INSPECTION">점검중</SelectItem>
                    <SelectItem value="REPAIR">수리중</SelectItem>
                    <SelectItem value="DISPOSED">폐기</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">보증수명 (샷수)</Label>
                <Input
                  type="number"
                  className="h-9 text-sm font-mono"
                  value={moldForm.warranty_shot_count ?? ""}
                  onChange={(e) => setMoldForm({ ...moldForm, warranty_shot_count: e.target.value })}
                  min={0}
                />
              </div>
              <div className="flex flex-col gap-1.5">
                <Label className="text-xs">금형 이미지</Label>
                <ImageUpload
                  value={moldForm.image_path || ""}
                  onChange={(v) => setMoldForm((prev) => ({ ...prev, image_path: v }))}
                  tableName="mold_mng"
                  recordId={moldForm.id || ""}
                  columnName="image_path"
                  height="h-32"
                />
              </div>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setMoldModalOpen(false)}>취소</Button>
            <Button size="sm" onClick={handleSaveMold} disabled={saving}>
              {saving && <Loader2 className="w-4 h-4 mr-1 animate-spin" />}
              {moldEditMode ? "수정하기" : "등록하기"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ========== 일련번호 등록/수정 모달 ========== */}
      <Dialog open={serialModalOpen} onOpenChange={setSerialModalOpen}>
        <DialogContent className="sm:max-w-[480px]">
          <DialogHeader>
            <DialogTitle>{serialForm.id ? "일련번호 수정" : "일련번호 등록"}</DialogTitle>
            <DialogDescription>{serialForm.id ? `${serialForm.serial_number} 정보를 수정해요.` : "일련번호는 자동으로 채번돼요."}</DialogDescription>
          </DialogHeader>
          <div className="grid grid-cols-2 gap-4 py-2">
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">상태</Label>
              <Select
                value={serialForm.status || "STORED"}
                onValueChange={(v) => setSerialForm({ ...serialForm, status: v })}
              >
                <SelectTrigger className="h-9 text-sm">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="IN_USE">사용중</SelectItem>
                  <SelectItem value="STORED">보관중</SelectItem>
                  <SelectItem value="REPAIR">수리중</SelectItem>
                  <SelectItem value="DISPOSED">폐기</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">현재 샷수</Label>
              <Input
                type="number"
                className="h-9 text-sm font-mono"
                value={serialForm.current_shot_count ?? ""}
                onChange={(e) => setSerialForm({ ...serialForm, current_shot_count: e.target.value ? Number(e.target.value) : null })}
                placeholder="0"
                min={0}
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">보관위치</Label>
              <Input
                className="h-9 text-sm"
                value={serialForm.storage_location || ""}
                onChange={(e) => setSerialForm({ ...serialForm, storage_location: e.target.value })}
                placeholder="보관위치"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">비고</Label>
              <Input
                className="h-9 text-sm"
                value={serialForm.remarks || ""}
                onChange={(e) => setSerialForm({ ...serialForm, remarks: e.target.value })}
                placeholder="비고"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setSerialModalOpen(false)}>취소</Button>
            <Button size="sm" onClick={handleSaveSerial} disabled={saving}>
              {saving && <Loader2 className="w-4 h-4 mr-1 animate-spin" />}
              {serialForm.id ? "수정하기" : "등록하기"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ========== 점검항목 등록 모달 ========== */}
      <Dialog open={inspectionModalOpen} onOpenChange={setInspectionModalOpen}>
        <DialogContent className="sm:max-w-[560px]">
          <DialogHeader>
            <DialogTitle>점검항목 등록</DialogTitle>
            <DialogDescription>금형 점검항목을 등록해주세요.</DialogDescription>
          </DialogHeader>
          <div className="grid grid-cols-2 gap-4 py-2">
            <div className="flex flex-col gap-1.5 col-span-2">
              <Label className="text-xs">점검항목명 <span className="text-destructive">*</span></Label>
              <Input
                className="h-9 text-sm"
                value={inspectionForm.inspection_item || ""}
                onChange={(e) => setInspectionForm({ ...inspectionForm, inspection_item: e.target.value })}
                placeholder="점검항목명"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">점검주기</Label>
              <Input
                className="h-9 text-sm"
                value={inspectionForm.inspection_cycle || ""}
                onChange={(e) => setInspectionForm({ ...inspectionForm, inspection_cycle: e.target.value })}
                placeholder="예: 월 1회"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">점검방법 <span className="text-destructive">*</span></Label>
              <Select
                value={inspectionForm.inspection_method || ""}
                onValueChange={(v) => {
                  const updated: Record<string, any> = { ...inspectionForm, inspection_method: v };
                  if (v !== "숫자") {
                    updated.lower_limit = "";
                    updated.upper_limit = "";
                    updated.unit = "";
                  }
                  setInspectionForm(updated);
                }}
              >
                <SelectTrigger className="h-9 text-sm">
                  <SelectValue placeholder="선택하세요" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="숫자">숫자</SelectItem>
                  <SelectItem value="텍스트">텍스트</SelectItem>
                  <SelectItem value="합격/불합격">합격/불합격</SelectItem>
                  <SelectItem value="양호/불량">양호/불량</SelectItem>
                </SelectContent>
              </Select>
            </div>
            {inspectionForm.inspection_method === "숫자" && (
              <>
                <div className="flex flex-col gap-1.5">
                  <Label className="text-xs">기준값</Label>
                  <Input
                    type="number"
                    className="h-9 text-sm font-mono"
                    value={inspectionForm.lower_limit || ""}
                    onChange={(e) => setInspectionForm({ ...inspectionForm, lower_limit: e.target.value })}
                    placeholder="기준값"
                  />
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label className="text-xs">±오차범위</Label>
                  <Input
                    type="number"
                    className="h-9 text-sm font-mono"
                    value={inspectionForm.upper_limit || ""}
                    onChange={(e) => setInspectionForm({ ...inspectionForm, upper_limit: e.target.value })}
                    placeholder="허용 오차"
                  />
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label className="text-xs">단위</Label>
                  <Input
                    className="h-9 text-sm"
                    value={inspectionForm.unit || ""}
                    onChange={(e) => setInspectionForm({ ...inspectionForm, unit: e.target.value })}
                    placeholder="mm, ℃ 등"
                  />
                </div>
              </>
            )}
            <div className="flex flex-col gap-1.5 col-span-2">
              <Label className="text-xs">점검내용</Label>
              <textarea
                className="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs placeholder:text-muted-foreground focus-visible:outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 resize-y"
                value={inspectionForm.inspection_content || ""}
                onChange={(e) => setInspectionForm({ ...inspectionForm, inspection_content: e.target.value })}
                placeholder="상세 내용"
                rows={3}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setInspectionModalOpen(false)}>취소</Button>
            <Button size="sm" onClick={handleAddInspection} disabled={saving}>
              {saving && <Loader2 className="w-4 h-4 mr-1 animate-spin" />}
              등록하기
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ========== 부품 등록 모달 ========== */}
      <Dialog open={partModalOpen} onOpenChange={setPartModalOpen}>
        <DialogContent className="sm:max-w-[560px]">
          <DialogHeader>
            <DialogTitle>부품 등록</DialogTitle>
            <DialogDescription>금형 부품을 등록해주세요.</DialogDescription>
          </DialogHeader>
          <div className="grid grid-cols-2 gap-4 py-2">
            <div className="flex flex-col gap-1.5 col-span-2">
              <Label className="text-xs">부품명 <span className="text-destructive">*</span></Label>
              <Input
                className="h-9 text-sm"
                value={partForm.part_name || ""}
                onChange={(e) => setPartForm({ ...partForm, part_name: e.target.value })}
                placeholder="부품명"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">교체주기 <span className="text-destructive">*</span></Label>
              <Select
                value={partForm.replacement_cycle || ""}
                onValueChange={(v) => setPartForm({ ...partForm, replacement_cycle: v })}
              >
                <SelectTrigger className="h-9 text-sm">
                  <SelectValue placeholder="선택하세요" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="1만 샷">1만 샷</SelectItem>
                  <SelectItem value="5만 샷">5만 샷</SelectItem>
                  <SelectItem value="10만 샷">10만 샷</SelectItem>
                  <SelectItem value="월 1회">월 1회</SelectItem>
                  <SelectItem value="3개월">3개월</SelectItem>
                  <SelectItem value="6개월">6개월</SelectItem>
                  <SelectItem value="1년">1년</SelectItem>
                  <SelectItem value="수시">수시</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">단위</Label>
              <Input
                className="h-9 text-sm"
                value={partForm.unit || ""}
                onChange={(e) => setPartForm({ ...partForm, unit: e.target.value })}
                placeholder="EA, SET 등"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">규격</Label>
              <Input
                className="h-9 text-sm"
                value={partForm.specification || ""}
                onChange={(e) => setPartForm({ ...partForm, specification: e.target.value })}
                placeholder="규격"
              />
            </div>
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs">제조사</Label>
              <Input
                className="h-9 text-sm"
                value={partForm.manufacturer || ""}
                onChange={(e) => setPartForm({ ...partForm, manufacturer: e.target.value })}
                placeholder="제조사"
              />
            </div>
            <div className="flex flex-col gap-1.5 col-span-2">
              <Label className="text-xs">비고</Label>
              <textarea
                className="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs placeholder:text-muted-foreground focus-visible:outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 resize-y"
                value={partForm.remarks || ""}
                onChange={(e) => setPartForm({ ...partForm, remarks: e.target.value })}
                placeholder="비고"
                rows={3}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" size="sm" onClick={() => setPartModalOpen(false)}>취소</Button>
            <Button size="sm" onClick={handleAddPart} disabled={saving}>
              {saving && <Loader2 className="w-4 h-4 mr-1 animate-spin" />}
              등록하기
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
