"use client";

import React, { useState, useRef, useCallback } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Download,
  Upload,
  FileSpreadsheet,
  AlertCircle,
  CheckCircle2,
  XCircle,
  Loader2,
  ArrowRight,
  Info,
} from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import type {
  SmartExcelUploadConfig,
  ParseResult,
  ParsedSheetData,
  ValidationError,
  ItemProcessMapping,
} from "./types";
// ValidationError is used in customValidator prop signature
export type { ValidationError };
import { generateTemplate } from "./templateGenerator";
import type { GenerateTemplateOptions } from "./templateGenerator";
import { parseTemplate } from "./templateParser";
import type { ParseOptions } from "./templateParser";

export interface SmartExcelUploadModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  config: SmartExcelUploadConfig;
  /** 참조 데이터 (DB에서 조회한 검사기준 등) */
  referenceData?: Record<string, any>[];
  /** 시트별/컬럼별 드롭다운 옵션 */
  dropdownOptions?: Record<string, string[]>;
  /** 품목별 공정 매핑 (INDIRECT 동적 드롭다운용) */
  itemProcessMappings?: ItemProcessMapping[];
  /** 라벨→코드 변환 매핑 */
  labelToCodeMap?: Record<string, Record<string, string>>;
  /** 추가 메타 정보 (item_code 등) */
  extraMeta?: Record<string, string>;
  /** 업로드 완료 콜백 */
  onUpload: (data: ParsedSheetData[]) => Promise<void>;
  /** 파싱 후 추가 검증 (text 타입 카테고리 검증 등 커스텀 로직) — ValidationError[] 반환, 빈 배열이면 통과 */
  customValidator?: (data: ParsedSheetData[]) => ValidationError[];
  /** 품목명 등 표시용 제목 */
  subtitle?: string;
  /** 데이터 로딩 중 여부 (외부에서 품목 등 로딩 시) */
  dataLoading?: boolean;
  /** 로딩 진행률 */
  loadProgress?: { loaded: number; total: number };
}

type Step = "download" | "upload" | "validate" | "preview";

