/**
 * UploadZone — Drag-and-drop zone with click-to-browse, camera capture,
 * and full mobile responsiveness.
 *
 * On mobile/tablet the component shows three distinct action buttons:
 *   1. Browse Files  — standard file-picker (all images in gallery)
 *   2. Take Photo    — opens camera directly via `capture="environment"`
 *   3. (desktop)     — full drag-and-drop surface as usual
 *
 * Expected input: 4 required orthographic views (Front, Back, Left, Right)
 * plus up to 2 optional views (Top, Bottom).
 */
import { useCallback, useRef, useState } from 'react';
import { motion } from 'framer-motion';

interface UploadZoneProps {
  onFilesSelected: (files: File[]) => void;
  disabled?: boolean;
  fileCount: number;
}

const MAX_FILES = 6;
const ACCEPTED = 'image/jpeg,image/png';

/** Detect a coarse-grained touch/mobile environment */
function isMobileDevice(): boolean {
  return typeof window !== 'undefined' && window.matchMedia('(pointer: coarse)').matches;
}

export default function UploadZone({ onFilesSelected, disabled, fileCount }: UploadZoneProps) {
  const [isDragging, setIsDragging] = useState(false);
  const browseRef = useRef<HTMLInputElement>(null);
  const cameraRef = useRef<HTMLInputElement>(null);

  const isFull = fileCount >= MAX_FILES;
  const isBlocked = disabled || isFull;

  /* ── file helpers ── */
  const filterAndEmit = useCallback(
    (rawFiles: FileList | null) => {
      if (!rawFiles || isBlocked) return;
      const valid = Array.from(rawFiles).filter(
        (f) => f.type === 'image/jpeg' || f.type === 'image/png',
      );
      if (valid.length > 0) onFilesSelected(valid);
    },
    [isBlocked, onFilesSelected],
  );

  /* ── drag-and-drop handlers ── */
  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      setIsDragging(false);
      filterAndEmit(e.dataTransfer.files);
    },
    [filterAndEmit],
  );

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    if (!isBlocked) setIsDragging(true);
  };

  const handleDragLeave = () => setIsDragging(false);

  /* ── click handlers ── */
  const openBrowse = () => {
    if (!isBlocked) browseRef.current?.click();
  };

  const openCamera = () => {
    if (!isBlocked) cameraRef.current?.click();
  };

  const onBrowseChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    filterAndEmit(e.target.files);
    e.target.value = '';
  };

  const onCameraChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    filterAndEmit(e.target.files);
    e.target.value = '';
  };

  /* ── derived UI state ── */
  const mobile = isMobileDevice();

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      className="relative"
    >
      {/* Hidden file inputs */}
      <input
        ref={browseRef}
        type="file"
        multiple
        accept={ACCEPTED}
        onChange={onBrowseChange}
        className="hidden"
        aria-hidden="true"
      />
      {/* Camera input — capture="environment" opens rear camera on mobile */}
      <input
        ref={cameraRef}
        type="file"
        multiple
        accept={ACCEPTED}
        capture="environment"
        onChange={onCameraChange}
        className="hidden"
        aria-hidden="true"
      />

      {/* ── Main drop surface (desktop-first) ── */}
      <div
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        className={`
          border-2 border-dashed rounded-2xl p-6 sm:p-10 text-center
          transition-all duration-300 ease-out select-none
          ${isBlocked
            ? 'border-white/10 opacity-50 cursor-not-allowed'
            : isDragging
              ? 'border-cyan-400 bg-cyan-400/10 shadow-[0_0_40px_rgba(34,211,238,0.25)] scale-[1.015]'
              : 'border-white/20 hover:border-indigo-400 hover:bg-indigo-400/5'
          }
        `}
      >
        <div className="flex flex-col items-center gap-5">
          {/* Icon */}
          <div
            className={`p-4 rounded-full bg-white/5 transition-all duration-300
              ${isDragging ? 'animate-pulse scale-110' : ''}`}
          >
            <svg
              className={`w-10 h-10 sm:w-12 sm:h-12 transition-colors duration-300
                ${isDragging ? 'text-cyan-400' : 'text-white/40'}`}
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
              aria-hidden="true"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={1.5}
                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>

          {/* Primary label */}
          <div>
            <p className="text-base sm:text-lg font-semibold text-white/90">
              {isFull
                ? 'Maximum images reached'
                : isDragging
                  ? 'Drop images here!'
                  : mobile
                    ? 'Add photos of your object'
                    : 'Drag & drop images here'}
            </p>
            {!isBlocked && (
              <p className="text-xs sm:text-sm text-white/50 mt-1">
                {fileCount === 0
                  ? 'Need Front, Back, Left, Right views (4 required, up to 6 total)'
                  : `${fileCount} / ${MAX_FILES} images added — need ${Math.max(0, 4 - fileCount)} more required views`}
              </p>
            )}
          </div>

          {/* Format badges */}
          <div className="flex gap-2 flex-wrap justify-center">
            {['JPG', 'PNG', 'Max 10 MB each'].map((label) => (
              <span
                key={label}
                className="px-3 py-1 text-xs rounded-full bg-white/10 text-white/60"
              >
                {label}
              </span>
            ))}
          </div>

          {/* ── Action buttons ── */}
          {!isBlocked && (
            <div className="flex flex-col sm:flex-row gap-3 w-full max-w-sm mt-1">
              {/* Browse files */}
              <button
                type="button"
                onClick={openBrowse}
                className="flex-1 flex items-center justify-center gap-2
                  px-5 py-3 rounded-xl font-medium text-sm
                  bg-indigo-500/20 hover:bg-indigo-500/35 border border-indigo-500/40
                  text-indigo-300 hover:text-indigo-200
                  transition-all duration-200 active:scale-95"
                aria-label="Browse image files"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
                    d="M3 7h18M3 12h18M3 17h18" />
                </svg>
                Browse Files
              </button>

              {/* Take photo — prominent on mobile */}
              <button
                type="button"
                onClick={openCamera}
                className="flex-1 flex items-center justify-center gap-2
                  px-5 py-3 rounded-xl font-medium text-sm
                  bg-cyan-500/20 hover:bg-cyan-500/35 border border-cyan-500/40
                  text-cyan-300 hover:text-cyan-200
                  transition-all duration-200 active:scale-95"
                aria-label="Open camera to take a photo"
              >
                {/* Camera icon */}
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
                    d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
                    d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
                </svg>
                Take Photo
              </button>
            </div>
          )}
        </div>
      </div>

      {/* Mobile tip */}
      {!isBlocked && mobile && fileCount === 0 && (
        <motion.p
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ delay: 0.5 }}
          className="text-center text-xs text-white/35 mt-3 px-4"
        >
          Tip: Capture orthographic views in order - Front, Back, Left, Right.
        </motion.p>
      )}
    </motion.div>
  );
}
