/**
 * Check-in station — scan QR code or search bidder by name / paddle number.
 * Uses the browser BarcodeDetector API for camera scanning (Chrome/Edge mobile).
 * Falls back to manual search if BarcodeDetector is unavailable.
 */
import { useCallback, useEffect, useRef, useState } from "react";
import { api } from "../../lib/api.js";

interface BidderEnrollment {
  id: string;
  bidderId: string;
  paddleNumber: number | null;
  checkInStatus: string;
  checkInAt: string | null;
  bidder: {
    id: string;
    firstName: string;
    lastName: string;
    email: string | null;
    phone: string | null;
  };
}

declare global {
  interface Window {
    BarcodeDetector?: new (opts: { formats: string[] }) => {
      detect: (source: HTMLVideoElement) => Promise<{ rawValue: string }[]>;
    };
  }
}

type CheckInResult = { enrollment: BidderEnrollment; alreadyCheckedIn: boolean } | null;

export default function CheckInPage() {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<BidderEnrollment[]>([]);
  const [searching, setSearching] = useState(false);
  const [checkInResult, setCheckInResult] = useState<CheckInResult>(null);
  const [scanMode, setScanMode] = useState(false);
  const [scanError, setScanError] = useState<string | null>(null);
  const [eventId, setEventId] = useState<string | null>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  const scanLoopRef = useRef<number | null>(null);

  // Fetch active event for this staff session
  useEffect(() => {
    api
      .get<{ id: string; status: string }[]>("/api/events")
      .then((events) => {
        const active = events.find((e) => e.status === "active") ?? events[0];
        if (active) setEventId(active.id);
      })
      .catch(console.error);
  }, []);

  // Debounced bidder search
  useEffect(() => {
    if (!eventId || query.trim().length < 2) {
      setResults([]);
      return;
    }
    setSearching(true);
    const timer = setTimeout(() => {
      api
        .get<BidderEnrollment[]>(`/api/bidders?eventId=${eventId}&q=${encodeURIComponent(query)}`)
        .then(setResults)
        .catch(console.error)
        .finally(() => setSearching(false));
    }, 300);
    return () => clearTimeout(timer);
  }, [query, eventId]);

  const doCheckIn = useCallback(
    async (enrollmentId: string) => {
      try {
        const result = await api.post<{ enrollment: BidderEnrollment; alreadyCheckedIn: boolean }>(
          `/api/check-in/${enrollmentId}`,
          {},
        );
        setCheckInResult(result);
        setResults([]);
        setQuery("");
      } catch (err) {
        console.error(err);
      }
    },
    [],
  );

  const doScanCheckIn = useCallback(
    async (bidderId: string, eid: string) => {
      try {
        const result = await api.post<{ enrollment: BidderEnrollment; alreadyCheckedIn: boolean }>(
          "/api/check-in/scan",
          { bidderId, eventId: eid },
        );
        setCheckInResult(result);
      } catch {
        setScanError("Bidder not found for this event");
      }
    },
    [],
  );

  // Camera QR scanning loop
  const startScan = useCallback(async () => {
    if (!window.BarcodeDetector) {
      setScanError("Camera QR scanning not supported in this browser. Use manual search.");
      return;
    }
    setScanMode(true);
    setScanError(null);
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: "environment" },
      });
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        await videoRef.current.play();
      }
      const detector = new window.BarcodeDetector!({ formats: ["qr_code"] });
      const scan = async () => {
        if (!videoRef.current) return;
        try {
          const barcodes = await detector.detect(videoRef.current);
          if (barcodes.length > 0) {
            const raw = barcodes[0]!.rawValue;
            // Parse /check-in?b=<bidderId>&e=<eventId>
            try {
              const url = new URL(raw);
              const b = url.searchParams.get("b");
              const e = url.searchParams.get("e");
              if (b && e) {
                stopScan(stream);
                await doScanCheckIn(b, e);
                return;
              }
            } catch {
              // Not a valid URL — ignore
            }
          }
        } catch {
          // Detector error on a frame — continue
        }
        scanLoopRef.current = requestAnimationFrame(scan);
      };
      scanLoopRef.current = requestAnimationFrame(scan);
    } catch {
      setScanError("Camera access denied. Use manual search instead.");
      setScanMode(false);
    }
  }, [doScanCheckIn]);

  const stopScan = (stream?: MediaStream) => {
    if (scanLoopRef.current) cancelAnimationFrame(scanLoopRef.current);
    if (videoRef.current?.srcObject) {
      (videoRef.current.srcObject as MediaStream).getTracks().forEach((t) => t.stop());
      videoRef.current.srcObject = null;
    }
    if (stream) stream.getTracks().forEach((t) => t.stop());
    setScanMode(false);
  };

  return (
    <main className="min-h-screen bg-gray-50">
      {/* Header */}
      <div className="bg-brand-700 text-white px-4 py-4 flex items-center gap-3">
        <span className="text-2xl">✅</span>
        <div>
          <h1 className="text-xl font-black">Check-In</h1>
          <p className="text-xs opacity-70">Scan QR or search by name / paddle</p>
        </div>
        <div className="ml-auto">
          {scanMode ? (
            <button
              onClick={() => stopScan()}
              className="bg-white/20 text-white text-sm font-semibold px-3 py-1.5 rounded-lg"
            >
              Cancel Scan
            </button>
          ) : (
            <button
              onClick={startScan}
              className="bg-white/20 text-white text-sm font-semibold px-3 py-1.5 rounded-lg"
            >
              Scan QR
            </button>
          )}
        </div>
      </div>

      <div className="p-4 space-y-4 max-w-xl mx-auto">
        {/* Camera viewfinder */}
        {scanMode && (
          <div className="card overflow-hidden aspect-square relative">
            <video ref={videoRef} className="w-full h-full object-cover" playsInline muted />
            <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
              <div className="w-48 h-48 border-4 border-white/80 rounded-2xl" />
            </div>
            <p className="absolute bottom-3 left-0 right-0 text-center text-white text-xs font-semibold drop-shadow">
              Point at bidder's QR code
            </p>
          </div>
        )}

        {scanError && (
          <div className="bg-red-50 border border-red-200 rounded-xl p-3 text-sm text-red-700">
            {scanError}
          </div>
        )}

        {/* Manual search */}
        {!scanMode && (
          <input
            type="search"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="Search name, email, or paddle #…"
            className="field"
            autoFocus
          />
        )}

        {/* Search results */}
        {results.length > 0 && (
          <ul className="space-y-2">
            {results.map((enrollment) => (
              <li key={enrollment.id} className="card p-4 flex items-center gap-3">
                <div className="w-10 h-10 rounded-full bg-brand-100 flex items-center justify-center text-brand-700 font-black flex-shrink-0">
                  {enrollment.bidder.firstName.charAt(0).toUpperCase()}
                </div>
                <div className="flex-1 min-w-0">
                  <p className="font-bold text-gray-900">
                    {enrollment.bidder.firstName} {enrollment.bidder.lastName}
                  </p>
                  <p className="text-xs text-gray-400">
                    {enrollment.bidder.email ?? enrollment.bidder.phone}
                    {enrollment.paddleNumber ? ` · Paddle #${enrollment.paddleNumber}` : ""}
                  </p>
                </div>
                {enrollment.checkInStatus === "checked_in" ? (
                  <span className="badge bg-emerald-100 text-emerald-700 shrink-0">
                    Checked In
                  </span>
                ) : (
                  <button
                    onClick={() => doCheckIn(enrollment.id)}
                    className="btn-primary text-sm px-4 py-2 shrink-0"
                  >
                    Check In
                  </button>
                )}
              </li>
            ))}
          </ul>
        )}

        {searching && (
          <p className="text-center text-sm text-gray-400">Searching…</p>
        )}

        {/* Check-in result toast */}
        {checkInResult && (
          <div
            className={`card p-5 border-2 ${
              checkInResult.alreadyCheckedIn
                ? "border-amber-300 bg-amber-50"
                : "border-emerald-400 bg-emerald-50"
            }`}
          >
            <div className="flex items-center gap-3">
              <span className="text-3xl">
                {checkInResult.alreadyCheckedIn ? "⚠️" : "✅"}
              </span>
              <div>
                <p className="font-bold text-gray-900">
                  {checkInResult.enrollment.bidder.firstName}{" "}
                  {checkInResult.enrollment.bidder.lastName}
                </p>
                {checkInResult.alreadyCheckedIn ? (
                  <p className="text-sm text-amber-700">Already checked in earlier</p>
                ) : (
                  <p className="text-sm text-emerald-700">
                    Checked in!
                    {checkInResult.enrollment.paddleNumber
                      ? ` · Paddle #${checkInResult.enrollment.paddleNumber}`
                      : ""}
                  </p>
                )}
              </div>
              <button
                onClick={() => setCheckInResult(null)}
                className="ml-auto text-gray-400 hover:text-gray-600 text-xl leading-none"
              >
                ×
              </button>
            </div>
          </div>
        )}

        {/* Empty state */}
        {!scanMode && query.trim().length >= 2 && results.length === 0 && !searching && (
          <div className="card p-8 text-center text-gray-400 text-sm">
            No bidders found for "{query}"
          </div>
        )}

        {!scanMode && query.trim().length === 0 && !checkInResult && (
          <div className="card p-6 text-center text-gray-400 text-sm border-dashed border-2 border-gray-200">
            Search above or tap <strong className="text-gray-500">Scan QR</strong> to use camera
          </div>
        )}
      </div>
    </main>
  );
}
