"use client";

import * as React from "react";
import { useState } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { FolderOpen, Loader2, ChevronRight, ChevronLeft, CheckCircle2 } from "lucide-react";
import { toast } from "sonner";
import { Progress } from "@/components/ui/progress";
import { useTranslation } from "@/i18n/client";
import {
  validateB4FileName,
  B4UploadValidationDialog,
  type FileValidationResult,
} from "./b4-upload-validation-dialog";
import {
  checkB4MappingStatus,
  saveB4MappingBatch,
  type MappingCheckResult,
  type B4BulkUploadResult,
  type B4MappingSaveItem,
} from "../actions";
import { uploadFilesWithProgress } from "../utils/upload-with-progress";
import { FileUploadProgressList } from "../components/file-upload-progress-list";
import type { FileUploadProgress } from "../hooks/use-file-upload-with-progress";
import { v4 as uuidv4 } from "uuid";

interface B4BulkUploadDialogV3Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  projectNo: string;
  userId: string;
  userName: string;
  userEmail: string;
  vendorCode: string;
  onUploadComplete?: () => void;
  lng: string;
}

type UploadStep = "files" | "validation" | "uploading" | "complete";

export function B4BulkUploadDialogV3({
  open,
  onOpenChange,
  projectNo,
  userId,
  userName,
  userEmail,
  vendorCode,
  onUploadComplete,
  lng,
}: B4BulkUploadDialogV3Props) {
  const { t } = useTranslation(lng, "dolce");
  const [currentStep, setCurrentStep] = useState<UploadStep>("files");
  const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
  const [isUploading, setIsUploading] = useState(false);
  const [validationResults, setValidationResults] = useState<FileValidationResult[]>([]);
  const [mappingResultsMap, setMappingResultsMap] = useState<Map<string, MappingCheckResult>>(new Map());
  const [showValidationDialog, setShowValidationDialog] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadResult, setUploadResult] = useState<B4BulkUploadResult | null>(null);
  const [fileProgresses, setFileProgresses] = useState<FileUploadProgress[]>([]);

  // Reset on close
  React.useEffect(() => {
    if (!open) {
      setCurrentStep("files");
      setSelectedFiles([]);
      setValidationResults([]);
      setMappingResultsMap(new Map());
      setShowValidationDialog(false);
      setIsDragging(false);
      setUploadProgress(0);
      setUploadResult(null);
      setFileProgresses([]);
    }
  }, [open]);

  // File Selection Handler
  const handleFilesChange = (files: File[]) => {
    if (files.length === 0) return;

    const existingNames = new Set(selectedFiles.map((f) => f.name));
    const newFiles = files.filter((f) => !existingNames.has(f.name));

    if (newFiles.length === 0) {
      toast.error(t("bulkUpload.duplicateFileError"));
      return;
    }

    setSelectedFiles((prev) => [...prev, ...newFiles]);
    toast.success(t("bulkUpload.filesSelectedSuccess", { count: newFiles.length }));
  };

  // Drag & Drop Handlers
  const handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
  };

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.currentTarget === e.target) {
      setIsDragging(false);
    }
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    e.dataTransfer.dropEffect = "copy";
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);

    const droppedFiles = Array.from(e.dataTransfer.files);
    if (droppedFiles.length > 0) {
      handleFilesChange(droppedFiles);
    }
  };

  const handleRemoveFile = (index: number) => {
    setSelectedFiles((prev) => prev.filter((_, i) => i !== index));
  };

  // Step 1 Next: Validation
  const handleFilesNext = () => {
    if (selectedFiles.length === 0) {
      toast.error(t("bulkUpload.selectFilesError"));
      return;
    }
    setCurrentStep("validation");
    handleValidate();
  };

  // Validation Process (V3)
  const handleValidate = async () => {
    try {
      console.log("[V3 Dialog] Validation started");

      // 1. Parse Filenames
      const parseResults: FileValidationResult[] = selectedFiles.map((file) => {
        const validation = validateB4FileName(file.name);
        return {
          file,
          valid: validation.valid,
          parsed: validation.parsed,
          error: validation.error,
        };
      });

      const parsedFiles = parseResults.filter((r) => r.valid && r.parsed);
      
      // If no files parsed correctly, show dialog immediately with errors
      if (parsedFiles.length === 0) {
        setValidationResults(parseResults);
        setShowValidationDialog(true);
        return;
      }

      // 2. Call MatchBatchFileDwg to check mapping status
      const mappingCheckItems = parsedFiles.map((r) => ({
        DrawingNo: r.parsed!.drawingNo,
        RevNo: r.parsed!.revNo,
        FileNm: r.file.name,
      }));

      console.log(`[V3 Dialog] Checking mapping for ${mappingCheckItems.length} files`);

      const mappingResults = await checkB4MappingStatus(
        projectNo,
        mappingCheckItems
      );

      // Store mapping results for later use (upload/save)
      const newMappingResultsMap = new Map<string, MappingCheckResult>();
      mappingResults.forEach((result) => {
        newMappingResultsMap.set(result.FileNm, result);
      });
      setMappingResultsMap(newMappingResultsMap);

      // 3. Merge results
      const finalResults: FileValidationResult[] = parseResults.map((parseResult) => {
        if (!parseResult.valid || !parseResult.parsed) {
          return parseResult;
        }

        const mappingResult = newMappingResultsMap.get(parseResult.file.name);

        if (!mappingResult) {
          return {
            ...parseResult,
            mappingStatus: "not_found" as const,
            error: t("validation.notFound"),
          };
        }

        // According to prompt: "API 응답에서 매핑되지 않은 경우는, 파일명으로부터 파싱된 도면이 없는 경우임."
        // Also "MappingYN 의 값이 현재 매핑이 되어있는지를 나타냄. Y인 건들은 저장 가능"
        if (mappingResult.MappingYN !== "Y") {
           return {
            ...parseResult,
            mappingStatus: "not_found" as const,
            error: t("validation.notRegistered"), // Or specific message for MappingYN=N
          };
        }
        
        // Check DrawingMoveGbn = "도면입수" (implied by requirements to use MatchBatchFileDwg with 도면입수)
        if (mappingResult.DrawingMoveGbn !== "도면입수") {
            return {
                ...parseResult,
                mappingStatus: "not_found" as const,
                error: t("validation.notGttDeliverables"),
            };
        }

        return {
          ...parseResult,
          mappingStatus: "available" as const,
          drawingName: mappingResult.DrawingName || undefined,
          registerGroupId: mappingResult.RegisterGroupId,
        };
      });

      console.log("[V3 Dialog] Validation complete");
      setValidationResults(finalResults);
      setShowValidationDialog(true);
    } catch (error) {
      console.error("[V3 Dialog] Validation failed:", error);
      toast.error(
        error instanceof Error ? error.message : t("bulkUpload.validationError")
      );
      // Go back to files step if validation crashes completely
      setCurrentStep("files");
    }
  };

  // Confirm Upload & Save (V3)
  const handleConfirmUpload = async (validFiles: FileValidationResult[]) => {
    setIsUploading(true);
    setCurrentStep("uploading");
    setShowValidationDialog(false);

    try {
      console.log(`[V3 Dialog] Upload started: ${validFiles.length} files`);

      // 0. Initialize progress
      const initialProgresses: FileUploadProgress[] = validFiles.map((fileResult) => ({
        file: fileResult.file,
        progress: 0,
        status: "pending" as const,
      }));
      setFileProgresses(initialProgresses);

      // 1. Group by DrawingNo + RevNo (to share UploadId if needed)
      const uploadGroups = new Map<
        string,
        Array<{
            file: File;
            fileIndex: number; // Index in validFiles
            mappingData: MappingCheckResult;
        }>
      >();

      // Pre-process groups
      validFiles.forEach((fileResult, index) => {
          const mappingData = mappingResultsMap.get(fileResult.file.name);
          if (!mappingData) return; // Should not happen for valid files

          const groupKey = `${mappingData.DrawingNo}_${mappingData.RevNo}`;
          if (!uploadGroups.has(groupKey)) {
              uploadGroups.set(groupKey, []);
          }
          uploadGroups.get(groupKey)!.push({
              file: fileResult.file,
              fileIndex: index,
              mappingData
          });
      });

      let successCount = 0;
      let failCount = 0;
      let completedGroups = 0;
      const results: B4BulkUploadResult["results"] = [];

      // 2. Process each group
      for (const [groupKey, groupItems] of uploadGroups.entries()) {
          // Reuse UploadId from the first item's mapping data if available, else generate new
          const firstItemMapping = groupItems[0].mappingData;
          // Reuse existing UploadId if present in API response, otherwise generate new one
          // UploadId는 있으면 재활용하고, 없으면 UUID로 만들어서 사용
          const uploadId = firstItemMapping.UploadId || uuidv4();
          
          console.log(`[V3 Dialog] Processing group ${groupKey}, UploadId: ${uploadId}`);

          try {
             // Update status to uploading
             setFileProgresses((prev) => 
                prev.map((fp, idx) => 
                    groupItems.some(item => item.fileIndex === idx)
                        ? { ...fp, status: "uploading" as const }
                        : fp
                )
             );

             // A. Upload Files (Physical Upload)
             const uploadResult = await uploadFilesWithProgress({
                uploadId: uploadId,
                userId: userId,
                files: groupItems.map(item => item.file),
                callbacks: {
                    onProgress: (fileIndexInGroup, progress) => {
                        const globalFileIndex = groupItems[fileIndexInGroup].fileIndex;
                        setFileProgresses((prev) =>
                            prev.map((fp, idx) =>
                                idx === globalFileIndex
                                ? { ...fp, progress, status: "uploading" as const }
                                : fp
                            )
                        );

                        // Overall progress approximation
                        const groupProgress = (completedGroups / uploadGroups.size) * 100;
                        const currentGroupProgress = (progress / 100) * (100 / uploadGroups.size);
                        setUploadProgress(Math.round(groupProgress + currentGroupProgress));
                    },
                    onFileComplete: (fileIndexInGroup) => {
                        const globalFileIndex = groupItems[fileIndexInGroup].fileIndex;
                        setFileProgresses((prev) =>
                            prev.map((fp, idx) =>
                                idx === globalFileIndex
                                ? { ...fp, progress: 100, status: "completed" as const }
                                : fp
                            )
                        );
                    },
                    onFileError: (fileIndexInGroup, error) => {
                        const globalFileIndex = groupItems[fileIndexInGroup].fileIndex;
                        console.error(`[V3 Dialog] File upload error:`, error);
                         setFileProgresses((prev) =>
                            prev.map((fp, idx) =>
                                idx === globalFileIndex
                                ? { ...fp, status: "error" as const, error }
                                : fp
                            )
                        );
                    }
                }
             });

             if (!uploadResult.success) {
                 throw new Error(uploadResult.error || "File upload failed");
             }

             // B. Save Metadata (MatchBatchFileDwgEdit)
             // Construct payload from mappingData + generated UploadId + hardcoded values as per prompt
             const mappingSaveLists: B4MappingSaveItem[] = groupItems.map(item => {
                 const m = item.mappingData;
                 return {
                    CGbn: m.CGbn,
                    Category: "TS", // Hardcoded fixed value is required!
                    CheckBox: m.CheckBox,
                    DGbn: m.DGbn,
                    DegreeGbn: m.DegreeGbn,
                    DeptGbn: m.DeptGbn,
                    Discipline: m.Discipline,
                    DrawingKind: m.DrawingKind,
                    DrawingMoveGbn: m.DrawingMoveGbn,
                    DrawingName: m.DrawingName,
                    DrawingNo: m.DrawingNo,
                    DrawingUsage: m.DrawingUsage,
                    FileNm: item.file.name,
                    JGbn: m.JGbn,
                    Manager: m.Manager,
                    MappingYN: m.MappingYN,
                    NewOrNot: m.NewOrNot,
                    ProjectNo: projectNo,
                    RegisterGroup: m.RegisterGroup,
                    RegisterGroupId: m.RegisterGroupId,
                    RegisterKindCode: m.RegisterKindCode,
                    RegisterSerialNo: m.RegisterSerialNo,
                    RevNo: m.RevNo,
                    SGbn: m.SGbn,
                    UploadId: uploadId, // Used for all files in this group
                    status: "Standby", // Hardcoded fixed value is required!
                 };
             });

             await saveB4MappingBatch(mappingSaveLists, {
                userId,
                userName,
                vendorCode,
                email: userEmail,
             });

             console.log(`[V3 Dialog] Group ${groupKey} complete`);
             successCount += groupItems.length;
             
             groupItems.forEach(item => {
                 results.push({
                     drawingNo: item.mappingData.DrawingNo,
                     revNo: item.mappingData.RevNo || "",
                     fileName: item.file.name,
                     success: true
                 });
             });

          } catch (error) {
              console.error(`[V3 Dialog] Group ${groupKey} failed:`, error);
              failCount += groupItems.length;
              const errorMessage = error instanceof Error ? error.message : "Unknown error";
              
              groupItems.forEach(item => {
                 results.push({
                     drawingNo: item.mappingData.DrawingNo,
                     revNo: item.mappingData.RevNo || "",
                     fileName: item.file.name,
                     success: false,
                     error: errorMessage
                 });
             });
          }

          completedGroups++;
          setUploadProgress(Math.round((completedGroups / uploadGroups.size) * 100));
      }

      // Finalize
      const result: B4BulkUploadResult = {
        success: successCount > 0,
        successCount,
        failCount,
        results,
      };

      setUploadResult(result);
      setCurrentStep("complete");

      if (result.success) {
        toast.success(
          t("bulkUpload.uploadSuccessToast", {
            successCount: result.successCount,
            total: validFiles.length,
          })
        );
      } else {
        toast.error(result.error || t("bulkUpload.uploadError"));
      }

    } catch (error) {
      console.error("[V3 Dialog] Upload process failed:", error);
      toast.error(
        error instanceof Error ? error.message : t("bulkUpload.uploadError")
      );
      setCurrentStep("files");
    } finally {
      setIsUploading(false);
    }
  };

  return (
    <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{t("bulkUpload.title")} (V3)</DialogTitle>
            <DialogDescription>
              {currentStep === "files" && t("bulkUpload.stepFiles")}
              {currentStep === "validation" && t("bulkUpload.stepValidation")}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            {/* Step 1: Files */}
            {currentStep === "files" && (
              <>
                <div
                  className={`border-2 border-dashed rounded-lg p-8 transition-all duration-200 ${
                    isDragging
                      ? "border-primary bg-primary/5 scale-[1.02]"
                      : "border-muted-foreground/30 hover:border-muted-foreground/50"
                  }`}
                  onDragEnter={handleDragEnter}
                  onDragLeave={handleDragLeave}
                  onDragOver={handleDragOver}
                  onDrop={handleDrop}
                >
                  <input
                    type="file"
                    multiple
                    accept=".pdf,.doc,.docx,.xls,.xlsx,.dwg,.dxf,.zip"
                    onChange={(e) => handleFilesChange(Array.from(e.target.files || []))}
                    className="hidden"
                    id="b4-file-upload-v3"
                  />
                  <label
                    htmlFor="b4-file-upload-v3"
                    className="flex flex-col items-center justify-center cursor-pointer"
                  >
                    <FolderOpen
                      className={`h-12 w-12 mb-3 transition-colors ${
                        isDragging ? "text-primary" : "text-muted-foreground"
                      }`}
                    />
                    <p
                      className={`text-sm transition-colors ${
                        isDragging
                          ? "text-primary font-medium"
                          : "text-muted-foreground"
                      }`}
                    >
                      {isDragging
                        ? t("bulkUpload.fileDropHere")
                        : t("bulkUpload.fileSelectArea")}
                    </p>
                    <p className="text-xs text-muted-foreground mt-1">
                      {t("bulkUpload.fileTypes")}
                    </p>
                  </label>
                </div>

                {selectedFiles.length > 0 && (
                  <div className="border rounded-lg p-4">
                    <div className="flex items-center justify-between mb-3">
                      <h4 className="text-sm font-medium">
                        {t("bulkUpload.selectedFiles", { count: selectedFiles.length })}
                      </h4>
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => setSelectedFiles([])}
                      >
                        {t("bulkUpload.removeAll")}
                      </Button>
                    </div>
                    <div className="max-h-60 overflow-y-auto space-y-2">
                      {selectedFiles.map((file, index) => (
                        <div
                          key={index}
                          className="flex items-center justify-between p-2 rounded bg-muted/50"
                        >
                          <div className="flex-1 min-w-0">
                            <p className="text-sm truncate">{file.name}</p>
                            <p className="text-xs text-muted-foreground">
                              {(file.size / 1024 / 1024).toFixed(2)} MB
                            </p>
                          </div>
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => handleRemoveFile(index)}
                          >
                            {t("bulkUpload.removeFile")}
                          </Button>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </>
            )}

            {/* Loading Indicator */}
            {currentStep === "validation" && (
              <div className="flex flex-col items-center justify-center py-12">
                <Loader2 className="h-12 w-12 animate-spin text-primary mb-4" />
                <p className="text-sm text-muted-foreground">
                  {t("bulkUpload.validating")}
                </p>
              </div>
            )}

            {/* Uploading Progress */}
            {currentStep === "uploading" && (
              <div className="space-y-6 py-4">
                <div className="flex flex-col items-center">
                  <Loader2 className="h-12 w-12 animate-spin text-primary mb-4" />
                  <h3 className="text-lg font-semibold mb-2">{t("bulkUpload.uploading")}</h3>
                  <p className="text-sm text-muted-foreground">
                    {t("bulkUpload.uploadingWait")}
                  </p>
                </div>
                
                <div className="space-y-2">
                  <div className="flex justify-between text-sm">
                    <span>{t("bulkUpload.uploadProgress")}</span>
                    <span>{uploadProgress}%</span>
                  </div>
                  <Progress value={uploadProgress} className="h-2" />
                </div>

                {fileProgresses.length > 0 && (
                  <div className="border rounded-lg p-4 max-h-96 overflow-y-auto">
                    <FileUploadProgressList fileProgresses={fileProgresses} />
                  </div>
                )}
              </div>
            )}

            {/* Completion Screen */}
            {currentStep === "complete" && uploadResult && (
              <div className="space-y-6 py-8">
                <div className="flex flex-col items-center">
                  <CheckCircle2 className="h-16 w-16 text-green-500 mb-4" />
                  <h3 className="text-lg font-semibold mb-2">{t("bulkUpload.uploadComplete")}</h3>
                  <p className="text-sm text-muted-foreground">
                    {t("bulkUpload.uploadSuccessMessage", { count: uploadResult.successCount })}
                  </p>
                </div>
                
                {uploadResult.failCount && uploadResult.failCount > 0 && (
                  <div className="bg-yellow-50 dark:bg-yellow-950/30 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4">
                    <p className="text-sm text-yellow-800 dark:text-yellow-200">
                      {t("bulkUpload.uploadFailMessage", { count: uploadResult.failCount })}
                    </p>
                  </div>
                )}

                <div className="flex justify-center">
                  <Button
                    onClick={() => {
                      onOpenChange(false);
                      onUploadComplete?.();
                    }}
                  >
                    {t("bulkUpload.confirmButton")}
                  </Button>
                </div>
              </div>
            )}
          </div>

          {/* Footer */}
          {currentStep !== "uploading" && currentStep !== "complete" && currentStep !== "validation" && (
            <DialogFooter>
              {currentStep === "files" && (
                <>
                   <Button
                    variant="outline"
                    onClick={() => onOpenChange(false)}
                  >
                    {t("bulkUpload.cancelButton")}
                  </Button>
                  <Button
                    onClick={handleFilesNext}
                    disabled={selectedFiles.length === 0}
                  >
                    {t("bulkUpload.validateButton")}
                    <ChevronRight className="ml-2 h-4 w-4" />
                  </Button>
                </>
              )}
            </DialogFooter>
          )}
        </DialogContent>
      </Dialog>

      {/* Validation Dialog */}
      <B4UploadValidationDialog
        open={showValidationDialog}
        onOpenChange={(open) => {
          setShowValidationDialog(open);
          if (!open && currentStep !== "uploading" && currentStep !== "complete") {
            // If canceled during validation view (and not proceeding to upload), go back to file selection or close?
            // Usually just close the validation dialog allows user to fix files in the main dialog, 
            // but here the main dialog is in "validation" state which is just a loader.
            // So we should reset main dialog to "files" step.
             setCurrentStep("files");
          }
        }}
        validationResults={validationResults}
        onConfirmUpload={handleConfirmUpload}
        isUploading={isUploading}
      />
    </>
  );
}

