import { useEffect, useRef, useState } from 'react';
import { Html5Qrcode } from 'html5-qrcode';
import { useQueryClient } from '@tanstack/react-query';
import {
  ESTADO_META,
  siguientesEstados,
  formatUsd,
  type Pedido,
  type PedidoItem,
  type EstadoPedido,
} from '@gustito/shared';
import { supabase } from '../lib/supabase';

type PedidoFull = Pedido & { pedido_items: PedidoItem[]; cuenta_id: string | null };

export default function EscanearQR({
  restauranteId,
  onCerrar,
}: {
  restauranteId: string;
  onCerrar: () => void;
}) {
  const qc = useQueryClient();
  const [pedido, setPedido] = useState<PedidoFull | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [mesa, setMesa] = useState('');
  const [sentando, setSentando] = useState(false);
  const scannerRef = useRef<Html5Qrcode | null>(null);
  const lectorId = 'qr-reader';

  async function detener() {
    try {
      if (scannerRef.current?.isScanning) await scannerRef.current.stop();
    } catch {
      /* ignore */
    }
  }

  async function buscar(texto: string) {
    setError(null);
    const id = texto.trim();
    if (!/^[0-9a-fA-F-]{36}$/.test(id)) {
      setError('Ese QR no es un ticket valido.');
      return;
    }
    // RLS: solo devuelve el pedido si es de ESTE restaurante (aislamiento).
    const { data, error } = await supabase
      .from('pedidos')
      .select('*, pedido_items(*)')
      .eq('id', id)
      .eq('restaurante_id', restauranteId)
      .maybeSingle();
    if (error) {
      setError(error.message);
      return;
    }
    if (!data) {
      setError('Ese pedido no es de tu restaurante.');
      return;
    }
    setPedido(data as unknown as PedidoFull);
  }

  useEffect(() => {
    const scanner = new Html5Qrcode(lectorId);
    scannerRef.current = scanner;
    scanner
      .start(
        { facingMode: 'environment' },
        { fps: 10, qrbox: 220 },
        async (texto) => {
          await detener();
          buscar(texto);
        },
        () => {},
      )
      .catch((e) => setError('No se pudo abrir la camara: ' + String(e)));
    return () => {
      detener();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps -- la camara arranca UNA vez al montar; buscar/detener solo cierran sobre props estables
  }, []);

  async function cambiar(nuevo: EstadoPedido) {
    if (!pedido) return;
    const { error } = await supabase.rpc('cambiar_estado_pedido', {
      p_pedido_id: pedido.id,
      p_nuevo_estado: nuevo,
    });
    if (error) {
      setError(error.message);
      return;
    }
    qc.invalidateQueries({ queryKey: ['pedidos', restauranteId] });
    onCerrar();
  }

  // El QR escaneado ES la verificacion de identidad (el ticket trae nombre y
  // pedido del cliente, visibles arriba, para calzarlos con la persona presente).
  // Reserva sin mesa todavia: aqui mismo se le asigna, sin escribir nada aparte.
  async function sentarEnMesa() {
    if (!pedido) return;
    const numMesa = mesa.trim();
    if (!numMesa) {
      setError('Escribe el número de mesa.');
      return;
    }
    setSentando(true);
    const { error } = await supabase.rpc('sentar_reserva', { p_pedido_id: pedido.id, p_mesa: numMesa });
    setSentando(false);
    if (error) {
      setError(error.message);
      return;
    }
    qc.invalidateQueries({ queryKey: ['pedidos', restauranteId] });
    qc.invalidateQueries({ queryKey: ['cuentas-mesa', restauranteId] });
    onCerrar();
  }

  return (
    <div className="fixed inset-0 bg-black/70 z-40 flex items-center justify-center p-4">
      <div className="bg-superficie rounded-2xl w-full max-w-sm overflow-hidden">
        <div className="p-3 border-b flex items-center justify-between">
          <h2 className="font-bold">Escanear ticket</h2>
          <button
            onClick={() => {
              detener();
              onCerrar();
            }}
            className="text-niebla text-2xl leading-none"
          >
            &times;
          </button>
        </div>

        {!pedido ? (
          <div className="p-3">
            <div id={lectorId} className="w-full" />
            <p className="text-xs text-niebla mt-2 text-center">Apunta al QR del ticket del cliente.</p>
            {error && <p className="text-sm text-red-600 mt-2 text-center">{error}</p>}
          </div>
        ) : (
          <div className="p-4 space-y-2">
            <p className="font-extrabold text-lg">{pedido.codigo}</p>
            <p className="text-sm text-niebla">
              {pedido.cliente_nombre} · {pedido.cliente_telefono}
            </p>
            {pedido.cliente_cedula && (
              <p className="text-sm text-niebla">Cedula: {pedido.cliente_cedula}</p>
            )}
            {pedido.tipo_entrega === 'mesa' && (
              <p className="text-sm text-niebla">Mesa {pedido.mesa}</p>
            )}
            {pedido.tipo_entrega === 'reserva' && (
              <p className="text-sm text-niebla">
                Reserva para {pedido.personas ?? 1} persona{(pedido.personas ?? 1) === 1 ? '' : 's'}
                {pedido.cuenta_id ? ` · Mesa ${pedido.mesa ?? ''}`.trim() : ''}
              </p>
            )}
            <ul className="text-sm border-y py-2 space-y-1">
              {pedido.pedido_items.map((it) => (
                <li key={it.id} className="flex justify-between">
                  <span>
                    {it.cantidad}× {it.nombre}
                  </span>
                  <span>{formatUsd(it.precio_usd * it.cantidad)}</span>
                </li>
              ))}
            </ul>
            <p className="font-bold">Total {formatUsd(pedido.total_usd)}</p>
            <p className="text-sm">
              Estado: <b>{ESTADO_META[pedido.estado].label}</b>
            </p>

            {/* El QR ya verifico que es su pedido (nombre y detalle arriba,
                calzalo con quien tienes al frente): aqui mismo se le asigna mesa. */}
            {pedido.tipo_entrega === 'reserva' && !pedido.cuenta_id && (
              <div className="rounded-xl bg-sky-500/10 p-2.5 ring-1 ring-sky-500/30">
                <p className="mb-1.5 text-xs font-semibold text-sky-200">Asignarle mesa:</p>
                <div className="flex items-center gap-2">
                  <input
                    placeholder="N° mesa"
                    className="input w-24"
                    value={mesa}
                    onChange={(e) => setMesa(e.target.value)}
                    autoFocus
                  />
                  <button
                    onClick={sentarEnMesa}
                    disabled={sentando}
                    className="btn ml-auto bg-sky-600 text-white disabled:opacity-60"
                  >
                    {sentando ? 'Sentando...' : 'Sentar en mesa'}
                  </button>
                </div>
              </div>
            )}

            <div className="flex flex-wrap gap-2 pt-2">
              {siguientesEstados(pedido.estado, pedido.tipo_entrega).map((s) => (
                <button
                  key={s}
                  onClick={() => cambiar(s)}
                  className="btn text-white"
                  style={{ backgroundColor: ESTADO_META[s].color }}
                >
                  {ESTADO_META[s].label}
                </button>
              ))}
              {siguientesEstados(pedido.estado, pedido.tipo_entrega).length === 0 && (
                <p className="text-sm text-niebla">Pedido finalizado.</p>
              )}
            </div>
            {error && <p className="text-sm text-red-600">{error}</p>}
          </div>
        )}
      </div>
    </div>
  );
}
