"use client";

// 생산관리 > M-BOM 관리 — BOM 복사 다이얼로그 (PR-B5+).
//
// 운영판 partMng/structureBomCopyFormPopup.jsp (774 lines) 1:1 재구성.
// 진입: 메인 그리드 [BOM 복사] 버튼 (체크박스 1개 선택).
// 저장: /production/mbom/assign (saveBomAssignment) — MbomAssignDialog 와 동일 매퍼.
// 차이점: E-BOM/M-BOM 셀렉트 두 개 (상호배타) + 트리 미리보기 + 도면 다중 업로드.
//
// 운영판 fn_uploadDrawingFiles 는 placeholder ("구현 예정") — RPS 는 공용 AttachFileDropZone
// 재사용으로 실구현 (target_objid=projectObjid, docType="MBOM_DRAWING").

import React, { useEffect, useMemo, useState } from "react";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Loader2, Copy, Folder, X as XIcon } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import {
  mbomApi,
  AssignableEbomRow,
  AssignableMbomRow,
  MbomTreeResponse,
  MbomTreeRow,
  LatestMbomByPartNoRow,
} from "@/lib/api/mbom";
import { AttachFileDropZone } from "@/components/common/AttachFileDropZone";

type SourceType = "EBOM" | "MBOM";

const MACHINE_PRODUCT_CD = "0000928";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  projectObjid: string | null;
  partNo: string | null;
  partName: string | null;
  productCode?: string | null; // contract_mgmt.product — Machine 외 자동 추천 분기용
  hasMbom?: boolean;            // 이미 저장된 M-BOM 이 있으면 "초기화" 경고
  onSaved: () => void;
}

