import { useRef, useState, DragEvent, ChangeEvent, useEffect } from 'react';
import { validateFile, validateImageDimensions } from '../lib/imageProcessor';

interface Props {
  onFileSelect: (file: File) => void;
  onError: (msg: string) => void;
  onWarning: (msg: string) => void;
  currentFile: File | null;
}

export default function UploadPanel({ onFileSelect, onError, onWarning, currentFile }: Props) {
  const [dragging, setDragging] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  const handleFile = async (file: File) => {
    const typeResult = validateFile(file);
    if (!typeResult.ok) { onError(typeResult.error!); return; }

    const dimResult = await validateImageDimensions(file);
    if (!dimResult.ok) { onError(dimResult.error!); return; }
    if (dimResult.warning) onWarning(dimResult.warning);

    onFileSelect(file);
  };

  const onInputChange = (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) handleFile(file);
  };

  const onDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setDragging(false);
    const file = e.dataTransfer.files[0];
    if (file) handleFile(file);
  };

  const onDragOver = (e: DragEvent<HTMLDivElement>) => { e.preventDefault(); setDragging(true); };
  const onDragLeave = () => setDragging(false);

  // Clipboard paste listener
  useEffect(() => {
    const handler = (e: ClipboardEvent) => {
      const item = Array.from(e.clipboardData?.items ?? []).find(
        (i) => i.kind === 'file' && i.type.startsWith('image/'),
      );
      if (item) {
        const file = item.getAsFile();
        if (file) handleFile(file);
      }
    };
    window.addEventListener('paste', handler);
    return () => window.removeEventListener('paste', handler);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div className="panel">
      <div className="panel-header">
        <div className="panel-header-icon">
          <UploadIcon />
        </div>
        <span className="panel-title">Image Input</span>
      </div>
      <div className="panel-body">
        <div
          className={`upload-zone ${dragging ? 'drag-over' : ''}`}
          onDrop={onDrop}
          onDragOver={onDragOver}
          onDragLeave={onDragLeave}
          onClick={() => inputRef.current?.click()}
          role="button"
          tabIndex={0}
          aria-label="Upload image"
          onKeyDown={(e) => e.key === 'Enter' && inputRef.current?.click()}
        >
          <input
            ref={inputRef}
            type="file"
            accept=".png,.jpg,.jpeg,.webp,image/png,image/jpeg,image/webp"
            onChange={onInputChange}
            onClick={(e) => e.stopPropagation()}
            id="image-file-input"
            style={{ position: 'absolute', inset: 0, opacity: 0, cursor: 'pointer' }}
          />
          <div className="upload-zone-icon">
            <UploadIcon size={22} />
          </div>
          <div className="upload-zone-text">
            <strong>Drop image here</strong>
            <span>or click to browse · PNG, JPG, WebP</span>
          </div>
          {currentFile && (
            <div className="upload-filename">
              <CheckIcon size={12} />
              {currentFile.name}
            </div>
          )}
        </div>
        <div style={{ fontSize: '0.72rem', color: 'var(--text-muted)', textAlign: 'center' }}>
          Tip: you can also paste an image with <kbd style={{ background: 'rgba(255,255,255,0.08)', padding: '1px 5px', borderRadius: 3, fontSize: '0.7rem' }}>Ctrl+V</kbd>
        </div>
      </div>
    </div>
  );
}

// ── Icons ───────────────────────────────────────────────────────────────────

function UploadIcon({ size = 16 }: { size?: number }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="16 16 12 12 8 16" />
      <line x1="12" y1="12" x2="12" y2="21" />
      <path d="M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" />
    </svg>
  );
}

function CheckIcon({ size = 14 }: { size?: number }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="20 6 9 17 4 12" />
    </svg>
  );
}
