"use client";

import React, { FC, useState } from "react";
import { useToast } from "@/hooks/use-toast";
import { toast as toastMessage } from "sonner";
import prettyBytes from "pretty-bytes";
import { X, Loader2 } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { DialogFooter } from "@/components/ui/dialog";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import {
  Dropzone,
  DropzoneDescription,
  DropzoneInput,
  DropzoneTitle,
  DropzoneUploadIcon,
  DropzoneZone,
} from "@/components/ui/dropzone";
import {
  FileList,
  FileListAction,
  FileListDescription,
  FileListHeader,
  FileListIcon,
  FileListInfo,
  FileListItem,
  FileListName,
} from "@/components/ui/file-list";
import { uploadReportTemp } from "@/lib/forms/services";

// 최대 파일 크기 설정 (3000MB)
const MAX_FILE_SIZE = 3000000;

interface FormDataReportTempUploadTabProps {
  packageId: number;
  formId: number;
  uploaderType: string;
}

export const FormDataReportTempUploadTab: FC<
  FormDataReportTempUploadTabProps
> = ({ packageId, formId, uploaderType }) => {
  const { toast } = useToast();
  const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
  const [isUploading, setIsUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);

  // 드롭존 - 파일 드랍 처리
  const handleDropAccepted = (acceptedFiles: File[]) => {
    const newFiles = [...selectedFiles, ...acceptedFiles];
    setSelectedFiles(newFiles);
  };

  // 드롭존 - 파일 거부(에러) 처리
  const handleDropRejected = (fileRejections: any[]) => {
    fileRejections.forEach((rejection) => {
      toast({
        variant: "destructive",
        title: "File Error",
        description: `${rejection.file.name}: ${
          rejection.errors[0]?.message || "Upload failed"
        }`,
      });
    });
  };

  // 파일 제거 핸들러
  const removeFile = (index: number) => {
    const updatedFiles = [...selectedFiles];
    updatedFiles.splice(index, 1);
    setSelectedFiles(updatedFiles);
  };

  const submitData = async () => {
    setIsUploading(true);
    setUploadProgress(0);
    try {
      const totalFiles = selectedFiles.length;
      let successCount = 0;

      for (let i = 0; i < totalFiles; i++) {
        const file = selectedFiles[i];

        const formData = new FormData();
        formData.append("file", file);
        formData.append("customFileName", file.name);
        formData.append("uploaderType", uploaderType);

        await uploadReportTemp(packageId, formId, formData);

        successCount++;
        setUploadProgress(Math.round((successCount / totalFiles) * 100));
      }
      toastMessage.success("Template File 업로드 완료!");
    } catch (err) {
      console.error(err);
      toast({
        title: "Error",
        description: "파일 업로드 중 오류가 발생했습니다.",
        variant: "destructive",
      });
    } finally {
      setIsUploading(false);
      setUploadProgress(0);
      setSelectedFiles([])
    }
  };

  return (
    <div className='flex flex-col gap-4'>
      <div>
        <Label>Vendor Document Template File Upload(.docx)</Label>
        <Dropzone
          maxSize={MAX_FILE_SIZE}
          multiple={true}
          accept={{ accept: [".docx"] }}
          onDropAccepted={handleDropAccepted}
          onDropRejected={handleDropRejected}
          disabled={isUploading}
        >
          {({ maxSize }) => (
            <>
              <DropzoneZone className="flex justify-center">
                <DropzoneInput />
                <div className="flex items-center gap-6">
                  <DropzoneUploadIcon />
                  <div className="grid gap-0.5">
                    <DropzoneTitle>파일을 여기에 드롭하세요</DropzoneTitle>
                    <DropzoneDescription>
                      또는 클릭하여 파일을 선택하세요. 최대 크기:{" "}
                      {maxSize ? prettyBytes(maxSize) : "무제한"}
                    </DropzoneDescription>
                  </div>
                </div>
              </DropzoneZone>
              <Label className="text-xs text-muted-foreground">
                여러 파일을 선택할 수 있습니다.
              </Label>
            </>
          )}
        </Dropzone>
      </div>

      {selectedFiles.length > 0 && (
        <div className="grid gap-2">
          <div className="flex items-center justify-between">
            <h6 className="text-sm font-semibold">
              선택된 파일 ({selectedFiles.length})
            </h6>
            <Badge variant="secondary">{selectedFiles.length}개 파일</Badge>
          </div>
          <ScrollArea>
            <UploadFileItem
              selectedFiles={selectedFiles}
              removeFile={removeFile}
              isUploading={isUploading}
            />
          </ScrollArea>
        </div>
      )}

      {isUploading && <UploadProgressBox uploadProgress={uploadProgress} />}
      <DialogFooter>
        <Button disabled={selectedFiles.length === 0} onClick={submitData}>
          업로드
        </Button>
      </DialogFooter>
    </div>
  );
};

interface UploadFileItemProps {
  selectedFiles: File[];
  removeFile: (index: number) => void;
  isUploading: boolean;
}

const UploadFileItem: FC<UploadFileItemProps> = ({
  selectedFiles,
  removeFile,
  isUploading,
}) => {
  return (
    <FileList className="max-h-[150px] gap-3">
      {selectedFiles.map((file, index) => (
        <FileListItem key={index} className="p-3">
          <FileListHeader>
            <FileListIcon />
            <FileListInfo>
              <FileListName>{file.name}</FileListName>
              <FileListDescription>
                {prettyBytes(file.size)}
              </FileListDescription>
            </FileListInfo>
            <FileListAction
              onClick={() => removeFile(index)}
              disabled={isUploading}
            >
              <X className="h-4 w-4" />
              <span className="sr-only">Remove</span>
            </FileListAction>
          </FileListHeader>
        </FileListItem>
      ))}
    </FileList>
  );
};

const UploadProgressBox: FC<{ uploadProgress: number }> = ({
  uploadProgress,
}) => {
  return (
    <div className="flex flex-col gap-1 mt-2">
      <div className="flex items-center gap-2">
        <Loader2 className="h-4 w-4 animate-spin" />
        <span className="text-sm">{uploadProgress}% 업로드 중...</span>
      </div>
      <div className="h-2 w-full bg-muted rounded-full overflow-hidden">
        <div
          className="h-full bg-primary rounded-full transition-all"
          style={{ width: `${uploadProgress}%` }}
        />
      </div>
    </div>
  );
};