"use client";

// 개발관리 > PART 도면 다중 업로드 버튼 — wace partMngTempList.jsp btnDrawingUpload 1:1.
//
// 동작:
//   1) 버튼 클릭 → 숨김 <input type="file" multiple accept=".stp,.step,.dwg,.dxf,.pdf"> 클릭
//   2) onChange → 확장자 분류 (3D/2D/PDF) + 0개 거부 + 분류표 confirm
//   3) 확인 → POST /api/development/part/drawing-multi-upload
//   4) 응답 받아 결과 다이얼로그 표시 + 그리드 새로고침

import React, { useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { FileImage, Loader2 } from "lucide-react";
import { toast } from "sonner";
import {
  devPartApi,
  DrawingMultiUploadResult,
  DrawingMultiUploadDetail,
} from "@/lib/api/devPart";

interface Props {
  /** 매칭 후보 PART_NO 범위.
   *   배열 지정 → 그 목록만 매칭 후보 (M1 등록 화면 — 현재 그리드 기반).
   *   null/undefined/빈 배열 → IS_LAST='1' 전체 part_mng 매칭 (M2 조회 화면 — 페이지 밖도 허용).
   *   (wace partMng.xml `<if PART_NO_LIST != null>` 분기 1:1) */
  partNoList?: string[] | null;
  onUploaded?: () => void; // 업로드 완료 후 그리드 새로고침
  className?: string;
}

const ACCEPT = ".stp,.step,.dwg,.dxf,.pdf";

export function PartDrawingMultiUploadButton({ partNoList, onUploaded, className }: Props) {
  const inputRef = useRef<HTMLInputElement | null>(null);
  const [uploading, setUploading] = useState(false);
  const [result, setResult] = useState<DrawingMultiUploadResult | null>(null);
  const [resultOpen, setResultOpen] = useState(false);

  const onClick = () => {
    if (uploading) return;
    inputRef.current?.click();
  };

  const onChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const picked = e.target.files;
    if (!picked || picked.length === 0) return;

    // wace fn_uploadDrawingFiles 1:1 — 확장자별 분류
    const filesByType: Record<"3D" | "2D" | "PDF", File[]> = {
      "3D": [],
      "2D": [],
      PDF: [],
    };
    for (let i = 0; i < picked.length; i++) {
      const f = picked[i];
      const dot = f.name.lastIndexOf(".");
      if (dot < 0) continue;
      const ext = f.name.substring(dot + 1).toLowerCase();
      if (ext === "stp" || ext === "step") filesByType["3D"].push(f);
      else if (ext === "dwg" || ext === "dxf") filesByType["2D"].push(f);
      else if (ext === "pdf") filesByType.PDF.push(f);
    }
    const valid = [...filesByType["3D"], ...filesByType["2D"], ...filesByType.PDF];

    // input 초기화 (같은 파일 재선택 가능)
    if (inputRef.current) inputRef.current.value = "";

    if (valid.length === 0) {
      window.alert("업로드 가능한 파일 형식이 없습니다. (stp, dwg, dxf, pdf만 가능)");
      return;
    }

    const msg =
      `총 ${valid.length}개의 파일을 업로드하시겠습니까?\n` +
      `- 3D (STP): ${filesByType["3D"].length}개\n` +
      `- 2D (DWG/DXF): ${filesByType["2D"].length}개\n` +
      `- PDF: ${filesByType.PDF.length}개`;
    if (!window.confirm(msg)) return;

    setUploading(true);
    try {
      const res = await devPartApi.drawingMultiUpload(valid, partNoList);
      setResult(res);
      setResultOpen(true);
      if (onUploaded) onUploaded();
    } catch (err: any) {
      toast.error(
        err?.response?.data?.message ?? err?.message ?? "도면 업로드 실패"
      );
    } finally {
      setUploading(false);
    }
  };

  return (
    <>
      <Button
        size="sm"
        variant="outline"
        onClick={onClick}
        disabled={uploading}
        className={className}
      >
        {uploading ? (
          <Loader2 className="h-4 w-4 animate-spin" />
        ) : (
          <FileImage className="h-4 w-4" />
        )}
        <span className="ml-1">도면 다중 업로드</span>
      </Button>
      <input
        ref={inputRef}
        type="file"
        multiple
        accept={ACCEPT}
        className="hidden"
        onChange={onChange}
      />
      <DrawingResultDialog
        open={resultOpen}
        onOpenChange={setResultOpen}
        result={result}
      />
    </>
  );
}

