import { useState, useRef, useCallback } from 'react';
import type { DetectionResult } from '@core/types.js';
import { autoDetectMultiFrame, type AutoDetectResult } from '@core/detector.js';
import { extractFrames, rgbaToY } from '../lib/video-io.js';
import ResultCard from './ResultCard.js';

export default function DetectPanel() {
  const [videoUrl, setVideoUrl] = useState<string | null>(null);
  const [videoName, setVideoName] = useState('');
  const [key, setKey] = useState('');
  const [maxFrames, setMaxFrames] = useState(10);
  const [cropResilient, setCropResilient] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [progress, setProgress] = useState({ phase: '', current: 0, total: 0 });
  const [result, setResult] = useState<AutoDetectResult | null>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  const handleFile = useCallback((file: File) => {
    const url = URL.createObjectURL(file);
    setVideoUrl(url);
    setVideoName(file.name);
    setResult(null);
  }, []);

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      const file = e.dataTransfer.files[0];
      if (file?.type.startsWith('video/')) handleFile(file);
    },
    [handleFile]
  );

  const handleDetect = async () => {
    if (!videoUrl || !key) return;
    setProcessing(true);
    setResult(null);

    try {
      setProgress({ phase: 'Extracting frames', current: 0, total: 0 });
      const { frames, width, height } = await extractFrames(videoUrl, maxFrames, (c, t) =>
        setProgress({ phase: 'Extracting frames', current: c, total: t })
      );

      setProgress({ phase: 'Converting frames', current: 0, total: frames.length });
      const yPlanes = frames.map((frame, i) => {
        setProgress({ phase: 'Converting frames', current: i + 1, total: frames.length });
        return rgbaToY(frame);
      });

      setProgress({ phase: 'Trying all presets', current: 0, total: 0 });
      const detection = autoDetectMultiFrame(yPlanes, width, height, key, { cropResilient });

      setResult(detection);
    } catch (e) {
      console.error('Detection error:', e);
      alert(`Error: ${e}`);
    } finally {
      setProcessing(false);
    }
  };

  return (
    <div className="space-y-8">
      {/* Upload area */}
      <div
        onDrop={handleDrop}
        onDragOver={(e) => e.preventDefault()}
        onClick={() => fileRef.current?.click()}
        className={`group cursor-pointer rounded-xl border-2 border-dashed p-10 text-center transition-colors
          ${videoUrl
            ? 'border-zinc-700 bg-zinc-900/30'
            : 'border-zinc-800 bg-zinc-900/20 hover:border-zinc-600 hover:bg-zinc-900/40'
          }`}
      >
        <input
          ref={fileRef}
          type="file"
          accept="video/*"
          className="hidden"
          onChange={(e) => {
            const file = e.target.files?.[0];
            if (file) handleFile(file);
          }}
        />
        {videoUrl ? (
          <div className="space-y-2">
            <p className="text-sm font-medium text-zinc-300">{videoName}</p>
            <p className="text-xs text-zinc-500">Click or drop to replace</p>
          </div>
        ) : (
          <div className="space-y-2">
            <svg className="mx-auto h-8 w-8 text-zinc-600 transition-colors group-hover:text-zinc-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
            </svg>
            <p className="text-sm text-zinc-400">Drop a video file to analyze</p>
            <p className="text-xs text-zinc-600">Upload a potentially watermarked video</p>
          </div>
        )}
      </div>

      {/* Configuration — just key and frame count */}
      <div className="grid gap-6 sm:grid-cols-2">
        <div className="space-y-1.5">
          <label className="text-sm font-medium text-zinc-300">Secret Key</label>
          <input
            type="text"
            value={key}
            onChange={(e) => setKey(e.target.value)}
            placeholder="Enter the secret key used for embedding..."
            className="w-full rounded-lg border border-zinc-800 bg-zinc-900/50 px-3 py-2 text-sm text-zinc-100
              placeholder:text-zinc-600 focus:border-blue-600 focus:outline-none focus:ring-1 focus:ring-blue-600"
          />
        </div>

        <div className="space-y-1.5">
          <label className="text-sm font-medium text-zinc-300">Frames to analyze</label>
          <input
            type="number"
            value={maxFrames}
            onChange={(e) => setMaxFrames(Math.max(1, Math.min(100, parseInt(e.target.value) || 10)))}
            min={1}
            max={100}
            className="w-full rounded-lg border border-zinc-800 bg-zinc-900/50 px-3 py-2 text-sm text-zinc-100
              focus:border-blue-600 focus:outline-none focus:ring-1 focus:ring-blue-600"
          />
          <p className="text-[10px] text-zinc-600">More frames = better detection, slower processing</p>
        </div>
      </div>

      <div className="flex items-center gap-3">
        <label className="relative inline-flex cursor-pointer items-center">
          <input
            type="checkbox"
            checked={cropResilient}
            onChange={(e) => setCropResilient(e.target.checked)}
            className="peer sr-only"
          />
          <div className="h-5 w-9 rounded-full bg-zinc-700 after:absolute after:left-[2px] after:top-[2px] after:h-4 after:w-4 after:rounded-full after:bg-zinc-400 after:transition-all peer-checked:bg-violet-600 peer-checked:after:translate-x-full peer-checked:after:bg-white" />
        </label>
        <div>
          <span className="text-sm text-zinc-300">Crop-resilient detection</span>
          <p className="text-[10px] text-zinc-600">Slower — brute-forces DWT alignment for cropped videos</p>
        </div>
      </div>

      <p className="text-xs text-zinc-500">
        All presets will be tried automatically. No need to know which preset was used during embedding.
      </p>

      {/* Detect button */}
      <button
        onClick={handleDetect}
        disabled={!videoUrl || !key || processing}
        className="w-full rounded-lg bg-violet-600 px-4 py-2.5 text-sm font-medium text-white
          transition-colors hover:bg-violet-500 disabled:cursor-not-allowed disabled:bg-zinc-800 disabled:text-zinc-500"
      >
        {processing ? (
          <span className="flex items-center justify-center gap-2">
            <span className="h-4 w-4 animate-spin rounded-full border-2 border-zinc-400 border-t-white" />
            {progress.phase} {progress.total > 0 ? `${progress.current}/${progress.total}` : ''}
          </span>
        ) : (
          'Detect Watermark'
        )}
      </button>

      {/* Results */}
      <ResultCard result={result} presetUsed={result?.presetUsed ?? null} loading={processing} />
    </div>
  );
}
