'use client';

/**
 * ImageUpload - 이미지 업로드 컴포넌트 (미리보기 포함)
 *
 * 프로필 이미지, 로고, 썸네일 등에 사용
 *
 * 사용 예시:
 * <ImageUpload
 *   value={profileImageUrl}
 *   onChange={(file) => handleUpload(file)}
 *   onRemove={() => setProfileImageUrl(null)}
 *   aspectRatio="square"
 *   maxSize={5}
 * />
 */

import { useState, useRef, useCallback, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Camera, X, Upload, AlertCircle, Image as ImageIcon } from 'lucide-react';
import { cn } from '@/lib/utils';

export interface ImageUploadProps {
  /** 현재 이미지 URL (기존 이미지 또는 미리보기) */
  value?: string | null;
  /** 이미지 선택 시 콜백 (File 객체 전달) */
  onChange: (file: File) => void;
  /** 이미지 제거 시 콜백 */
  onRemove?: () => void;
  /** 비활성화 */
  disabled?: boolean;
  /** 최대 파일 크기 (MB) */
  maxSize?: number;
  /** 허용 이미지 타입 */
  accept?: string;
  /** 가로세로 비율 */
  aspectRatio?: 'square' | 'video' | 'wide' | 'portrait';
  /** 컴포넌트 크기 */
  size?: 'sm' | 'md' | 'lg';
  /** 추가 클래스 */
  className?: string;
  /** 안내 텍스트 */
  hint?: string;
  /** 에러 상태 */
  error?: boolean;
  /** 에러 메시지 */
  errorMessage?: string;
  /** 원형 (프로필용) */
  rounded?: boolean;
}

const sizeClasses = {
  sm: 'w-24 h-24',
  md: 'w-32 h-32',
  lg: 'w-40 h-40',
};

const aspectRatioClasses = {
  square: 'aspect-square',
  video: 'aspect-video',
  wide: 'aspect-[2/1]',
  portrait: 'aspect-[3/4]',
};

export function ImageUpload({
  value,
  onChange,
  onRemove,
  disabled = false,
  maxSize = 10,
  accept = 'image/png,image/jpeg,image/gif,image/webp',
  aspectRatio = 'square',
  size = 'md',
  className,
  hint,
  error = false,
  errorMessage,
  rounded = false,
}: ImageUploadProps) {
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [validationError, setValidationError] = useState<string | null>(null);
  const [isDragging, setIsDragging] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  // 외부 value 또는 내부 preview 사용
  const displayUrl = value || previewUrl;
  const displayError = errorMessage || validationError;

  // value가 변경되면 previewUrl 초기화
  useEffect(() => {
    if (value) {
      setPreviewUrl(null);
    }
  }, [value]);

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

  const validateAndProcessFile = useCallback((file: File) => {
    // 이미지 타입 검증
    if (!file.type.startsWith('image/')) {
      setValidationError('이미지 파일만 업로드할 수 있습니다');
      return false;
    }

    // 파일 크기 검증
    const fileSizeMB = file.size / (1024 * 1024);
    if (fileSizeMB > maxSize) {
      setValidationError(`파일 크기는 ${maxSize}MB 이하여야 합니다`);
      return false;
    }

    setValidationError(null);

    // 미리보기 URL 생성
    const objectUrl = URL.createObjectURL(file);
    setPreviewUrl(objectUrl);

    onChange(file);
    return true;
  }, [maxSize, onChange]);

  const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      validateAndProcessFile(file);
    }
    // input 초기화
    if (inputRef.current) {
      inputRef.current.value = '';
    }
  }, [validateAndProcessFile]);

  const handleRemove = useCallback((e: React.MouseEvent) => {
    e.stopPropagation();
    if (previewUrl) {
      URL.revokeObjectURL(previewUrl);
    }
    setPreviewUrl(null);
    setValidationError(null);
    if (inputRef.current) {
      inputRef.current.value = '';
    }
    onRemove?.();
  }, [previewUrl, onRemove]);

  // 드래그 앤 드롭 핸들러
  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 file = e.dataTransfer.files?.[0];
    if (file) {
      validateAndProcessFile(file);
    }
  }, [disabled, validateAndProcessFile]);

  // 컴포넌트 언마운트 시 미리보기 URL 정리
  useEffect(() => {
    return () => {
      if (previewUrl) {
        URL.revokeObjectURL(previewUrl);
      }
    };
  }, [previewUrl]);

  return (
    <div className={cn('space-y-2', className)}>
      {/* 업로드 영역 */}
      <div
        onClick={handleClick}
        onDragEnter={handleDragEnter}
        onDragLeave={handleDragLeave}
        onDragOver={handleDragOver}
        onDrop={handleDrop}
        className={cn(
          'relative flex flex-col items-center justify-center overflow-hidden transition-colors',
          rounded ? 'rounded-full' : 'rounded-lg',
          sizeClasses[size],
          aspectRatio !== 'square' && !rounded && aspectRatioClasses[aspectRatio],
          // 테두리 스타일: 이미지 있고 비활성화면 테두리 없음
          disabled && displayUrl
            ? 'border-0'
            : 'border-2 border-dashed',
          // 색상 스타일
          error || displayError
            ? 'border-red-500 bg-red-50'
            : isDragging
              ? 'border-primary bg-primary/5'
              : disabled && displayUrl
                ? 'bg-transparent'
                : 'border-gray-300 bg-gray-50 hover:border-primary/50',
          // 커서 스타일
          disabled
            ? displayUrl
              ? 'cursor-default'
              : 'opacity-50 cursor-not-allowed'
            : 'cursor-pointer',
        )}
      >
        {/* 숨겨진 파일 input */}
        <input
          ref={inputRef}
          type="file"
          accept={accept}
          onChange={handleChange}
          disabled={disabled}
          className="hidden"
        />

        {displayUrl ? (
          // 이미지 미리보기
          <>
            <img
              src={displayUrl}
              alt="미리보기"
              className={cn(
                'w-full h-full object-cover',
                rounded && 'rounded-full',
              )}
            />
            {/* 호버 오버레이 */}
            {!disabled && (
              <div className={cn(
                'absolute inset-0 bg-black/50 opacity-0 hover:opacity-100 transition-opacity flex items-center justify-center gap-2',
                rounded && 'rounded-full',
              )}>
                <Button
                  type="button"
                  variant="secondary"
                  size="sm"
                  onClick={(e) => {
                    e.stopPropagation();
                    handleClick();
                  }}
                >
                  <Camera className="w-4 h-4" />
                </Button>
                <Button
                  type="button"
                  variant="destructive"
                  size="sm"
                  onClick={handleRemove}
                >
                  <X className="w-4 h-4" />
                </Button>
              </div>
            )}
          </>
        ) : (
          // 업로드 안내
          <div className="flex flex-col items-center justify-center text-center p-2">
            {isDragging ? (
              <Upload className="w-8 h-8 text-primary mb-1" />
            ) : (
              <ImageIcon className="w-8 h-8 text-gray-400 mb-1" />
            )}
            <span className="text-xs text-gray-500">
              {isDragging ? '놓으세요' : '클릭 또는 드래그'}
            </span>
          </div>
        )}
      </div>

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

      {/* 안내 텍스트 */}
      {!displayError && hint && (
        <p className="text-xs text-muted-foreground text-center">
          {hint}
        </p>
      )}
    </div>
  );
}

export default ImageUpload;
