"use client";

import React, { useCallback, useState } from "react";
import { useDropzone } from "react-dropzone";
import {
  CloudArrowUpIcon,
  CheckCircleIcon,
  ExclamationTriangleIcon,
  XMarkIcon,
} from "@heroicons/react/24/outline";

interface UploadFile {
  id: string;
  file: File;
  progress: number;
  status: "uploading" | "completed" | "error";
  error?: string;
  result?: {
    id: string;
    url: string;
    fileName: string;
  };
}

interface MediaUploadZoneProps {
  onUploadComplete?: (files: UploadFile[]) => void;
  maxFiles?: number;
  maxFileSize?: number;
  acceptedFileTypes?: string[];
  className?: string;
}

export function MediaUploadZone({
  onUploadComplete,
  maxFiles = 10,
  maxFileSize = 50 * 1024 * 1024, // 50MB
  acceptedFileTypes = ["image/*", "video/*", "audio/*"],
  className = "",
}: MediaUploadZoneProps) {
  const [uploadFiles, setUploadFiles] = useState<UploadFile[]>([]);
  const [isUploading, setIsUploading] = useState(false);

  const uploadFile = async (file: File): Promise<UploadFile> => {
    const uploadFile: UploadFile = {
      id: Math.random().toString(36).substring(2),
      file,
      progress: 0,
      status: "uploading",
    };

    try {
      const formData = new FormData();
      formData.append("file", file);

      const response = await fetch("/api/media/upload", {
        method: "POST",
        body: formData,
      });

      if (!response.ok) {
        throw new Error("업로드 실패");
      }

      const result = await response.json();

      return {
        ...uploadFile,
        progress: 100,
        status: "completed",
        result: result.data,
      };
    } catch (error) {
      return {
        ...uploadFile,
        status: "error",
        error: error instanceof Error ? error.message : "업로드 실패",
      };
    }
  };

  const onDrop = useCallback(
    async (acceptedFiles: File[]) => {
      if (acceptedFiles.length === 0) return;

      setIsUploading(true);
      const newUploadFiles: UploadFile[] = acceptedFiles.map((file) => ({
        id: Math.random().toString(36).substring(2),
        file,
        progress: 0,
        status: "uploading" as const,
      }));

      setUploadFiles((prev) => [...prev, ...newUploadFiles]);

      // 파일들을 병렬로 업로드
      const uploadPromises = acceptedFiles.map(uploadFile);
      const results = await Promise.all(uploadPromises);

      setUploadFiles((prev) =>
        prev.map((prevFile) => {
          const result = results.find(
            (r) => r.file.name === prevFile.file.name
          );
          return result || prevFile;
        })
      );

      setIsUploading(false);
      onUploadComplete?.(results);
    },
    [onUploadComplete]
  );

  const { getRootProps, getInputProps, isDragActive, fileRejections } =
    useDropzone({
      onDrop,
      accept: acceptedFileTypes.reduce((acc, type) => {
        acc[type] = [];
        return acc;
      }, {} as Record<string, string[]>),
      maxFiles,
      maxSize: maxFileSize,
      disabled: isUploading,
    });

  const removeFile = (id: string) => {
    setUploadFiles((prev) => prev.filter((file) => file.id !== id));
  };

  const getStatusIcon = (status: UploadFile["status"]) => {
    switch (status) {
      case "completed":
        return <CheckCircleIcon className="h-5 w-5 text-green-500" />;
      case "error":
        return <ExclamationTriangleIcon className="h-5 w-5 text-red-500" />;
      default:
        return (
          <div className="h-5 w-5 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
        );
    }
  };

  return (
    <div className={`space-y-4 ${className}`}>
      {/* 드롭존 */}
      <div
        {...getRootProps()}
        className={`
          border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors
          ${
            isDragActive
              ? "border-blue-500 bg-blue-50"
              : "border-gray-300 hover:border-gray-400"
          }
          ${isUploading ? "opacity-50 cursor-not-allowed" : ""}
        `}
      >
        <input {...getInputProps()} />
        <CloudArrowUpIcon className="mx-auto h-12 w-12 text-gray-400" />
        <p className="mt-2 text-sm text-gray-600">
          {isDragActive
            ? "파일을 놓아주세요"
            : "파일을 끌어다 놓거나 클릭하여 선택하세요"}
        </p>
        <p className="text-xs text-gray-500 mt-1">
          최대 {maxFiles}개 파일, 파일당 최대{" "}
          {Math.round(maxFileSize / 1024 / 1024)}MB
        </p>
      </div>

      {/* 파일 거부 에러 */}
      {fileRejections.length > 0 && (
        <div className="bg-red-50 border border-red-200 rounded-md p-3">
          <div className="flex">
            <ExclamationTriangleIcon className="h-5 w-5 text-red-400" />
            <div className="ml-3">
              <h3 className="text-sm font-medium text-red-800">
                업로드할 수 없는 파일이 있습니다
              </h3>
              <div className="mt-2 text-sm text-red-700">
                <ul className="list-disc space-y-1 pl-5">
                  {fileRejections.map(({ file, errors }) => (
                    <li key={file.name}>
                      {file.name}: {errors.map((e) => e.message).join(", ")}
                    </li>
                  ))}
                </ul>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* 업로드 파일 목록 */}
      {uploadFiles.length > 0 && (
        <div className="space-y-2">
          <h4 className="text-sm font-medium text-gray-900">업로드 파일</h4>
          {uploadFiles.map((uploadFile) => (
            <div
              key={uploadFile.id}
              className="flex items-center justify-between p-3 bg-gray-50 rounded-md"
            >
              <div className="flex items-center space-x-3">
                {getStatusIcon(uploadFile.status)}
                <div>
                  <p className="text-sm font-medium text-gray-900">
                    {uploadFile.file.name}
                  </p>
                  <p className="text-xs text-gray-500">
                    {Math.round(uploadFile.file.size / 1024)} KB
                  </p>
                </div>
              </div>
              <div className="flex items-center space-x-2">
                {uploadFile.status === "uploading" && (
                  <div className="w-20 bg-gray-200 rounded-full h-2">
                    <div
                      className="bg-blue-600 h-2 rounded-full transition-all duration-300"
                      style={{ width: `${uploadFile.progress}%` }}
                    />
                  </div>
                )}
                {uploadFile.status === "error" && (
                  <span className="text-xs text-red-600">
                    {uploadFile.error}
                  </span>
                )}
                <button
                  onClick={() => removeFile(uploadFile.id)}
                  className="text-gray-400 hover:text-gray-600"
                >
                  <XMarkIcon className="h-4 w-4" />
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
