'use client';

import { useState, useRef, DragEvent, ChangeEvent } from 'react';
import Image from 'next/image';

export interface FileDropZoneProps {
  onFileSelect: (file: File) => void;
  accept?: string;
  maxSizeMB?: number;
  disabled?: boolean;
}

export function FileDropZone({
  onFileSelect,
  accept = 'image/jpeg,image/png,image/webp,image/gif',
  maxSizeMB = 5,
  disabled = false,
}: FileDropZoneProps) {
  const [isDragOver, setIsDragOver] = useState(false);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [error, setError] = useState<string>('');
  const fileInputRef = useRef<HTMLInputElement>(null);

  const maxSizeBytes = maxSizeMB * 1024 * 1024;

  // Validate file
  const validateFile = (file: File): string | null => {
    // Check file type
    const acceptedTypes = accept.split(',').map((t) => t.trim());
    if (!acceptedTypes.includes(file.type)) {
      return `Invalid file type. Please upload: ${acceptedTypes.join(', ')}`;
    }

    // Check file size
    if (file.size > maxSizeBytes) {
      return `File size exceeds ${maxSizeMB}MB limit (${(file.size / 1024 / 1024).toFixed(2)}MB)`;
    }

    return null;
  };

  // Handle file selection
  const handleFile = (file: File) => {
    if (disabled) return;

    setError('');
    const validationError = validateFile(file);

    if (validationError) {
      setError(validationError);
      return;
    }

    setSelectedFile(file);
    onFileSelect(file);

    // Create preview URL
    const url = URL.createObjectURL(file);
    setPreviewUrl(url);
  };

  // Handle drag events
  const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    if (!disabled) {
      setIsDragOver(true);
    }
  };

  const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDragOver(false);
  };

  const handleDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDragOver(false);

    if (disabled) return;

    const files = e.dataTransfer.files;
    if (files.length > 0) {
      handleFile(files[0]);
    }
  };

  // Handle click to browse
  const handleClick = () => {
    if (!disabled && fileInputRef.current) {
      fileInputRef.current.click();
    }
  };

  // Handle file input change
  const handleFileInputChange = (e: ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      handleFile(files[0]);
    }
  };

  // Clear selected file
  const handleClear = () => {
    setSelectedFile(null);
    setPreviewUrl(null);
    setError('');
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  // Cleanup preview URL on unmount
  useState(() => {
    return () => {
      if (previewUrl) {
        URL.revokeObjectURL(previewUrl);
      }
    };
  });

  // Format file size
  const formatFileSize = (bytes: number): string => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
  };

  return (
    <div className="w-full">
      {/* Hidden file input */}
      <input
        ref={fileInputRef}
        type="file"
        accept={accept}
        onChange={handleFileInputChange}
        className="hidden"
        disabled={disabled}
        aria-label="File upload input"
      />

      {/* Drop zone */}
      <div
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        onClick={handleClick}
        role="button"
        tabIndex={disabled ? -1 : 0}
        aria-label="Click to browse or drag and drop files"
        aria-disabled={disabled}
        onKeyDown={(e) => {
          if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            handleClick();
          }
        }}
        className={`
          relative border-2 border-dashed rounded-2xl p-8 transition-all cursor-pointer
          ${
            disabled
              ? 'opacity-50 cursor-not-allowed bg-slate-900/50 border-slate-700'
              : isDragOver
                ? 'border-amber-500 bg-amber-500/10 scale-[1.02]'
                : selectedFile
                  ? 'border-slate-600 bg-slate-800/50'
                  : 'border-slate-700 bg-slate-900/80 hover:border-amber-500/50 hover:bg-slate-800/50'
          }
          focus:outline-none focus:ring-2 focus:ring-amber-500 focus:ring-offset-2 focus:ring-offset-slate-950
        `}
      >
        {selectedFile && previewUrl ? (
          // File selected state
          <div className="flex flex-col md:flex-row items-center gap-6">
            {/* Preview thumbnail */}
            <div className="relative flex-shrink-0">
              <div className="relative w-32 h-32 rounded-lg overflow-hidden border border-slate-700 bg-slate-950">
                <Image
                  src={previewUrl}
                  alt="File preview"
                  fill
                  className="object-cover"
                  sizes="128px"
                />
              </div>
              {/* Clear button */}
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  handleClear();
                }}
                disabled={disabled}
                className="absolute -top-2 -right-2 w-7 h-7 rounded-full bg-red-600 hover:bg-red-700 text-white flex items-center justify-center transition-colors shadow-lg focus:ring-2 focus:ring-red-500 disabled:opacity-50 disabled:cursor-not-allowed"
                aria-label="Remove selected file"
              >
                <span className="text-sm font-bold">✕</span>
              </button>
            </div>

            {/* File info */}
            <div className="flex-1 min-w-0 text-center md:text-left">
              <p className="text-lg font-semibold text-white truncate mb-2">{selectedFile.name}</p>
              <div className="flex flex-wrap gap-2 justify-center md:justify-start">
                <span className="px-3 py-1 text-xs font-medium bg-slate-700/50 text-gray-300 rounded-full border border-slate-600">
                  {formatFileSize(selectedFile.size)}
                </span>
                <span className="px-3 py-1 text-xs font-medium bg-amber-600/20 text-amber-400 rounded-full border border-amber-600/30">
                  {selectedFile.type.split('/')[1].toUpperCase()}
                </span>
              </div>
              <p className="mt-3 text-sm text-gray-400">
                Click or drag to replace file
              </p>
            </div>
          </div>
        ) : (
          // Empty state
          <div className="text-center">
            {/* Upload icon */}
            <div
              className={`mx-auto w-16 h-16 mb-4 rounded-full flex items-center justify-center transition-colors ${
                isDragOver
                  ? 'bg-amber-500/20 text-amber-400'
                  : 'bg-slate-800 text-gray-400'
              }`}
            >
              <svg
                className="w-8 h-8"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                aria-hidden="true"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
                />
              </svg>
            </div>

            {/* Text */}
            <p className="text-lg font-semibold text-white mb-2">
              {isDragOver ? 'Drop your file here' : 'Upload an image'}
            </p>
            <p className="text-sm text-gray-400 mb-4">
              Drag and drop or click to browse
            </p>

            {/* Constraints */}
            <div className="flex flex-wrap gap-2 justify-center text-xs text-gray-500">
              <span className="px-2 py-1 bg-slate-800/50 rounded">
                Max {maxSizeMB}MB
              </span>
              <span className="px-2 py-1 bg-slate-800/50 rounded">
                JPEG, PNG, WEBP, GIF
              </span>
            </div>
          </div>
        )}
      </div>

      {/* Error message */}
      {error && (
        <div
          className="mt-3 p-3 bg-red-900/20 border border-red-700 rounded-lg flex items-start gap-2 animate-fade-in"
          role="alert"
        >
          <span className="text-red-400 text-lg flex-shrink-0">⚠️</span>
          <p className="text-sm text-red-400 flex-1">{error}</p>
        </div>
      )}
    </div>
  );
}
