"use client";

// 개발관리 E-BOM 등록 CSV Import 다이얼로그
// wace partMng/openBomReportExcelImportPopUp.jsp 1:1
//
// 운영판 흐름:
//  · Drop Zone: Drag & Drop CSV 템플릿 (fnc_setFileDropZone(..., "csv"))
//  · 파싱: parsingExcelFile.do 의 .csv 분기 → parsingCsvFile (수준 기반 부모 자동 매핑)
//  · 저장: partBomApplySave.do → savePartBomMaster
//
// CSV 컬럼 (11개, 헤더 1줄 후 데이터):
//   0:수준 1:품번 2:품명 3:수량 4:항목수량 5:재료 6:열처리경도 7:열처리방법
//   8:표면처리 9:공급업체(MAKER) 10:범주이름(PART_TYPE)

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { CommCodeSelect } from "@/components/common/CommCodeSelect";
import { SmartSelect, SmartSelectOption } from "@/components/common/SmartSelect";
import { Download, Upload, Save, Loader2, FileX, Copy } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { devBomApi, BomCsvRow, BomCopySourceRow } from "@/lib/api/devBom";

const PRODUCT_GROUP = "0000001";
const TEMPLATE_DOWNLOAD_URL = "/templates/BOM_REPORT_CSV_IMPORT_TEMPLATE.csv";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  editObjid?: string | null;
  initialProductCd?: string;
  onSaved: () => void;
}

interface Column {
  key: keyof BomCsvRow;
  label: string;
  width: string;
  align?: "left" | "center" | "right";
  showNameFor?: keyof BomCsvRow;
}

// 그리드 컬럼: 화면 표시는 핵심 + 자동 채움 컬럼 (운영 그리드 25컬럼 중 CSV 11컬럼 + 자동 ACCTFG/ODRFG)
const COLUMNS: Column[] = [
  { key: "NOTE", label: "결과", width: "min-w-[200px]", align: "left" },
  { key: "LEVEL", label: "수준", width: "min-w-[60px]", align: "center" },
  { key: "PARENT_PART_NO", label: "모품번 (자동)", width: "min-w-[140px]", align: "center" },
  { key: "PART_NO", label: "품번", width: "min-w-[140px]", align: "center" },
  { key: "PART_NAME", label: "품명", width: "min-w-[200px]", align: "left" },
  { key: "QTY", label: "수량", width: "min-w-[70px]", align: "right" },
  { key: "ITEM_QTY", label: "항목수량", width: "min-w-[80px]", align: "right" },
  { key: "MATERIAL", label: "재료", width: "min-w-[100px]" },
  { key: "HEAT_TREATMENT_HARDNESS", label: "열처리경도", width: "min-w-[100px]" },
  { key: "HEAT_TREATMENT_METHOD", label: "열처리방법", width: "min-w-[100px]" },
  { key: "SURFACE_TREATMENT", label: "표면처리", width: "min-w-[100px]" },
  { key: "MAKER", label: "공급업체", width: "min-w-[110px]" },
  { key: "PART_TYPE", label: "범주", width: "min-w-[90px]", align: "center", showNameFor: "PART_TYPE_NAME" },
  { key: "ACCTFG", label: "계정구분(자동)", width: "min-w-[90px]", align: "center" },
  { key: "ODRFG", label: "조달구분(자동)", width: "min-w-[90px]", align: "center" },
];

const ACCTFG_LABEL: Record<string, string> = { "4": "반제품", "7": "비용" };
const ODRFG_LABEL: Record<string, string> = { "0": "구매", "1": "생산", "8": "Phantom" };

function displayValue(r: BomCsvRow, col: Column): string {
  if (col.key === "ACCTFG") {
    const v = String(r.ACCTFG ?? "");
    return ACCTFG_LABEL[v] ?? v;
  }
  if (col.key === "ODRFG") {
    const v = String(r.ODRFG ?? "");
    return ODRFG_LABEL[v] ?? v;
  }
  if (col.showNameFor) {
    const name = r[col.showNameFor];
    if (name) return String(name);
  }
  return String(r[col.key] ?? "");
}