export function SmartExcelUploadModal({
  open,
  onOpenChange,
  config,
  referenceData = [],
  dropdownOptions = {},
  itemProcessMappings = [],
  labelToCodeMap = {},
  extraMeta = {},
  onUpload,
  customValidator,
  subtitle,
  dataLoading = false,
  loadProgress,
}: SmartExcelUploadModalProps) {
  const [step, setStep] = useState<Step>("download");
  const [downloading, setDownloading] = useState(false);
  const [templateDownloaded, setTemplateDownloaded] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [parseResult, setParseResult] = useState<ParseResult | null>(null);
  const [previewTab, setPreviewTab] = useState(0);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const reset = useCallback(() => {
    setStep("download");
    setTemplateDownloaded(false);
    setParseResult(null);
    setPreviewTab(0);
    if (fileInputRef.current) fileInputRef.current.value = "";
  }, []);

  const handleClose = (open: boolean) => {
    if (!open) reset();
    onOpenChange(open);
  };

  // ═══════════════════ 템플릿 다운로드 ═══════════════════
  const handleDownload = async () => {
    setDownloading(true);
    try {
      const options: GenerateTemplateOptions = {
        config,
        referenceData,
        dropdownOptions,
        itemProcessMappings: itemProcessMappings.length > 0 ? itemProcessMappings : undefined,
        extraMeta,
      };
      const buffer = await generateTemplate(options);
      const blob = new Blob([buffer], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${config.templateName}_템플릿.xlsx`;
      a.click();
      URL.revokeObjectURL(url);

      setTemplateDownloaded(true);
      toast.success("템플릿 다운로드 완료");
    } catch (err) {
      console.error("템플릿 생성 실패:", err);
      toast.error("템플릿 생성에 실패했습니다");
    } finally {
      setDownloading(false);
    }
  };

  // ═══════════════════ 파일 업로드 + 파싱 ═══════════════════
  const handleFileChange = async (
    e: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = e.target.files?.[0];
    if (!file) return;
    // 같은 파일 재선택 허용
    e.target.value = "";

    if (!file.name.endsWith(".xlsx") && !file.name.endsWith(".xls")) {
      toast.error("엑셀 파일(.xlsx)만 업로드 가능합니다");
      return;
    }

    setUploading(true);
    setStep("validate");
    setPreviewTab(0);

    try {
      const parseOptions: ParseOptions = {
        config,
        file,
        currentReferenceData: referenceData,
        currentDropdownOptions: dropdownOptions,
        currentItemProcessMappings: itemProcessMappings.length > 0 ? itemProcessMappings : undefined,
        labelToCodeMap,
      };
      const result = await parseTemplate(parseOptions);

      // 커스텀 검증 (text 타입 카테고리 등 parseTemplate가 못 잡는 항목)
      if (customValidator && result.data.length > 0) {
        const customErrors = customValidator(result.data);
        if (customErrors.length > 0) {
          result.errors = [...result.errors, ...customErrors];
          result.success = false;
        }
      }

      setParseResult(result);

      if (result.success) {
        setStep("preview");
        toast.success("검증 통과! 미리보기를 확인해주세요");
      } else if (result.warnings.length > 0 && result.errors.length === 0) {
        // 경고만 있는 경우
        setStep("validate");
      } else {
        setStep("validate");
        toast.error(`검증 실패: ${result.errors.length}건의 오류`);
      }
    } catch (err) {
      console.error("파싱 실패:", err);
      toast.error("파일 파싱에 실패했습니다");
      setStep("upload");
    } finally {
      setUploading(false);
    }
  };

  // ═══════════════════ 저장 ═══════════════════
  const handleSave = async () => {
    if (!parseResult?.data?.length) return;
    setSaving(true);
    try {
      await onUpload(parseResult.data);
      toast.success("업로드 완료");
      handleClose(false);
    } catch (err) {
      console.error("저장 실패:", err);
      toast.error("저장에 실패했습니다");
    } finally {
      setSaving(false);
    }
  };

  // ═══════════════════ 렌더링 ═══════════════════
  const totalRows =
    parseResult?.data?.reduce((sum, d) => sum + d.rows.length, 0) || 0;

  return (
    <Dialog open={open} onOpenChange={handleClose}>
      <DialogContent className="sm:max-w-[800px] max-h-[85vh] flex flex-col">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <FileSpreadsheet className="h-5 w-5" />
            {config.templateName} 엑셀 업로드
          </DialogTitle>
          <DialogDescription>
            {subtitle || "템플릿을 다운로드하여 데이터를 작성한 후 업로드해주세요"}
          </DialogDescription>
        </DialogHeader>

        {/* 스텝 인디케이터 */}
        <div className="flex items-center gap-2 px-1 py-2">
          {(
            [
              { key: "download", label: "템플릿 다운로드", icon: Download },
              { key: "upload", label: "파일 업로드", icon: Upload },
              { key: "validate", label: "검증", icon: AlertCircle },
              { key: "preview", label: "미리보기", icon: CheckCircle2 },
            ] as const
          ).map(({ key, label, icon: Icon }, i) => {
            const stepOrder = ["download", "upload", "validate", "preview"];
            const currentIdx = stepOrder.indexOf(step);
            const thisIdx = stepOrder.indexOf(key);
            const isActive = key === step;
            const isDone = thisIdx < currentIdx;
            return (
              <React.Fragment key={key}>
                {i > 0 && (
                  <ArrowRight
                    className={cn(
                      "h-3 w-3 shrink-0",
                      isDone
                        ? "text-primary"
                        : "text-muted-foreground/40"
                    )}
                  />
                )}
                <div
                  className={cn(
                    "flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium transition-colors",
                    isActive
                      ? "bg-primary text-primary-foreground"
                      : isDone
                        ? "bg-primary/10 text-primary"
                        : "bg-muted text-muted-foreground"
                  )}
                >
                  <Icon className="h-3 w-3" />
                  {label}
                </div>
              </React.Fragment>
            );
          })}
        </div>

        {/* 컨텐츠 영역 */}
        <div className="flex-1 min-h-0 overflow-auto space-y-4">
          {/* ── 다운로드 단계 ── */}
          {(step === "download" || step === "upload") && (
            <div className="space-y-4">
              {/* 데이터 로딩 진행률 */}
              {dataLoading && loadProgress && loadProgress.total > 0 && (
                <div className="border rounded-lg p-4 space-y-2 bg-blue-50/50 border-blue-200">
                  <div className="flex items-center gap-2">
                    <Loader2 className="h-4 w-4 animate-spin text-blue-600" />
                    <span className="text-sm font-medium text-blue-700">
                      데이터 로딩 중...
                    </span>
                    <span className="text-xs text-blue-600 ml-auto">
                      {loadProgress.loaded.toLocaleString()} / {loadProgress.total.toLocaleString()}
                    </span>
                  </div>
                  <div className="w-full bg-blue-100 rounded-full h-1.5">
                    <div
                      className="bg-blue-600 h-1.5 rounded-full transition-all duration-300"
                      style={{ width: `${Math.round((loadProgress.loaded / loadProgress.total) * 100)}%` }}
                    />
                  </div>
                </div>
              )}

              {/* 템플릿 다운로드 */}
              <div
                className={cn(
                  "border rounded-lg p-4 space-y-3",
                  templateDownloaded
                    ? "border-primary/30 bg-primary/5"
                    : "border-dashed",
                  dataLoading && "opacity-50 pointer-events-none"
                )}
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <Download
                      className={cn(
                        "h-4 w-4",
                        templateDownloaded
                          ? "text-primary"
                          : "text-muted-foreground"
                      )}
                    />
                    <span className="text-sm font-medium">
                      1. 템플릿 다운로드
                    </span>
                    {templateDownloaded && (
                      <Badge
                        variant="default"
                        className="text-[10px] h-5"
                      >
                        완료
                      </Badge>
                    )}
                  </div>
                  <Button
                    size="sm"
                    variant={templateDownloaded ? "outline" : "default"}
                    onClick={handleDownload}
                    disabled={downloading || dataLoading}
                    className="h-8"
                  >
                    {downloading ? (
                      <Loader2 className="h-3.5 w-3.5 animate-spin mr-1" />
                    ) : (
                      <Download className="h-3.5 w-3.5 mr-1" />
                    )}
                    {templateDownloaded ? "다시 다운로드" : "템플릿 다운로드"}
                  </Button>
                </div>
                <div className="text-xs text-muted-foreground space-y-1">
                  <p>
                    시트 구성:{" "}
                    {config.sheets.map((s) => s.name).join(", ")}
                  </p>
                  {config.referenceSheet && (
                    <p>참조 데이터: {referenceData.length}건 포함</p>
                  )}
                </div>
              </div>

              {/* 파일 업로드 */}
              <div
                className={cn(
                  "border rounded-lg p-4 space-y-3",
                  dataLoading && "opacity-50 pointer-events-none"
                )}
              >
                <div className="flex items-center gap-2">
                  <Upload className="h-4 w-4 text-muted-foreground" />
                  <span className="text-sm font-medium">
                    2. 파일 업로드
                  </span>
                </div>
                <div className="flex items-center gap-3">
                  <input
                    ref={fileInputRef}
                    type="file"
                    accept=".xlsx,.xls"
                    onChange={handleFileChange}
                    className="text-sm file:mr-3 file:py-1.5 file:px-3 file:rounded-md file:border-0 file:text-xs file:font-medium file:bg-primary file:text-primary-foreground hover:file:bg-primary/90 cursor-pointer"
                    disabled={dataLoading || uploading}
                  />
                  {uploading && (
                    <Loader2 className="h-4 w-4 animate-spin text-primary" />
                  )}
                </div>
                {dataLoading && (
                  <p className="text-xs text-amber-600 flex items-center gap-1">
                    <Info className="h-3 w-3" />
                    데이터 로딩 중입니다. 잠시 기다려주세요
                  </p>
                )}
              </div>
            </div>
          )}

          {/* ── 검증 결과 (에러) ── */}
          {step === "validate" && parseResult && (
            <div className="space-y-4">
              {/* 경고 메시지 */}
              {parseResult.warnings.map((w, i) => (
                <div
                  key={i}
                  className="flex items-start gap-2 p-3 rounded-lg bg-amber-50 border border-amber-200 text-amber-800"
                >
                  <AlertCircle className="h-4 w-4 mt-0.5 shrink-0" />
                  <span className="text-sm">{w}</span>
                </div>
              ))}

              {/* 에러 목록 */}
              {parseResult.errors.length > 0 && (
                <div className="space-y-2">
                  <div className="flex items-center gap-2">
                    <XCircle className="h-4 w-4 text-destructive" />
                    <span className="text-sm font-medium text-destructive">
                      검증 오류 {parseResult.errors.length}건
                    </span>
                  </div>
                  <div className="border rounded-lg overflow-hidden max-h-[300px] overflow-y-auto">
                    <Table>
                      <TableHeader>
                        <TableRow className="bg-muted/50">
                          <TableHead className="text-[10px] font-bold w-[100px]">
                            시트
                          </TableHead>
                          <TableHead className="text-[10px] font-bold w-[60px]">
                            행
                          </TableHead>
                          <TableHead className="text-[10px] font-bold w-[100px]">
                            컬럼
                          </TableHead>
                          <TableHead className="text-[10px] font-bold">
                            오류 내용
                          </TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {parseResult.errors.map((err, i) => (
                          <TableRow key={i}>
                            <TableCell className="text-xs py-1.5">
                              <Badge
                                variant="outline"
                                className="text-[10px]"
                              >
                                {err.sheet}
                              </Badge>
                            </TableCell>
                            <TableCell className="text-xs py-1.5 font-mono">
                              {err.row}행
                            </TableCell>
                            <TableCell className="text-xs py-1.5">
                              {err.column}
                            </TableCell>
                            <TableCell className="text-xs py-1.5 text-destructive">
                              {err.message}
                            </TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  </div>
                </div>
              )}

              <div className="flex gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    setStep("upload");
                    setParseResult(null);
                    if (fileInputRef.current) fileInputRef.current.value = "";
                  }}
                >
                  다시 업로드
                </Button>
              </div>
            </div>
          )}

          {/* ── 미리보기 ── */}
          {step === "preview" && parseResult?.data && (
            <div className="space-y-3">
              <div className="flex items-center gap-2">
                <CheckCircle2 className="h-4 w-4 text-green-600" />
                <span className="text-sm font-medium text-green-700">
                  검증 통과
                </span>
                <Badge variant="secondary" className="text-[10px]">
                  총 {totalRows}건
                </Badge>
              </div>

              {/* 시트 탭 */}
              {parseResult.data.length > 1 && (
                <div className="flex gap-1.5">
                  {parseResult.data.map((sheet, i) => (
                    <button
                      key={i}
                      type="button"
                      onClick={() => setPreviewTab(i)}
                      className={cn(
                        "px-3 py-1.5 rounded-full text-xs font-medium transition-colors border",
                        previewTab === i
                          ? "bg-primary text-primary-foreground border-primary"
                          : "bg-muted/50 text-muted-foreground border-border hover:bg-muted"
                      )}
                    >
                      {sheet.sheetName}
                      <span className="ml-1 opacity-70">
                        ({sheet.rows.length})
                      </span>
                    </button>
                  ))}
                </div>
              )}

              {/* 데이터 테이블 */}
              {parseResult.data[previewTab] && (
                <div className="border rounded-lg overflow-hidden max-h-[350px] overflow-auto">
                  <Table>
                    <TableHeader>
                      <TableRow className="bg-muted/50">
                        <TableHead className="text-[10px] font-bold w-[40px]">
                          #
                        </TableHead>
                        {(() => {
                          const sheetData = parseResult.data[previewTab];
                          const sheetConfig = config.sheets.find(
                            (s) => s.name === sheetData.sheetName
                          );
                          return (sheetConfig?.columns || [])
                            .filter((c) => !c.readOnly && !c.autoFill && !c.customFormula)
                            .map((col) => (
                              <TableHead
                                key={col.key}
                                className="text-[10px] font-bold"
                              >
                                {col.label}
                              </TableHead>
                            ));
                        })()}
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {parseResult.data[previewTab].rows.map((row, i) => {
                        const sheetData = parseResult.data[previewTab];
                        const sheetConfig = config.sheets.find(
                          (s) => s.name === sheetData.sheetName
                        );
                        return (
                          <TableRow key={i}>
                            <TableCell className="text-[10px] py-1.5 text-muted-foreground">
                              {i + 1}
                            </TableCell>
                            {(sheetConfig?.columns || [])
                              .filter((c) => !c.readOnly && !c.autoFill && !c.customFormula)
                              .map((col) => (
                                <TableCell
                                  key={col.key}
                                  className="text-xs py-1.5"
                                >
                                  {row[`${col.key}_label`] ||
                                    row[col.key] ||
                                    "-"}
                                </TableCell>
                              ))}
                          </TableRow>
                        );
                      })}
                    </TableBody>
                  </Table>
                </div>
              )}
            </div>
          )}
        </div>

        <DialogFooter className="shrink-0">
          <Button variant="outline" onClick={() => handleClose(false)}>
            취소
          </Button>
          {step === "preview" && (
            <Button onClick={handleSave} disabled={saving}>
              {saving ? (
                <Loader2 className="h-4 w-4 animate-spin mr-1" />
              ) : (
                <Upload className="h-4 w-4 mr-1" />
              )}
              {totalRows}건 업로드
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
