/**
 * PipelineControl — start / stop pipeline form.
 *
 * Features:
 *   - Free-form source input (webcam index, file path, RTSP URL)
 *   - "Demo" quick-start button — synthetic scene, no model needed
 *   - Optional counting line configuration (up to 3 named lines)
 *   - Confidence threshold
 */
import { useState } from 'react'

const API = '/api'

// Default counting line for demo mode: vertical centre line on a 1280×720 frame
const DEMO_LINE = { name: 'main', x1: 640, y1: 252, x2: 640, y2: 612 }

export default function PipelineControl({ status, onStatusChange, gpu }) {
  const [source,    setSource]    = useState('0')
  const [conf,      setConf]      = useState('0.35')
  const [showLines, setShowLines] = useState(false)
  const [lines,     setLines]     = useState([])
  const [loading,   setLoading]   = useState(false)
  const [error,     setError]     = useState(null)

  const isRunning = status?.running ?? false

  // ── helpers ──────────────────────────────────────────────────────────────

  function addLine() {
    if (lines.length >= 3) return
    setLines(prev => [
      ...prev,
      { name: `line${prev.length + 1}`, x1: 0, y1: 360, x2: 1280, y2: 360 },
    ])
  }

  function removeLine(i) {
    setLines(prev => prev.filter((_, idx) => idx !== i))
  }

  function updateLine(i, field, value) {
    setLines(prev =>
      prev.map((l, idx) =>
        idx === i ? { ...l, [field]: field === 'name' ? value : Number(value) } : l
      )
    )
  }

  async function startPipeline(src, linesCfg) {
    setLoading(true)
    setError(null)
    try {
      const res = await fetch(`${API}/pipeline/start`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          source: src,
          confidence_threshold: parseFloat(conf),
          counting_lines: linesCfg,
        }),
      })
      if (!res.ok) {
        const body = await res.json().catch(() => ({}))
        throw new Error(body?.detail ?? `HTTP ${res.status}`)
      }
      onStatusChange?.()
    } catch (err) {
      setError(err.message)
    } finally {
      setLoading(false)
    }
  }

  async function handleStart(e) {
    e.preventDefault()
    await startPipeline(source, lines)
  }

  async function handleDemo() {
    await startPipeline('demo', [DEMO_LINE])
  }

  async function handleStop() {
    setLoading(true)
    setError(null)
    try {
      await fetch(`${API}/pipeline/stop`, { method: 'POST' })
      onStatusChange?.()
    } catch (err) {
      setError(err.message)
    } finally {
      setLoading(false)
    }
  }

  // ── render ────────────────────────────────────────────────────────────────

  return (
    <div className="bg-gray-800 border border-gray-700 rounded-xl p-4">
      <h3 className="text-sm font-semibold text-gray-300 mb-3">Pipeline Control</h3>

      <form onSubmit={handleStart} className="flex flex-wrap gap-3 items-end">
        {/* Source */}
        <div className="flex flex-col gap-1">
          <label className="text-xs text-gray-400">Source</label>
          <input
            className="bg-gray-900 border border-gray-600 rounded px-3 py-1.5 text-sm text-gray-200 w-52 focus:outline-none focus:border-blue-500"
            placeholder="0  /path/to/video  rtsp://…"
            value={source}
            onChange={e => setSource(e.target.value)}
            disabled={isRunning}
          />
        </div>

        {/* Confidence */}
        <div className="flex flex-col gap-1">
          <label className="text-xs text-gray-400">Confidence</label>
          <input
            type="number"
            step="0.05"
            min="0.05"
            max="0.95"
            className="bg-gray-900 border border-gray-600 rounded px-3 py-1.5 text-sm text-gray-200 w-24 focus:outline-none focus:border-blue-500"
            value={conf}
            onChange={e => setConf(e.target.value)}
            disabled={isRunning}
          />
        </div>

        {/* Counting lines toggle */}
        {!isRunning && (
          <button
            type="button"
            onClick={() => setShowLines(v => !v)}
            className="px-3 py-1.5 rounded border border-gray-600 text-xs text-gray-400 hover:text-gray-200 hover:border-gray-400 transition-colors"
          >
            {showLines ? 'Hide lines' : `Lines (${lines.length})`}
          </button>
        )}

        {/* Start / Stop buttons */}
        {!isRunning ? (
          <div className="flex gap-2">
            <button
              type="submit"
              disabled={loading}
              className="px-4 py-1.5 rounded bg-blue-600 hover:bg-blue-500 text-sm font-medium disabled:opacity-50 transition-colors"
            >
              {loading ? 'Starting…' : 'Start'}
            </button>
            <button
              type="button"
              onClick={handleDemo}
              disabled={loading}
              className="px-4 py-1.5 rounded bg-emerald-700 hover:bg-emerald-600 text-sm font-medium disabled:opacity-50 transition-colors"
              title="Run synthetic demo — no ONNX model or camera required"
            >
              Demo
            </button>
          </div>
        ) : (
          <button
            type="button"
            onClick={handleStop}
            disabled={loading}
            className="px-4 py-1.5 rounded bg-red-600 hover:bg-red-500 text-sm font-medium disabled:opacity-50 transition-colors"
          >
            {loading ? 'Stopping…' : 'Stop'}
          </button>
        )}
      </form>

      {/* Counting lines editor */}
      {showLines && !isRunning && (
        <div className="mt-3 space-y-2">
          <div className="text-xs text-gray-500 mb-1">
            Counting lines — vehicles are counted when they cross a line
          </div>
          {lines.map((line, i) => (
            <div key={i} className="flex flex-wrap gap-2 items-center">
              <input
                className="bg-gray-900 border border-gray-700 rounded px-2 py-1 text-xs text-gray-300 w-20"
                placeholder="name"
                value={line.name}
                onChange={e => updateLine(i, 'name', e.target.value)}
              />
              {['x1', 'y1', 'x2', 'y2'].map(f => (
                <input
                  key={f}
                  type="number"
                  className="bg-gray-900 border border-gray-700 rounded px-2 py-1 text-xs text-gray-300 w-16"
                  placeholder={f}
                  value={line[f]}
                  onChange={e => updateLine(i, f, e.target.value)}
                />
              ))}
              <button
                type="button"
                onClick={() => removeLine(i)}
                className="text-xs text-red-500 hover:text-red-400"
              >
                ✕
              </button>
            </div>
          ))}
          {lines.length < 3 && (
            <button
              type="button"
              onClick={addLine}
              className="text-xs text-blue-400 hover:text-blue-300"
            >
              + Add line
            </button>
          )}
        </div>
      )}

      {/* CPU-only warning — shown when GPU is confirmed absent and source is not demo */}
      {gpu === false && !isRunning && source.trim().toLowerCase() !== 'demo' && (
        <div className="mt-3 flex items-start gap-2 rounded-lg border border-yellow-700 bg-yellow-900/30 px-3 py-2 text-xs text-yellow-300">
          <span className="mt-0.5 shrink-0">⚠</span>
          <span>
            <strong>CPU-only mode</strong> — no GPU detected. Real video inference will run at
            roughly 3–8 FPS and may lag behind live sources.{' '}
            Keep uploaded video clips under <strong>20 seconds</strong> for best results,
            or click <strong>Demo</strong> for full-speed synthetic playback.
          </span>
        </div>
      )}

      {error && <p className="mt-2 text-xs text-red-400">{error}</p>}

      {status && (
        <p className="mt-2 text-xs text-gray-500">
          {isRunning
            ? `${status.demo_mode ? '[DEMO] ' : ''}Running — frame ${status.frame_index} · ${status.fps} fps · source: ${status.source}`
            : 'Pipeline stopped'}
        </p>
      )}
    </div>
  )
}