export function BomReportExcelImportDialog({ open, onOpenChange, editObjid, initialProductCd, onSaved }: Props) {
  const fileInputRef = useRef<HTMLInputElement>(null);

  const [productCd, setProductCd] = useState<string>("");
  const [bomPartNo, setBomPartNo] = useState<string>("");
  const [bomPartName, setBomPartName] = useState<string>("");
  const [version, setVersion] = useState<string>("");

  const [copyOptions, setCopyOptions] = useState<BomCopySourceRow[]>([]);
  const [copySelect, setCopySelect] = useState<string>("");

  const [rows, setRows] = useState<BomCsvRow[]>([]);
  const [hasError, setHasError] = useState(false);
  const [fileName, setFileName] = useState<string>("");
  const [encoding, setEncoding] = useState<string>("");
  const [parsing, setParsing] = useState(false);
  const [saving, setSaving] = useState(false);
  const [copying, setCopying] = useState(false);
  const [dragOver, setDragOver] = useState(false);

  const reset = useCallback(() => {
    setProductCd(initialProductCd ?? "");
    setBomPartNo("");
    setBomPartName("");
    setVersion("");
    setRows([]);
    setHasError(false);
    setFileName("");
    setEncoding("");
    setCopySelect("");
  }, [initialProductCd]);

  useEffect(() => {
    if (!open) return;
    reset();
    devBomApi.excelCopySource().then(setCopyOptions).catch(() => setCopyOptions([]));
  }, [open, reset]);

  const handleDialogChange = (v: boolean) => {
    if (!v) reset();
    onOpenChange(v);
  };

  const applyFirstLevelToHeader = (first: { part_no: string; part_name: string } | null) => {
    if (!first) return;
    if (first.part_no) setBomPartNo(first.part_no);
    if (first.part_name) setBomPartName(first.part_name);
  };

  const parseFile = useCallback(async (file: File) => {
    if (!/\.csv$/i.test(file.name)) {
      toast.error("CSV(.csv) 파일만 업로드 가능합니다.");
      return;
    }
    setParsing(true);
    setFileName(file.name);
    try {
      const data = await devBomApi.excelParse(file);
      setRows(data.rows ?? []);
      setHasError(!!data.hasError);
      setEncoding(data.encoding ?? "");
      applyFirstLevelToHeader(data.firstLevel);
      if (!data.rows || data.rows.length === 0) {
        toast.warning("파싱된 데이터가 없습니다. CSV 형식을 확인해 주세요.");
      } else if (data.hasError) {
        toast.error("CSV 파일 로딩결과가 유효하지 않습니다. 결과 메시지를 확인해 주세요.");
      } else {
        toast.success(`${data.rows.length}건 파싱 완료 (인코딩: ${data.encoding})`);
      }
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "CSV 파싱 실패");
      setRows([]); setHasError(false); setFileName(""); setEncoding("");
    } finally {
      setParsing(false);
    }
  }, []);

  const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    const f = e.target.files?.[0];
    if (f) parseFile(f);
    e.target.value = "";
  };
  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setDragOver(false);
    const f = e.dataTransfer.files?.[0];
    if (f) parseFile(f);
  };

  const handleCopy = async () => {
    if (!copySelect) { toast.error("복사할 BOM을 선택하세요."); return; }
    setCopying(true);
    try {
      const copied = await devBomApi.excelCopy(copySelect);
      setRows(copied);
      setHasError(false);
      const first = copied.find((r) => !r.PARENT_PART_NO);
      if (first) applyFirstLevelToHeader({ part_no: first.PART_NO, part_name: first.PART_NAME });
      toast.success(`BOM 데이터 ${copied.length}건 불러왔습니다.`);
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "BOM 복사 실패");
    } finally {
      setCopying(false);
    }
  };

  const handleSave = async () => {
    if (!productCd) { toast.error("제품구분을 선택해 주세요."); return; }
    if (!bomPartNo)  { toast.error("품번을 입력해 주세요."); return; }
    if (!bomPartName){ toast.error("품명을 입력해 주세요."); return; }
    if (hasError) {
      toast.error("CSV 파일 로딩결과가 유효하지 않습니다. 결과 메시지를 확인해 주세요.");
      return;
    }
    try {
      const dup = await devBomApi.excelCheckDuplicate(bomPartNo, editObjid ?? undefined);
      if (dup) {
        toast.error("입력한 품번이 이미 존재합니다. 다른 품번을 입력해주세요.");
        return;
      }
    } catch { /* 비차단 */ }

    const confirmMsg = rows.length > 0 ? "저장 하시겠습니까?" : "품번, 품명으로 빈 E-BOM을 생성하시겠습니까?";
    if (!confirm(confirmMsg)) return;

    setSaving(true);
    try {
      const result = await devBomApi.excelSave({
        bomReportObjid: editObjid ?? undefined,
        productCd, partNo: bomPartNo, partName: bomPartName, version,
        rows,
      });
      toast.success(`${result.mode === "create" ? "등록" : "수정"} 완료 — BOM ${result.bomRows}건 (PART 신규 ${result.insertedParts} / 수정 ${result.updatedParts})`);
      onSaved();
      handleDialogChange(false);
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "저장 실패");
    } finally {
      setSaving(false);
    }
  };

  const errorCount = useMemo(() => rows.filter((r) => r.NOTE).length, [rows]);

  return (
    <Dialog open={open} onOpenChange={handleDialogChange}>
      <DialogContent className="max-w-[1500px] w-[97vw] max-h-[92vh] flex flex-col">
        <DialogHeader>
          <DialogTitle>PART 및 구조등록 CSV upload</DialogTitle>
        </DialogHeader>

        {/* 헤더 */}
        <div className="grid grid-cols-4 gap-3 border-b pb-3">
          <div>
            <Label className="mb-1 block text-xs text-muted-foreground">제품구분 *</Label>
            <CommCodeSelect
              groupId={PRODUCT_GROUP}
              value={productCd}
              onValueChange={setProductCd}
            />
          </div>
          <div>
            <Label className="mb-1 block text-xs text-muted-foreground">품번 * (1레벨 자동)</Label>
            <Input value={bomPartNo} readOnly placeholder="CSV 1레벨에서 자동 채움" />
          </div>
          <div>
            <Label className="mb-1 block text-xs text-muted-foreground">품명 * (1레벨 자동)</Label>
            <Input value={bomPartName} readOnly placeholder="CSV 1레벨에서 자동 채움" />
          </div>
          <div>
            <Label className="mb-1 block text-xs text-muted-foreground">Version</Label>
            <Input value={version} onChange={(e) => setVersion(e.target.value)} placeholder="REV 등" />
          </div>
        </div>

        {/* E-BOM 복사 + 액션 버튼 */}
        <div className="flex flex-wrap items-center gap-2 border-b pb-3">
          <div className="flex items-center gap-2">
            <Label className="text-xs text-muted-foreground whitespace-nowrap">E-BOM 복사</Label>
            <div className="min-w-[280px]">
              <SmartSelect
                options={copyOptions.map<SmartSelectOption>((o) => ({
                  code: o.objid,
                  label: `${o.part_no} / ${o.part_name}${o.revision ? ` (v${o.revision})` : ""}${o.regdate ? ` - ${o.regdate}` : ""}`,
                }))}
                value={copySelect}
                onValueChange={setCopySelect}
                placeholder="선택"
              />
            </div>
            <Button variant="outline" size="sm" onClick={handleCopy} disabled={copying || !copySelect}>
              {copying ? <Loader2 className="h-4 w-4 animate-spin" /> : <Copy className="h-4 w-4" />}
              <span className="ml-1">복사</span>
            </Button>
          </div>
          <div className="ml-auto flex items-center gap-2">
            <Button variant="outline" size="sm" asChild>
              <a href={TEMPLATE_DOWNLOAD_URL} download>
                <Download className="h-4 w-4" /><span className="ml-1">Template Download</span>
              </a>
            </Button>
            <Button variant="outline" size="sm" onClick={() => fileInputRef.current?.click()} disabled={parsing}>
              <Upload className="h-4 w-4" /><span className="ml-1">CSV 파일 선택</span>
            </Button>
            <input
              ref={fileInputRef}
              type="file"
              accept=".csv,text/csv"
              className="hidden"
              onChange={handleFileInput}
            />
            {rows.length > 0 && (
              <Button variant="ghost" size="sm"
                      onClick={() => { setRows([]); setHasError(false); setFileName(""); setEncoding(""); }}>
                <FileX className="h-4 w-4" /><span className="ml-1">초기화</span>
              </Button>
            )}
          </div>
        </div>

        <div className="text-xs text-muted-foreground flex items-center gap-3">
          {fileName && <span className="truncate max-w-[400px]">{fileName}</span>}
          {encoding && <span>인코딩: <b>{encoding}</b></span>}
          <span>총 {rows.length}건</span>
          {errorCount > 0 && <span className="text-destructive font-semibold">에러 {errorCount}건</span>}
        </div>

        {/* Drop Zone */}
        {rows.length === 0 && !parsing && (
          <div
            className={cn(
              "border-2 border-dashed rounded p-8 text-center transition-colors cursor-pointer",
              dragOver ? "border-primary bg-primary/5" : "border-muted-foreground/30"
            )}
            onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
            onDragLeave={() => setDragOver(false)}
            onDrop={handleDrop}
            onClick={() => fileInputRef.current?.click()}
          >
            <Upload className="h-9 w-9 mx-auto text-muted-foreground mb-2" />
            <div className="text-sm text-muted-foreground">
              Drag &amp; Drop 또는 클릭하여 CSV 템플릿 업로드 (.csv)
            </div>
            <div className="mt-1 text-xs text-muted-foreground">
              컬럼: 수준 / 품번 / 품명 / 수량 / 항목수량 / 재료 / 열처리경도 / 열처리방법 / 표면처리 / 공급업체 / 범주이름
            </div>
          </div>
        )}

        {parsing && (
          <div className="flex items-center justify-center py-8 text-muted-foreground">
            <Loader2 className="h-5 w-5 animate-spin" /><span className="ml-2">파싱 중...</span>
          </div>
        )}

        {/* 결과 그리드 */}
        {rows.length > 0 && !parsing && (
          <div className="flex-1 min-h-0 overflow-auto border rounded">
            <table className="text-xs border-collapse w-max min-w-full">
              <thead className="bg-muted sticky top-0">
                <tr>
                  <th className="border px-2 py-1 w-[40px] text-center">#</th>
                  {COLUMNS.map((c) => (
                    <th key={c.key as string} className={cn("border px-2 py-1", c.width)}>
                      {c.label}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {rows.map((r, i) => (
                  <tr key={i} className={r.NOTE ? "bg-destructive/5" : ""}>
                    <td className="border px-2 py-1 text-center">{i + 1}</td>
                    {COLUMNS.map((c) => {
                      const value = displayValue(r, c);
                      const isNote = c.key === "NOTE";
                      return (
                        <td
                          key={c.key as string}
                          className={cn(
                            "border px-2 py-1 whitespace-nowrap",
                            c.align === "right" && "text-right",
                            c.align === "center" && "text-center",
                            isNote && r.NOTE && "text-destructive font-semibold"
                          )}
                          title={value}
                        >
                          {value}
                        </td>
                      );
                    })}
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        <DialogFooter className="gap-2">
          <Button variant="outline" onClick={() => handleDialogChange(false)}>닫기</Button>
          <Button onClick={handleSave} disabled={saving || hasError}>
            {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
            <span className="ml-1">저장</span>
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
