"use client";

// 개발관리 PART Excel Import 다이얼로그
// wace partMng/openPartExcelImportPopUp.jsp 1:1
// - Template Download / Drag & Drop / 파일선택 → 백엔드 파싱 + 검증
// - 검증 그리드 22컬럼 + NOTE (에러는 빨강) — wace expenseDetailGrid 1:1
// - NOTE 있는 행이 하나라도 있으면 저장 차단 (wace fn_save 1:1)

import React, { useCallback, useMemo, useRef, useState } from "react";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Download, Upload, Save, Loader2, FileX } from "lucide-react";
import { toast } from "sonner";
import { devPartApi, PartExcelRow } from "@/lib/api/devPart";
import { cn } from "@/lib/utils";

const TEMPLATE_DOWNLOAD_URL = "/templates/PART_EXCEL_IMPORT_TEMPLATE.xlsx";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSaved: () => void;
}

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

const COLUMNS: Column[] = [
  { key: "NOTE", label: "결과", width: "min-w-[200px]", align: "left" },
  { key: "PART_NO", label: "품번", width: "min-w-[140px]", align: "center" },
  { key: "PART_NAME", label: "품명", width: "min-w-[200px]", align: "left" },
  { key: "MATERIAL", label: "재료", width: "min-w-[100px]" },
  { key: "HEAT_TREATMENT_HARDNESS", label: "열처리경도", width: "min-w-[110px]" },
  { key: "HEAT_TREATMENT_METHOD", label: "열처리방법", width: "min-w-[110px]" },
  { 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: "SPEC", label: "규격", width: "min-w-[100px]" },
  { key: "ACCTFG", label: "계정구분", width: "min-w-[90px]", align: "center", showNameFor: "ACCTFG_NAME" },
  { key: "ODRFG", label: "조달구분", width: "min-w-[90px]", align: "center", showNameFor: "ODRFG_NAME" },
  { key: "UNIT_DC", label: "재고단위", width: "min-w-[80px]", align: "center", showNameFor: "UNIT_DC_NAME" },
  { key: "UNITMANG_DC", label: "관리단위", width: "min-w-[80px]", align: "center", showNameFor: "UNITMANG_DC_NAME" },
  { key: "UNITCHNG_NB", label: "환산수량", width: "min-w-[80px]", align: "right" },
  { key: "LOT_FG", label: "LOT구분", width: "min-w-[80px]", align: "center" },
  { key: "USE_YN", label: "사용여부", width: "min-w-[80px]", align: "center" },
  { key: "QC_FG", label: "검사여부", width: "min-w-[80px]", align: "center" },
  { key: "SETITEM_FG", label: "SET품여부", width: "min-w-[90px]", align: "center" },
  { key: "REQ_FG", label: "의뢰여부", width: "min-w-[80px]", align: "center" },
  { key: "UNIT_LENGTH", label: "개당길이", width: "min-w-[80px]", align: "right" },
  { key: "UNIT_QTY", label: "개당소요량", width: "min-w-[90px]", align: "right" },
  { key: "REMARK", label: "비고", width: "min-w-[130px]", align: "left" },
];

const LABEL_LOT = { "0": "미사용", "1": "사용" } as Record<string, string>;
const LABEL_USE = { "0": "미사용", "1": "사용" } as Record<string, string>;
const LABEL_QC = { "0": "무검사", "1": "검사" } as Record<string, string>;
const LABEL_YN = { "0": "부", "1": "여" } as Record<string, string>;

function displayValue(r: PartExcelRow, col: Column): string {
  if (col.showNameFor) {
    const name = r[col.showNameFor];
    if (name) return String(name);
    return String(r[col.key] ?? "");
  }
  const v = String(r[col.key] ?? "");
  if (col.key === "LOT_FG") return LABEL_LOT[v] ?? v;
  if (col.key === "USE_YN") return LABEL_USE[v] ?? v;
  if (col.key === "QC_FG") return LABEL_QC[v] ?? v;
  if (col.key === "SETITEM_FG" || col.key === "REQ_FG") return LABEL_YN[v] ?? v;
  return v;
}

export function PartExcelImportDialog({ open, onOpenChange, onSaved }: Props) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [parsedRows, setParsedRows] = useState<PartExcelRow[]>([]);
  const [hasError, setHasError] = useState(false);
  const [fileName, setFileName] = useState<string>("");
  const [parsing, setParsing] = useState(false);
  const [saving, setSaving] = useState(false);
  const [dragOver, setDragOver] = useState(false);

  const reset = useCallback(() => {
    setParsedRows([]);
    setHasError(false);
    setFileName("");
  }, []);

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

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

  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 handleSave = async () => {
    if (parsedRows.length === 0) { toast.error("저장할 데이터가 없습니다."); return; }
    if (hasError) {
      toast.error("엑셀파일 로딩결과가 유효하지 않습니다. 결과메세지를 확인해 주세요.");
      return;
    }
    if (!confirm("저장 하시겠습니까?")) return;
    setSaving(true);
    try {
      const res = await devPartApi.excelSave(parsedRows);
      toast.success(`${res.inserted}건이 저장되었습니다.${res.skipped > 0 ? ` (중복 ${res.skipped}건 건너뜀)` : ""}`);
      onSaved();
      handleDialogChange(false);
    } catch (e: any) {
      toast.error(e?.response?.data?.message ?? e?.message ?? "저장 실패");
    } finally {
      setSaving(false);
    }
  };

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

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

        <div className="flex flex-wrap items-center gap-2 border-b pb-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">파일 선택</span>
          </Button>
          <input
            ref={fileInputRef}
            type="file"
            accept=".xlsx,.xls"
            className="hidden"
            onChange={handleFileInput}
          />
          {fileName && (
            <span className="text-sm text-muted-foreground ml-2 truncate max-w-[300px]">
              {fileName}
            </span>
          )}
          {parsedRows.length > 0 && (
            <Button variant="ghost" size="sm" onClick={reset}>
              <FileX className="h-4 w-4" /><span className="ml-1">초기화</span>
            </Button>
          )}
          <div className="ml-auto text-xs text-muted-foreground">
            총 {parsedRows.length}건
            {errorCount > 0 && <span className="ml-2 text-destructive">에러 {errorCount}건</span>}
          </div>
        </div>

        {/* Drop Zone — 파싱 전에만 노출 */}
        {parsedRows.length === 0 && !parsing && (
          <div
            className={cn(
              "border-2 border-dashed rounded p-10 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-10 w-10 mx-auto text-muted-foreground mb-2" />
            <div className="text-sm text-muted-foreground">
              Drag &amp; Drop 또는 클릭하여 엑셀 템플릿 업로드 (.xlsx, .xls)
            </div>
          </div>
        )}

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

        {/* 결과 그리드 */}
        {parsedRows.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>
                {parsedRows.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 || parsedRows.length === 0 || 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>
  );
}
