"use client";

import { useEffect, useRef, useState } from "react";
import { Camera, ScanBarcode, X } from "lucide-react";

type Props = {
  value: string;
  onChange: (value: string) => void;
  onScanComplete?: (value: string) => void;
  placeholder?: string;
  autoFocus?: boolean;
};

/**
 * Campo pensado para lector USB (teclado) + cámara opcional (BarcodeDetector).
 * El lector USB escribe rápido y termina con Enter.
 */
export function GuideScannerInput({
  value,
  onChange,
  onScanComplete,
  placeholder = "Escanea o escribe el número de guía",
  autoFocus,
}: Props) {
  const inputRef = useRef<HTMLInputElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  const streamRef = useRef<MediaStream | null>(null);
  const rafRef = useRef<number | null>(null);
  const [cameraOpen, setCameraOpen] = useState(false);
  const [cameraError, setCameraError] = useState<string | null>(null);
  const [scanning, setScanning] = useState(false);

  const supportsCamera =
    typeof window !== "undefined" &&
    "BarcodeDetector" in window &&
    !!navigator.mediaDevices?.getUserMedia;

  useEffect(() => {
    if (autoFocus) inputRef.current?.focus();
  }, [autoFocus]);

  useEffect(() => {
    return () => stopCamera();
  }, []);

  const stopCamera = () => {
    if (rafRef.current) cancelAnimationFrame(rafRef.current);
    rafRef.current = null;
    streamRef.current?.getTracks().forEach((t) => t.stop());
    streamRef.current = null;
    setScanning(false);
  };

  const closeCamera = () => {
    stopCamera();
    setCameraOpen(false);
  };

  const startCamera = async () => {
    setCameraError(null);
    setCameraOpen(true);
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: { ideal: "environment" } },
        audio: false,
      });
      streamRef.current = stream;
      const video = videoRef.current;
      if (!video) return;
      video.srcObject = stream;
      await video.play();
      setScanning(true);

      const Detector = (
        window as unknown as {
          BarcodeDetector: new (opts: { formats: string[] }) => {
            detect: (source: HTMLVideoElement) => Promise<{ rawValue?: string }[]>;
          };
        }
      ).BarcodeDetector;
      const detector = new Detector({
        formats: [
          "code_128",
          "code_39",
          "ean_13",
          "ean_8",
          "qr_code",
          "upc_a",
          "upc_e",
        ],
      });

      const tick = async () => {
        if (!videoRef.current || videoRef.current.readyState < 2) {
          rafRef.current = requestAnimationFrame(tick);
          return;
        }
        try {
          const codes = await detector.detect(videoRef.current);
          const raw = codes?.[0]?.rawValue?.trim();
          if (raw) {
            onChange(raw);
            onScanComplete?.(raw);
            closeCamera();
            return;
          }
        } catch {
          /* keep scanning */
        }
        rafRef.current = requestAnimationFrame(tick);
      };
      rafRef.current = requestAnimationFrame(tick);
    } catch {
      setCameraError(
        "No se pudo abrir la cámara. Usa el lector USB o escribe la guía."
      );
      setScanning(false);
    }
  };

  return (
    <div className="space-y-2">
      <div className="flex gap-2">
        <div className="relative flex-1">
          <ScanBarcode
            size={16}
            className="absolute left-3 top-1/2 -translate-y-1/2 text-ot-muted pointer-events-none"
          />
          <input
            ref={inputRef}
            className="w-full border border-black/15 pl-9 pr-3 py-2.5 text-sm font-mono tracking-wide"
            placeholder={placeholder}
            value={value}
            autoComplete="off"
            inputMode="text"
            onChange={(e) => onChange(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                e.preventDefault();
                const v = value.trim();
                if (v) onScanComplete?.(v);
              }
            }}
          />
        </div>
        {supportsCamera ? (
          <button
            type="button"
            className="ot-btn ot-btn-ghost !px-3"
            onClick={() => void startCamera()}
            title="Escanear con cámara"
          >
            <Camera size={18} />
          </button>
        ) : null}
      </div>
      <p className="text-[11px] text-ot-muted leading-snug">
        Tip: enfoca este campo y escanea con el lector USB (Enter confirma).
        {supportsCamera ? " También puedes usar la cámara." : ""}
      </p>

      {cameraOpen ? (
        <div className="relative border border-black/10 bg-black overflow-hidden">
          <video
            ref={videoRef}
            className="w-full aspect-[4/3] object-cover"
            muted
            playsInline
          />
          <button
            type="button"
            className="absolute top-2 right-2 bg-ot-cream/95 p-1.5"
            onClick={closeCamera}
            aria-label="Cerrar cámara"
          >
            <X size={16} />
          </button>
          <p className="absolute bottom-2 left-2 right-2 text-center text-[11px] text-white/90">
            {scanning
              ? "Apunta al código de barras de la guía…"
              : cameraError || "Iniciando cámara…"}
          </p>
        </div>
      ) : null}
      {cameraError && !cameraOpen ? (
        <p className="text-xs text-red-700">{cameraError}</p>
      ) : null}
    </div>
  );
}
