import { useRef, useState } from "react"
import { ChevronDown, Play, RotateCcw, Upload, Loader2, Clapperboard } from "lucide-react"
import { useDashboard } from "@/lib/dashboard"
import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Slider } from "@/components/ui/slider"
import { Separator } from "@/components/ui/separator"
import { cn } from "@/lib/utils"

const DETECTOR_MODELS = [
  { label: "Nano", value: "yoloe-26n-seg.pt" },
  { label: "Small", value: "yoloe-26s-seg.pt" },
  { label: "Medium", value: "yoloe-26m-seg.pt" },
  { label: "Large", value: "yoloe-26l-seg.pt" },
  { label: "XLarge", value: "yoloe-26x-seg.pt" },
]

const IMAGE_SIZES = [320, 640, 960, 1280]

function SliderRow({
  label,
  value,
  display,
  min,
  max,
  step,
  onChange,
}: {
  label: string
  value: number
  display: string
  min: number
  max: number
  step: number
  onChange: (v: number) => void
}) {
  return (
    <div className="space-y-2">
      <div className="flex items-baseline justify-between">
        <Label>{label}</Label>
        <span className="font-mono text-xs text-foreground tabular-nums">{display}</span>
      </div>
      <Slider
        value={[value]}
        min={min}
        max={max}
        step={step}
        onValueChange={([v]) => onChange(v)}
      />
    </div>
  )
}

export function DetectorPanel() {
  const { params, setParam, videoFile, setVideo, run, running } = useDashboard()
  const fileRef = useRef<HTMLInputElement>(null)
  const [dragging, setDragging] = useState(false)
  const [advanced, setAdvanced] = useState(false)
  const [loadingDemo, setLoadingDemo] = useState(false)

  async function loadDemo() {
    setLoadingDemo(true)
    try {
      const r = await fetch("/demo-video")
      const blob = await r.blob()
      setVideo(new File([blob], "tiny-trigger-demo.mp4", { type: "video/mp4" }))
    } catch {
      // silently ignore if demo not available
    } finally {
      setLoadingDemo(false)
    }
  }

  return (
    <div className="space-y-5">
      {/* dropzone */}
      <div
        onClick={() => fileRef.current?.click()}
        onDragOver={(e) => {
          e.preventDefault()
          setDragging(true)
        }}
        onDragLeave={() => setDragging(false)}
        onDrop={(e) => {
          e.preventDefault()
          setDragging(false)
          const f = e.dataTransfer.files?.[0]
          if (f) setVideo(f)
        }}
        className={cn(
          "group relative flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border border-dashed px-4 py-6 text-center transition-colors",
          dragging
            ? "border-primary/60 bg-primary/5"
            : "border-border hover:border-white/20 hover:bg-white/[0.02]",
        )}
      >
        <input
          ref={fileRef}
          type="file"
          accept="video/*"
          className="hidden"
          onChange={(e) => e.target.files?.[0] && setVideo(e.target.files[0])}
        />
        <div className="flex size-9 items-center justify-center rounded-full border border-border bg-white/5 text-muted-foreground group-hover:text-foreground">
          <Upload className="size-4" />
        </div>
        {videoFile ? (
          <div className="min-w-0">
            <p className="truncate font-mono text-xs text-foreground">{videoFile.name}</p>
            <p className="text-[0.6875rem] text-muted-foreground">
              {(videoFile.size / 1e6).toFixed(1)} MB · click to replace
            </p>
          </div>
        ) : (
          <div>
            <p className="text-sm text-foreground">Drop a clip or click to upload</p>
            <p className="text-[0.6875rem] text-muted-foreground">mp4 · webm · mov</p>
          </div>
        )}
      </div>

      <Button
        variant="outline"
        size="sm"
        className="w-full gap-2 text-muted-foreground"
        onClick={loadDemo}
        disabled={loadingDemo}
      >
        {loadingDemo ? <Loader2 className="size-3.5 animate-spin" /> : <Clapperboard className="size-3.5" />}
        Use demo video
      </Button>

      <div className="space-y-2">
        <Label htmlFor="classes">Open-vocabulary classes</Label>
        <Textarea
          id="classes"
          value={params.classes}
          onChange={(e) => setParam("classes", e.target.value)}
          className="min-h-16 font-mono text-xs leading-relaxed"
          placeholder="person, cat, car, chair, cup…"
        />
      </div>

      <div className="space-y-2">
        <Label htmlFor="model">Detector model</Label>
        <select
          id="model"
          value={params.modelName}
          onChange={(e) => setParam("modelName", e.target.value)}
          className="h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
        >
          {DETECTOR_MODELS.map((model) => (
            <option key={model.value} value={model.value}>
              {model.label}
            </option>
          ))}
        </select>
      </div>

      <div className="space-y-4">
        <SliderRow
          label="Confidence"
          value={params.confidence}
          display={params.confidence.toFixed(2)}
          min={0.05}
          max={0.9}
          step={0.05}
          onChange={(v) => setParam("confidence", Number(v.toFixed(2)))}
        />
        <SliderRow
          label="Sample interval"
          value={params.sampleIntervalSec}
          display={`${params.sampleIntervalSec.toFixed(2)}s`}
          min={0.25}
          max={5}
          step={0.25}
          onChange={(v) => setParam("sampleIntervalSec", Number(v.toFixed(2)))}
        />
        <SliderRow
          label="Max frames"
          value={params.maxFrames}
          display={`${params.maxFrames}`}
          min={10}
          max={300}
          step={10}
          onChange={(v) => setParam("maxFrames", v)}
        />
      </div>

      <div>
        <button
          onClick={() => setAdvanced((v) => !v)}
          className="flex w-full items-center justify-between text-xs font-medium text-muted-foreground hover:text-foreground"
        >
          Advanced
          <ChevronDown className={cn("size-3.5 transition-transform", advanced && "rotate-180")} />
        </button>
        {advanced && (
          <div className="mt-3 space-y-3 reveal">
            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1.5">
                <Label htmlFor="device">Device</Label>
                <Input
                  id="device"
                  value={params.device}
                  onChange={(e) => setParam("device", e.target.value)}
                  className="font-mono text-xs"
                  placeholder="auto / cuda:0 / cpu"
                />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="imgsz">Image size</Label>
                <select
                  id="imgsz"
                  value={params.imageSize}
                  onChange={(e) => setParam("imageSize", Number(e.target.value))}
                  className="h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
                >
                  {IMAGE_SIZES.map((size) => (
                    <option key={size} value={size}>
                      {size}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="maxdet">Max detections</Label>
              <Input
                id="maxdet"
                type="number"
                value={params.maxDetections || ""}
                onChange={(e) => setParam("maxDetections", Number(e.target.value) || 0)}
                className="font-mono text-xs"
                placeholder="default"
              />
            </div>
          </div>
        )}
      </div>

      <Separator />

      <div className="flex gap-2">
        <Button
          variant="secondary"
          size="default"
          className="flex-1"
          onClick={() => {
            setVideo(null)
          }}
          disabled={running}
        >
          <RotateCcw className="size-4" />
          Reset
        </Button>
        <Button className="flex-[2]" onClick={run} disabled={running}>
          {running ? <Loader2 className="size-4 animate-spin" /> : <Play className="size-4" />}
          {running ? "Detecting…" : "Run detection"}
        </Button>
      </div>
    </div>
  )
}
