'use client';

/**
 * FileDropzone - 드래그 앤 드롭 파일 업로드 영역
 *
 * 도면, 첨부파일 등 다중 파일 업로드에 사용
 *
 * 사용 예시:
 * <FileDropzone
 *   accept=".pdf,.dwg,.jpg"
 *   multiple
 *   maxSize={10}
 *   onFilesSelect={(files) => setFiles(prev => [...prev, ...files])}
 * />
 */

import { useState, useRef, useCallback } from 'react';
import { Upload, AlertCircle } from 'lucide-react';
import { cn } from '@/lib/utils';

export interface FileDropzoneProps {
  /** 파일 선택 시 콜백 */
  onFilesSelect: (files: File[]) => void;
  /** 허용 파일 타입 */
  accept?: string;
  /** 다중 파일 선택 허용 */
  multiple?: boolean;
  /** 최대 파일 크기 (MB) */
  maxSize?: number;
  /** 최대 파일 개수 */
  maxFiles?: number;
  /** 비활성화 */
  disabled?: boolean;
  /** 추가 클래스 */
  className?: string;
  /** 안내 텍스트 (메인) */
  title?: string;
  /** 안내 텍스트 (서브) */
  description?: string;
  /** 에러 상태 */
  error?: boolean;
  /** 에러 메시지 */
  errorMessage?: string;
  /** 컴팩트 모드 */
  compact?: boolean;
}

export function FileDropzone({
  onFilesSelect,
  accept = '*/*',
  multiple = false,
  maxSize = 10,
  maxFiles,
  disabled = false,
  className,
  title,
  description,
  error = false,
  errorMessage,
  compact = false,
}: FileDropzoneProps) {
  const [isDragging, setIsDragging] = useState(false);
  const [validationError, setValidationError] = useState<string | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const displayError = errorMessage || validationError;

  const handleClick = useCallback(() => {
    if (!disabled) {
      inputRef.current?.click();
    }
  }, [disabled]);

  const validateFiles = useCallback((files: File[]): File[] => {
    const validFiles: File[] = [];
    const errors: string[] = [];

    for (const file of files) {
      // 파일 크기 검증
      const fileSizeMB = file.size / (1024 * 1024);
      if (fileSizeMB > maxSize) {
        errors.push(`${file.name}: ${maxSize}MB 초과`);
        continue;
      }

      validFiles.push(file);
    }

    // 최대 파일 개수 검증
    if (maxFiles && validFiles.length > maxFiles) {
      setValidationError(`최대 ${maxFiles}개 파일만 선택할 수 있습니다`);
      return validFiles.slice(0, maxFiles);
    }

    if (errors.length > 0) {
      setValidationError(errors.join(', '));
    } else {
      setValidationError(null);
    }

    return validFiles;
  }, [maxSize, maxFiles]);

  const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      const fileArray = Array.from(files);
      const validFiles = validateFiles(fileArray);
      if (validFiles.length > 0) {
        onFilesSelect(validFiles);
      }
    }
    // input 초기화
    if (inputRef.current) {
      inputRef.current.value = '';
    }
  }, [validateFiles, onFilesSelect]);

  const handleDragEnter = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (!disabled) {
      setIsDragging(true);
    }
  }, [disabled]);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
  }, []);

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

    if (disabled) return;

    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
      const fileArray = multiple ? Array.from(files) : [files[0]];
      const validFiles = validateFiles(fileArray);
      if (validFiles.length > 0) {
        onFilesSelect(validFiles);
      }
    }
  }, [disabled, multiple, validateFiles, onFilesSelect]);

  // 기본 텍스트
  const defaultTitle = isDragging
    ? '파일을 여기에 놓으세요'
    : '클릭하거나 파일을 드래그하세요';
  const defaultDescription = `최대 ${maxSize}MB${accept !== '*/*' ? ` (${accept})` : ''}`;

  return (
    <div className={cn('space-y-2', className)}>
      <div
        onClick={handleClick}
        onDragEnter={handleDragEnter}
        onDragLeave={handleDragLeave}
        onDragOver={handleDragOver}
        onDrop={handleDrop}
        className={cn(
          'border-2 border-dashed rounded-lg transition-colors',
          compact ? 'p-4' : 'p-8',
          error || displayError
            ? 'border-red-500 bg-red-50'
            : isDragging
              ? 'border-primary bg-primary/5'
              : 'border-gray-300 hover:border-primary/50',
          disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer',
        )}
      >
        {/* 숨겨진 파일 input */}
        <input
          ref={inputRef}
          type="file"
          accept={accept}
          multiple={multiple}
          onChange={handleChange}
          disabled={disabled}
          className="hidden"
        />

        <div className="flex flex-col items-center justify-center text-center">
          <Upload
            className={cn(
              'mb-2 transition-colors',
              compact ? 'w-6 h-6' : 'w-10 h-10',
              isDragging ? 'text-primary' : 'text-gray-400',
            )}
          />
          <p className={cn(
            'font-medium',
            compact ? 'text-sm' : 'text-base',
            isDragging ? 'text-primary' : 'text-gray-700',
          )}>
            {title || defaultTitle}
          </p>
          <p className={cn(
            'text-muted-foreground mt-1',
            compact ? 'text-xs' : 'text-sm',
          )}>
            {description || defaultDescription}
          </p>
        </div>
      </div>

      {/* 에러 메시지 */}
      {displayError && (
        <div className="flex items-center gap-1 text-sm text-red-500">
          <AlertCircle className="w-3 h-3 shrink-0" />
          <span>{displayError}</span>
        </div>
      )}
    </div>
  );
}

export default FileDropzone;