export function BomCopyDialog({
  open, onOpenChange, projectObjid, partNo, partName, productCode, hasMbom, onSaved,
}: Props) {
  // 셀렉트 옵션 + 선택 상태
  const [ebomOpts, setEbomOpts] = useState<AssignableEbomRow[]>([]);
  const [mbomOpts, setMbomOpts] = useState<AssignableMbomRow[]>([]);
  const [ebomLoading, setEbomLoading] = useState(false);
  const [mbomLoading, setMbomLoading] = useState(false);
  const [selectedType, setSelectedType] = useState<SourceType | null>(null);
  const [selectedObjid, setSelectedObjid] = useState<string>("");

  // 미리보기 트리
  const [preview, setPreview] = useState<MbomTreeResponse | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);

  // 저장 진행 + 자동 추천 안내 1회 가드
  const [saving, setSaving] = useState(false);
  const autoCheckedRef = React.useRef(false);

  // ── 오픈 시 초기화 + 옵션 로드 + Machine 외 자동 추천 ──
  useEffect(() => {
    if (!open) {
      // 닫힐 때 상태 초기화
      setSelectedType(null);
      setSelectedObjid("");
      setPreview(null);
      autoCheckedRef.current = false;
      return;
    }
    // E-BOM 옵션
    setEbomLoading(true);
    mbomApi.searchAssignableEboms({ limit: 500 })
      .then(setEbomOpts)
      .catch((e: any) => toast.error(e?.response?.data?.message ?? e?.message ?? "E-BOM 옵션 조회 실패"))
      .finally(() => setEbomLoading(false));
    // M-BOM 옵션
    setMbomLoading(true);
    mbomApi.searchAssignableMboms({ limit: 500 })
      .then(setMbomOpts)
      .catch((e: any) => toast.error(e?.response?.data?.message ?? e?.message ?? "M-BOM 옵션 조회 실패"))
      .finally(() => setMbomLoading(false));
  }, [open]);

  // Machine 이외 제품 + partNo 있으면 자동 추천 (운영 fn_checkExistingMbom)
  useEffect(() => {
    if (!open) return;
    if (autoCheckedRef.current) return;
    if (!partNo || !partNo.trim()) return;
    const isMachine = (productCode ?? "").trim() === MACHINE_PRODUCT_CD;
    if (isMachine) return;
    autoCheckedRef.current = true;
    mbomApi.getLatestMbomByPartNo(partNo)
      .then((row) => {
        if (!row) return;
        const ok = window.confirm(
          `동일 품번(${partNo})의 M-BOM이 이미 존재합니다.\n` +
          `M-BOM 품번: ${row.mbom_no ?? ""}\n저장일: ${row.save_date ?? ""}\n\n` +
          `기존 M-BOM 을 자동으로 불러오시겠습니까?`
        );
        if (ok) {
          setSelectedType("MBOM");
          setSelectedObjid(String(row.template_header_objid));
        }
      })
      .catch(() => { /* 실패 시 조용히 무시 — 자동 추천은 부가기능 */ });
  }, [open, partNo, productCode]);

  // ── 선택 변경 시 트리 미리보기 ────────────────────────────
  useEffect(() => {
    if (!selectedType || !selectedObjid) {
      setPreview(null);
      return;
    }
    setPreviewLoading(true);
    const fetcher = selectedType === "EBOM"
      ? mbomApi.previewEbomTree(selectedObjid)
      : mbomApi.previewMbomTree(selectedObjid);
    fetcher
      .then(setPreview)
      .catch((e: any) => toast.error(e?.response?.data?.message ?? e?.message ?? "트리 미리보기 실패"))
      .finally(() => setPreviewLoading(false));
  }, [selectedType, selectedObjid]);

  const previewTitle = useMemo(() => {
    if (!selectedType || !selectedObjid) return "BOM 데이터를 조회하려면 E-BOM 또는 M-BOM 을 선택하세요.";
    if (selectedType === "EBOM") {
      const r = ebomOpts.find(o => String(o.objid) === String(selectedObjid));
      return r ? `${r.part_no ?? ""} - ${r.part_name ?? ""}${r.revision ? ` (Rev.${r.revision})` : ""}` : "";
    }
    const r = mbomOpts.find(o => String(o.objid) === String(selectedObjid));
    return r ? `${r.mbom_no ?? ""}${r.part_name ? ` - ${r.part_name}` : ""}` : "";
  }, [selectedType, selectedObjid, ebomOpts, mbomOpts]);

  // ── 저장 (운영 fn_saveBomCopy → saveBomAssignment.do) ─────
  const handleSave = async () => {
    if (!projectObjid) { toast.error("프로젝트가 선택되지 않았습니다."); return; }
    if (!partNo || !partName) { toast.error("품번과 품명이 비어 있습니다."); return; }
    if (!selectedType || !selectedObjid) { toast.error("복사할 BOM 을 선택하세요."); return; }
    if (!preview || preview.rows.length === 0) { toast.error("복사할 BOM 데이터가 없습니다."); return; }

    if (hasMbom) {
      const ok = window.confirm("저장된 M-BOM 이 초기화 됩니다.\n계속하시겠습니까?");
      if (!ok) return;
    }
    const ok = window.confirm(
      `선택한 ${selectedType} 을(를) M-BOM 기준으로 할당하시겠습니까?\n` +
      `실제 M-BOM 생성은 M-BOM 상세 팝업에서 저장 시 이루어집니다.`
    );
    if (!ok) return;

    try {
      setSaving(true);
      await mbomApi.assignBom({
        project_obj_id: projectObjid,
        source_bom_type: selectedType,
        source_bom_obj_id: selectedObjid,
      });
      toast.success("BOM 할당 정보가 저장되었습니다.");
      onSaved();
      onOpenChange(false);
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "BOM 할당 실패");
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-[1400px] w-[95vw] max-h-[92vh] overflow-hidden flex flex-col p-0">
        <DialogHeader className="px-6 pt-5 pb-3 border-b">
          <DialogTitle className="flex items-center gap-2 text-base">
            <Copy className="h-4 w-4 text-blue-600" />
            BOM 복사
          </DialogTitle>
        </DialogHeader>

        <div className="flex-1 overflow-auto px-6 py-4 space-y-4">
          {/* 상단: 품번/품명 readonly + [저장] [닫기] (운영 1:1) */}
          <div className="grid grid-cols-12 gap-3 items-end">
            <div className="col-span-3">
              <label className="text-xs text-muted-foreground">품번</label>
              <Input value={partNo ?? ""} readOnly className="bg-muted h-9" />
            </div>
            <div className="col-span-5">
              <label className="text-xs text-muted-foreground">품명</label>
              <Input value={partName ?? ""} readOnly className="bg-muted h-9" />
            </div>
            <div className="col-span-4 flex gap-2 justify-end">
              <Button variant="outline" onClick={() => onOpenChange(false)} disabled={saving}>
                <XIcon className="h-4 w-4 mr-1" /> 닫기
              </Button>
              <Button onClick={handleSave} disabled={saving || !selectedType || !selectedObjid}>
                {saving ? <Loader2 className="h-4 w-4 mr-1 animate-spin" /> : <Copy className="h-4 w-4 mr-1" />}
                저장
              </Button>
            </div>
          </div>

          {/* 중단: E-BOM / M-BOM 셀렉트 (상호배타) */}
          <div className="grid grid-cols-12 gap-3">
            <div className="col-span-2 flex items-center text-sm font-medium">E-BOM 선택</div>
            <div className="col-span-10">
              <select
                className="h-9 w-full border rounded px-2 text-sm bg-background disabled:bg-muted disabled:opacity-60"
                disabled={ebomLoading || selectedType === "MBOM"}
                value={selectedType === "EBOM" ? selectedObjid : ""}
                onChange={(e) => {
                  const v = e.target.value;
                  if (!v) { setSelectedType(null); setSelectedObjid(""); return; }
                  setSelectedType("EBOM");
                  setSelectedObjid(v);
                }}
              >
                <option value="">{ebomLoading ? "로딩…" : "선택"}</option>
                {ebomOpts.map(o => (
                  <option key={o.objid} value={o.objid}>
                    {(o.part_no ?? "")} - {(o.part_name ?? "")}{o.revision ? ` (Rev.${o.revision})` : ""}
                  </option>
                ))}
              </select>
            </div>
            <div className="col-span-2 flex items-center text-sm font-medium">M-BOM 선택</div>
            <div className="col-span-10">
              <select
                className="h-9 w-full border rounded px-2 text-sm bg-background disabled:bg-muted disabled:opacity-60"
                disabled={mbomLoading || selectedType === "EBOM"}
                value={selectedType === "MBOM" ? selectedObjid : ""}
                onChange={(e) => {
                  const v = e.target.value;
                  if (!v) { setSelectedType(null); setSelectedObjid(""); return; }
                  setSelectedType("MBOM");
                  setSelectedObjid(v);
                }}
              >
                <option value="">{mbomLoading ? "로딩…" : "선택"}</option>
                {mbomOpts.map(o => (
                  <option key={o.objid} value={o.objid}>
                    {(o.mbom_no ?? "")}{o.part_name ? ` - ${o.part_name}` : ""}
                  </option>
                ))}
              </select>
            </div>
          </div>

          {/* 하단: 미리보기 트리 + 도면 업로드 */}
          <div className="border rounded">
            <div className="flex items-center justify-between px-3 py-2 bg-muted/50 border-b text-sm">
              <span className="font-medium truncate">{previewTitle}</span>
              <span className="text-xs text-muted-foreground">
                {previewLoading ? "로딩…" : preview ? `${preview.rows.length} 행 · 최대 ${preview.max_level} 레벨` : ""}
              </span>
            </div>
            <PreviewTree preview={preview} loading={previewLoading} />
          </div>

          {/* 도면 다중 업로드 (운영판 fn_uploadDrawingFiles placeholder → RPS 실구현) */}
          <div className="border rounded p-3">
            <div className="flex items-center justify-between mb-2">
              <span className="text-sm font-medium flex items-center gap-1">
                <Folder className="h-4 w-4 text-amber-600" /> 도면 다중 업로드
              </span>
              <span className="text-xs text-muted-foreground">.stp .step .dwg .dxf .pdf</span>
            </div>
            {projectObjid ? (
              <AttachFileDropZone
                targetObjid={projectObjid}
                docType="MBOM_DRAWING"
                docTypeName="M-BOM 도면"
                accept=".stp,.step,.dwg,.dxf,.pdf"
              />
            ) : (
              <div className="text-xs text-muted-foreground">프로젝트 선택 후 도면 업로드가 가능합니다.</div>
            )}
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}

