"use client";

import React, { useState, useRef } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { toast } from "sonner";
import { Upload, FileSpreadsheet, AlertCircle, CheckCircle2 } from "lucide-react";
import { importFromExcel, getExcelSheetNames } from "@/lib/utils/excelExport";
import { DynamicFormApi } from "@/lib/api/dynamicForm";

export interface ExcelUploadModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  tableName: string;
  uploadMode?: "insert" | "update" | "upsert";
  keyColumn?: string;
  onSuccess?: () => void;
}

export const ExcelUploadModal: React.FC<ExcelUploadModalProps> = ({
  open,
  onOpenChange,
  tableName,
  uploadMode = "insert",
  keyColumn,
  onSuccess,
}) => {
  const [file, setFile] = useState<File | null>(null);
  const [sheetNames, setSheetNames] = useState<string[]>([]);
  const [selectedSheet, setSelectedSheet] = useState<string>("");
  const [isUploading, setIsUploading] = useState(false);
  const [previewData, setPreviewData] = useState<Record<string, any>[]>([]);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // 파일 선택 핸들러
  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = e.target.files?.[0];
    if (!selectedFile) return;

    // 파일 확장자 검증
    const fileExtension = selectedFile.name.split(".").pop()?.toLowerCase();
    if (!["xlsx", "xls", "csv"].includes(fileExtension || "")) {
      toast.error("엑셀 파일만 업로드 가능합니다. (.xlsx, .xls, .csv)");
      return;
    }

    setFile(selectedFile);

    try {
      // 시트 목록 가져오기
      const sheets = await getExcelSheetNames(selectedFile);
      setSheetNames(sheets);
      setSelectedSheet(sheets[0] || "");

      // 미리보기 데이터 로드 (첫 5행)
      const data = await importFromExcel(selectedFile, sheets[0]);
      setPreviewData(data.slice(0, 5));

      toast.success(`파일이 선택되었습니다: ${selectedFile.name}`);
    } catch (error) {
      console.error("파일 읽기 오류:", error);
      toast.error("파일을 읽는 중 오류가 발생했습니다.");
      setFile(null);
    }
  };

  // 시트 변경 핸들러
  const handleSheetChange = async (sheetName: string) => {
    setSelectedSheet(sheetName);

    if (!file) return;

    try {
      const data = await importFromExcel(file, sheetName);
      setPreviewData(data.slice(0, 5));
    } catch (error) {
      console.error("시트 읽기 오류:", error);
      toast.error("시트를 읽는 중 오류가 발생했습니다.");
    }
  };

  // 업로드 핸들러
  const handleUpload = async () => {
    if (!file) {
      toast.error("파일을 선택해주세요.");
      return;
    }

    if (!tableName) {
      toast.error("테이블명이 지정되지 않았습니다.");
      return;
    }

    setIsUploading(true);

    try {
      // 엑셀 데이터 읽기
      const data = await importFromExcel(file, selectedSheet);

      console.log("📤 엑셀 업로드 시작:", {
        tableName,
        uploadMode,
        rowCount: data.length,
      });

      // 업로드 모드에 따라 처리
      let successCount = 0;
      let failCount = 0;

      for (const row of data) {
        try {
          if (uploadMode === "insert") {
            // 삽입 모드
            const formData = { screenId: 0, tableName, data: row };
            const result = await DynamicFormApi.saveFormData(formData);
            if (result.success) {
              successCount++;
            } else {
              console.error("저장 실패:", result.message, row);
              failCount++;
            }
          } else if (uploadMode === "update" && keyColumn) {
            // 업데이트 모드
            const keyValue = row[keyColumn];
            if (keyValue) {
              await DynamicFormApi.updateFormDataPartial(tableName, keyValue, row);
              successCount++;
            } else {
              failCount++;
            }
          } else if (uploadMode === "upsert" && keyColumn) {
            // Upsert 모드 (있으면 업데이트, 없으면 삽입)
            const keyValue = row[keyColumn];
            if (keyValue) {
              try {
                const updateResult = await DynamicFormApi.updateFormDataPartial(tableName, keyValue, row);
                if (!updateResult.success) {
                  // 업데이트 실패 시 삽입 시도
                  const formData = { screenId: 0, tableName, data: row };
                  const insertResult = await DynamicFormApi.saveFormData(formData);
                  if (insertResult.success) {
                    successCount++;
                  } else {
                    console.error("Upsert 실패:", insertResult.message, row);
                    failCount++;
                  }
                } else {
                  successCount++;
                }
              } catch {
                const formData = { screenId: 0, tableName, data: row };
                const insertResult = await DynamicFormApi.saveFormData(formData);
                if (insertResult.success) {
                  successCount++;
                } else {
                  console.error("Upsert 실패:", insertResult.message, row);
                  failCount++;
                }
              }
            } else {
              const formData = { screenId: 0, tableName, data: row };
              const result = await DynamicFormApi.saveFormData(formData);
              if (result.success) {
                successCount++;
              } else {
                console.error("저장 실패:", result.message, row);
                failCount++;
              }
            }
          }
        } catch (error) {
          console.error("행 처리 오류:", row, error);
          failCount++;
        }
      }

      console.log("✅ 엑셀 업로드 완료:", {
        successCount,
        failCount,
        totalCount: data.length,
      });

      if (successCount > 0) {
        toast.success(`${successCount}개 행이 업로드되었습니다.${failCount > 0 ? ` (실패: ${failCount}개)` : ""}`);
        // onSuccess 내부에서 closeModal이 호출되므로 여기서는 호출하지 않음
        onSuccess?.();
        // onOpenChange(false); // 제거: onSuccess에서 이미 모달을 닫음
      } else {
        toast.error("업로드에 실패했습니다.");
      }
    } catch (error) {
      console.error("❌ 엑셀 업로드 실패:", error);
      toast.error("엑셀 업로드 중 오류가 발생했습니다.");
    } finally {
      setIsUploading(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] max-w-[95vw] overflow-y-auto sm:max-w-[900px]">
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">엑셀 파일 업로드</DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            엑셀 파일을 선택하여 데이터를 업로드하세요.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* 파일 선택 */}
          <div>
            <Label htmlFor="file-upload" className="text-xs sm:text-sm">
              파일 선택 *
            </Label>
            <div className="mt-2 flex items-center gap-2">
              <Button
                type="button"
                variant="outline"
                onClick={() => fileInputRef.current?.click()}
                className="h-8 flex-1 text-xs sm:h-10 sm:text-sm"
              >
                <Upload className="mr-2 h-4 w-4" />
                {file ? file.name : "파일 선택"}
              </Button>
              <input
                ref={fileInputRef}
                id="file-upload"
                type="file"
                accept=".xlsx,.xls,.csv"
                onChange={handleFileChange}
                className="hidden"
              />
            </div>
            <p className="mt-1 text-[10px] text-muted-foreground sm:text-xs">
              지원 형식: .xlsx, .xls, .csv
            </p>
          </div>

          {/* 시트 선택 */}
          {sheetNames.length > 0 && (
            <div>
              <Label htmlFor="sheet-select" className="text-xs sm:text-sm">
                시트 선택
              </Label>
              <Select value={selectedSheet} onValueChange={handleSheetChange}>
                <SelectTrigger className="h-8 text-xs sm:h-10 sm:text-sm">
                  <SelectValue placeholder="시트를 선택하세요" />
                </SelectTrigger>
                <SelectContent>
                  {sheetNames.map((sheetName) => (
                    <SelectItem key={sheetName} value={sheetName} className="text-xs sm:text-sm">
                      <FileSpreadsheet className="mr-2 inline h-4 w-4" />
                      {sheetName}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          )}

          {/* 업로드 모드 정보 */}
          <div className="rounded-md border border-border bg-muted/50 p-3">
            <div className="flex items-start gap-2">
              <AlertCircle className="mt-0.5 h-4 w-4 text-muted-foreground" />
              <div className="text-[10px] text-muted-foreground sm:text-xs">
                <p className="font-medium">업로드 모드: {uploadMode === "insert" ? "삽입" : uploadMode === "update" ? "업데이트" : "Upsert"}</p>
                <p className="mt-1">
                  {uploadMode === "insert" && "새로운 데이터로 삽입됩니다."}
                  {uploadMode === "update" && `기존 데이터를 업데이트합니다. (키: ${keyColumn})`}
                  {uploadMode === "upsert" && `있으면 업데이트, 없으면 삽입합니다. (키: ${keyColumn})`}
                </p>
              </div>
            </div>
          </div>

          {/* 미리보기 */}
          {previewData.length > 0 && (
            <div>
              <Label className="text-xs sm:text-sm">미리보기 (최대 5행)</Label>
              <div className="mt-2 max-h-[300px] overflow-auto rounded-md border border-border">
                <table className="min-w-full text-[10px] sm:text-xs">
                  <thead className="sticky top-0 bg-muted">
                    <tr>
                      {Object.keys(previewData[0]).map((key) => (
                        <th key={key} className="whitespace-nowrap border-b border-border px-2 py-1 text-left font-medium">
                          {key}
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {previewData.map((row, index) => (
                      <tr key={index} className="border-b border-border last:border-0">
                        {Object.values(row).map((value, i) => (
                          <td key={i} className="max-w-[150px] truncate whitespace-nowrap px-2 py-1" title={String(value)}>
                            {String(value)}
                          </td>
                        ))}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
              <div className="mt-2 flex items-center gap-1 text-[10px] text-muted-foreground sm:text-xs">
                <CheckCircle2 className="h-3 w-3 text-success" />
                <span>총 {previewData.length}개 행 (미리보기)</span>
              </div>
            </div>
          )}
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            disabled={isUploading}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            취소
          </Button>
          <Button
            onClick={handleUpload}
            disabled={!file || isUploading}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            {isUploading ? "업로드 중..." : "업로드"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