// ─── 결과 다이얼로그 ────────────────────────────────────────

function DrawingResultDialog({
  open,
  onOpenChange,
  result,
}: {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  result: DrawingMultiUploadResult | null;
}) {
  if (!result) return null;
  const total =
    result.successCount + result.failCount + result.notFoundCount;
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-[720px] w-[95vw] max-h-[80vh] flex flex-col p-0 overflow-hidden">
        <DialogHeader className="bg-blue-600 px-4 py-3">
          <DialogTitle className="text-white">도면 다중 업로드 결과</DialogTitle>
        </DialogHeader>

        <div className="flex-1 overflow-y-auto px-4 py-3 space-y-3">
          <div className="grid grid-cols-4 gap-2 text-sm">
            <Stat label="총합" value={total} />
            <Stat label="성공" value={result.successCount} tone="success" />
            <Stat label="품번 미존재" value={result.notFoundCount} tone="warn" />
            <Stat label="실패" value={result.failCount} tone="error" />
          </div>

          <table className="w-full border-collapse text-xs">
            <thead>
              <tr className="bg-muted/40">
                <th className="border px-2 py-1 text-left">파일명</th>
                <th className="border px-2 py-1 text-left">매칭 품번</th>
                <th className="border px-2 py-1 text-left">문서구분</th>
                <th className="border px-2 py-1 text-left">상태</th>
                <th className="border px-2 py-1 text-left">사유</th>
              </tr>
            </thead>
            <tbody>
              {result.details.map((d, i) => (
                <tr key={i}>
                  <td className="border px-2 py-1 break-all">{d.fileName}</td>
                  <td className="border px-2 py-1">{d.partNo ?? "—"}</td>
                  <td className="border px-2 py-1">{d.docType ?? "—"}</td>
                  <td className="border px-2 py-1">
                    <StatusBadge status={d.status} />
                  </td>
                  <td className="border px-2 py-1 break-all text-muted-foreground">
                    {d.reason ?? ""}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <DialogFooter className="border-t bg-muted/20 px-4 py-3 sm:justify-end">
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            닫기
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function Stat({
  label,
  value,
  tone,
}: {
  label: string;
  value: number;
  tone?: "success" | "warn" | "error";
}) {
  const cls =
    tone === "success"
      ? "text-emerald-700 bg-emerald-50"
      : tone === "warn"
      ? "text-amber-700 bg-amber-50"
      : tone === "error"
      ? "text-red-700 bg-red-50"
      : "text-foreground bg-muted/40";
  return (
    <div className={`rounded border px-2 py-2 ${cls}`}>
      <div className="text-[11px] text-muted-foreground">{label}</div>
      <div className="text-base font-semibold">{value.toLocaleString()}</div>
    </div>
  );
}

function StatusBadge({ status }: { status: DrawingMultiUploadDetail["status"] }) {
  const map: Record<
    DrawingMultiUploadDetail["status"],
    { label: string; cls: string }
  > = {
    success: { label: "성공", cls: "bg-emerald-100 text-emerald-700" },
    notFound: { label: "품번 미존재", cls: "bg-amber-100 text-amber-700" },
    unsupported: { label: "확장자 미지원", cls: "bg-amber-100 text-amber-700" },
    fail: { label: "실패", cls: "bg-red-100 text-red-700" },
  };
  const v = map[status];
  return (
    <span className={`rounded px-1.5 py-0.5 text-[11px] ${v.cls}`}>
      {v.label}
    </span>
  );
}