// ─── 트리 미리보기 (간단 그리드) ───────────────────────────────
function PreviewTree({
  preview, loading,
}: { preview: MbomTreeResponse | null; loading: boolean }) {
  if (loading) {
    return (
      <div className="p-8 text-center text-sm text-muted-foreground">
        <Loader2 className="h-5 w-5 animate-spin inline mr-1" /> 트리 로딩 중…
      </div>
    );
  }
  if (!preview || preview.rows.length === 0) {
    return (
      <div className="p-8 text-center text-sm text-muted-foreground">표시할 BOM 데이터가 없습니다.</div>
    );
  }
  const maxLevel = preview.max_level || 1;
  return (
    <div className="overflow-auto max-h-[40vh]">
      <table className="min-w-full text-xs">
        <thead className="sticky top-0 bg-muted/80 border-b">
          <tr>
            <th className="px-2 py-1 text-center" style={{ width: 50 }}>#</th>
            {Array.from({ length: maxLevel }).map((_, i) => (
              <th key={i} className="px-1 py-1 text-center" style={{ width: 26 }}>{i + 1}</th>
            ))}
            <th className="px-2 py-1 text-left">품번</th>
            <th className="px-2 py-1 text-left">품명</th>
            <th className="px-2 py-1 text-right" style={{ width: 80 }}>수량</th>
            <th className="px-2 py-1 text-left">규격</th>
            <th className="px-2 py-1 text-left">소재</th>
          </tr>
        </thead>
        <tbody>
          {preview.rows.map((r: MbomTreeRow, idx: number) => (
            <tr key={`${r.objid ?? ""}-${idx}`} className={cn("border-b", levelBg(r.level))}>
              <td className="px-2 py-1 text-center text-muted-foreground">{idx + 1}</td>
              {Array.from({ length: maxLevel }).map((_, i) => (
                <td key={i} className="px-1 py-1 text-center">
                  {Number(r.level) === i + 1 ? "*" : ""}
                </td>
              ))}
              <td className="px-2 py-1 font-mono">{r.part_no ?? ""}</td>
              <td className="px-2 py-1">{r.part_name ?? ""}</td>
              <td className="px-2 py-1 text-right">{r.item_qty ?? r.qty ?? ""}</td>
              <td className="px-2 py-1">{r.spec ?? ""}</td>
              <td className="px-2 py-1">{r.material ?? ""}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function levelBg(level: number | string | null | undefined): string {
  const n = Number(level) || 0;
  switch (n) {
    case 1: return "bg-white";
    case 2: return "bg-blue-50";
    case 3: return "bg-amber-50";
    case 4: return "bg-emerald-50";
    case 5: return "bg-rose-50";
    default: return "";
  }
}
