import { useRef, useState, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Upload, FileImage, FileVideo, AlertCircle, Sparkles } from 'lucide-react';
import CameraCapture from './CameraCapture';
import styles from './UploadZone.module.css';

const MAX_SIZE_MB = 200;
const ACCEPTED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'image/tiff', 'image/avif'];
const ACCEPTED_VIDEO_TYPES = ['video/mp4', 'video/webm', 'video/quicktime', 'video/x-msvideo', 'video/avi'];

export default function UploadZone({ onFileSelect, error }) {
  const inputRef = useRef(null);
  const [isDragging, setIsDragging] = useState(false);
  const [dragType, setDragType] = useState(null);
  const [validationError, setValidationError] = useState(null);

  const validateFile = useCallback((file) => {
    if (!file) return 'No file selected';
    const isImage = ACCEPTED_IMAGE_TYPES.includes(file.type) || file.type.startsWith('image/');
    const isVideo = ACCEPTED_VIDEO_TYPES.includes(file.type) || file.type.startsWith('video/');
    if (!isImage && !isVideo) return 'Unsupported file format. Please use an image or video file.';
    if (file.size > MAX_SIZE_MB * 1024 * 1024) return `File is too large. Maximum size is ${MAX_SIZE_MB} MB.`;
    return null;
  }, []);

  const handleDragOver = useCallback((event) => {
    event.preventDefault();
    const file = event.dataTransfer?.items?.[0];
    if (!file) return;
    setIsDragging(true);
    if (file.type.startsWith('image/')) setDragType('image');
    else if (file.type.startsWith('video/')) setDragType('video');
    else setDragType('invalid');
  }, []);

  const handleDragLeave = useCallback((event) => {
    event.preventDefault();
    setIsDragging(false);
    setDragType(null);
  }, []);

  const handleDrop = useCallback((event) => {
    event.preventDefault();
    setIsDragging(false);
    setDragType(null);
    const file = event.dataTransfer?.files?.[0];
    if (!file) return;
    const validation = validateFile(file);
    if (validation) {
      setValidationError(validation);
      return;
    }
    setValidationError(null);
    onFileSelect(file);
  }, [validateFile, onFileSelect]);

  const handleInputChange = useCallback((event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    const validation = validateFile(file);
    if (validation) {
      setValidationError(validation);
      return;
    }
    setValidationError(null);
    onFileSelect(file);
  }, [validateFile, onFileSelect]);

  const handleClick = () => {
    setValidationError(null);
    inputRef.current?.click();
  };

  return (
    <div className={styles.wrapper}>
      <motion.div
        className={styles.hero}
        initial={{ opacity: 0, y: 20 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.5 }}
      >
        <div className={styles.heroBadge}>
          <Sparkles size={13} />
          <span>Forensic-Grade AI Detection · Explainable Results</span>
        </div>
        <h1 className={styles.heroTitle}>
          Is this media <span className={styles.heroAccent}>AI-generated?</span>
        </h1>
        <p className={styles.heroSub}>
          Upload an image or video for multi-model forensic analysis. UAIDE detects deepfakes,
          GAN artifacts, and AI-generated content using Grad-CAM heatmaps and frequency analysis.
        </p>
      </motion.div>

      <motion.div
        className={`${styles.dropzone} ${isDragging ? styles.dragging : ''} ${dragType === 'invalid' ? styles.invalid : ''}`}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        onClick={handleClick}
        role="button"
        tabIndex={0}
        aria-label="Upload media file for analysis"
        onKeyDown={(event) => event.key === 'Enter' || event.key === ' ' ? handleClick() : null}
        initial={{ opacity: 0, scale: 0.97 }}
        animate={{ opacity: 1, scale: 1 }}
        transition={{ duration: 0.4, delay: 0.15 }}
        whileHover={{ scale: 1.005 }}
      >
        <input
          ref={inputRef}
          type="file"
          accept="image/*,video/*"
          onChange={handleInputChange}
          className={styles.hiddenInput}
          aria-hidden="true"
        />

        <AnimatePresence mode="wait">
          {isDragging ? (
            <motion.div
              key="dragging"
              className={styles.dropContent}
              initial={{ opacity: 0, scale: 0.9 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.9 }}
              transition={{ duration: 0.15 }}
            >
              {dragType === 'invalid' ? (
                <>
                  <div className={`${styles.iconRing} ${styles.iconRingError}`}>
                    <AlertCircle size={32} />
                  </div>
                  <p className={styles.dropLabel} style={{ color: 'var(--ai-generated)' }}>Unsupported format</p>
                  <p className={styles.dropHint}>Drop images or video files only</p>
                </>
              ) : (
                <>
                  <div className={`${styles.iconRing} ${styles.iconRingActive}`}>
                    {dragType === 'video' ? <FileVideo size={32} /> : <FileImage size={32} />}
                  </div>
                  <p className={styles.dropLabel}>Release to analyse</p>
                  <p className={styles.dropHint}>{dragType === 'video' ? 'Video file detected' : 'Image file detected'}</p>
                </>
              )}
            </motion.div>
          ) : (
            <motion.div key="idle" className={styles.dropContent} initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
              <div className={styles.iconGroup}>
                <div className={styles.iconRing}>
                  <Upload size={28} />
                </div>
              </div>
              <p className={styles.dropLabel}>Drag & drop your media here</p>
              <p className={styles.dropHint}>or <span className={styles.browseLink}>browse files</span></p>
              <div className={styles.supportedTypes}>
                <div className={styles.typeChip}>
                  <FileImage size={12} />
                  <span>Images</span>
                  <span className={styles.typeFormats}>JPEG · PNG · WebP · GIF · TIFF · AVIF</span>
                </div>
                <div className={styles.typeDivider} />
                <div className={styles.typeChip}>
                  <FileVideo size={12} />
                  <span>Videos</span>
                  <span className={styles.typeFormats}>MP4 · WebM · MOV · AVI</span>
                </div>
              </div>
              <p className={styles.sizeNote}>Max file size: {MAX_SIZE_MB} MB</p>
            </motion.div>
          )}
        </AnimatePresence>
      </motion.div>

      <CameraCapture onCapture={onFileSelect} />

      <AnimatePresence>
        {(validationError || error) && (
          <motion.div className={styles.errorBanner} initial={{ opacity: 0, y: -8 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0 }}>
            <AlertCircle size={15} />
            <span>{validationError || error}</span>
          </motion.div>
        )}
      </AnimatePresence>

      <motion.div className={styles.capabilities} initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.35 }}>
        {['GAN Detection', 'Diffusion Model ID', 'Grad-CAM Heatmap', 'FFT Analysis', 'Temporal Analysis', 'Deepfake Detection', 'Live Capture'].map((cap) => (
          <span key={cap} className={styles.capPill}>{cap}</span>
        ))}
      </motion.div>
    </div>
  );
}
