import { useState, useEffect, useRef, useCallback } from 'react';
import {
  QrCode, ChevronLeft, Check, Search, Camera, CameraOff,
  Package, Loader2, RefreshCw, AlertTriangle, CheckCircle2,
  Bell, BellOff, X, ImagePlus,
} from 'lucide-react';
import api from '../services/api';

// ─── Types ────────────────────────────────────────────────────────────────────

interface Item {
  id: number;
  produto_id: number | null;
  nome_produto: string;
  sku: string | null;
  quantidade: number;
  separado: boolean;
  observacao?: string | null;
  alerta_tipo?: string | null;
  alerta_obs?: string | null;
  alerta_foto?: string | null;
  alerta_confirmado?: boolean;
}

interface Pedido {
  id: number;
  protocolo: string | null;
  cliente_nome: string;
  status: string;
  total: number | string;
  itens?: Item[];
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

function fmt(v: any) {
  return `R$ ${Number(v || 0).toFixed(2).replace('.', ',')}`;
}

function beep(ok: boolean) {
  try {
    const ctx = new AudioContext();
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    osc.connect(gain);
    gain.connect(ctx.destination);
    osc.frequency.value = ok ? 880 : 330;
    osc.type = 'sine';
    gain.gain.setValueAtTime(0.4, ctx.currentTime);
    gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.18);
    osc.start(ctx.currentTime);
    osc.stop(ctx.currentTime + 0.18);
  } catch {}
}

function vibrate(ok: boolean) {
  try { navigator.vibrate?.(ok ? [50] : [80, 40, 80]); } catch {}
}

// ─── BarcodeDetector (native) + manual fallback ───────────────────────────────

declare class BarcodeDetector {
  constructor(opts?: { formats?: string[] });
  detect(src: ImageBitmapSource): Promise<Array<{ rawValue: string }>>;
  static getSupportedFormats(): Promise<string[]>;
}

// ─── Lista de pedidos em separação ───────────────────────────────────────────

function PedidoCard({ pedido, onClick }: { pedido: Pedido; onClick: () => void }) {
  return (
    <button
      onClick={onClick}
      className="w-full text-left bg-slate-900 border border-white/10 rounded-2xl p-4 hover:border-amber-500/30 transition-all active:scale-[.98]"
    >
      <div className="flex items-start justify-between gap-2">
        <div>
          <p className="text-white font-bold text-sm">
            {pedido.protocolo || `#${pedido.id}`}
          </p>
          <p className="text-slate-400 text-xs mt-0.5 truncate">{pedido.cliente_nome || '—'}</p>
        </div>
        <span className="text-xs font-black text-amber-400 shrink-0">{fmt(pedido.total)}</span>
      </div>
      <div className="mt-3 flex items-center gap-2">
        <span className="text-[10px] font-black uppercase tracking-widest bg-blue-500/10 text-blue-400 border border-blue-500/20 px-2 py-0.5 rounded-full">
          Separação
        </span>
      </div>
    </button>
  );
}

// ─── Tipos de alerta ─────────────────────────────────────────────────────────
const ALERTA_TIPOS = [
  { id: 'falta',          label: '🚫 Falta',           cor: 'border-rose-500/40 text-rose-400 bg-rose-500/10' },
  { id: 'marca_diferente',label: '🔄 Marca diferente',  cor: 'border-amber-500/40 text-amber-400 bg-amber-500/10' },
  { id: 'substituicao',   label: '📸 Substituição',     cor: 'border-blue-500/40 text-blue-400 bg-blue-500/10' },
]

function ItemCard({ item, onSeparado, onAlerta }: {
  item: Item
  onSeparado: (id: number, val: boolean) => void
  onAlerta: (id: number, alerta: Partial<Item>) => void
}) {
  const [alertaOpen, setAlertaOpen] = useState(false)
  const [tipo, setTipo] = useState(item.alerta_tipo || '')
  const [obs, setObs] = useState(item.alerta_obs || '')
  const [fotoUrl, setFotoUrl] = useState(item.alerta_foto || '')
  const [saving, setSaving] = useState(false)

  async function salvarAlerta() {
    if (!tipo) return
    setSaving(true)
    try {
      await api.patch(`/cotacoes/admin/pedidos/itens/${item.id}/alerta`, { tipo, obs, foto: fotoUrl || null })
      onAlerta(item.id, { alerta_tipo: tipo, alerta_obs: obs, alerta_foto: fotoUrl || null, alerta_confirmado: false })
      setAlertaOpen(false)
    } catch {}
    finally { setSaving(false) }
  }

  async function limparAlerta() {
    setSaving(true)
    try {
      await api.delete(`/cotacoes/admin/pedidos/itens/${item.id}/alerta`)
      onAlerta(item.id, { alerta_tipo: null, alerta_obs: null, alerta_foto: null, alerta_confirmado: false })
      setTipo(''); setObs(''); setFotoUrl('')
    } catch {}
    finally { setSaving(false) }
  }

  const alertaDef = ALERTA_TIPOS.find(a => a.id === item.alerta_tipo)

  return (
    <div className={`rounded-xl border transition-all ${
      item.separado ? 'bg-emerald-500/5 border-emerald-500/20' :
      item.alerta_tipo ? 'bg-slate-900 border-rose-500/30' :
      'bg-slate-900 border-white/8'
    }`}>
      <div className="flex items-center gap-3 p-3">
        <button
          onClick={() => onSeparado(item.id, !item.separado)}
          className={`w-7 h-7 rounded-lg flex items-center justify-center shrink-0 border-2 transition-all ${
            item.separado
              ? 'bg-emerald-500 border-emerald-500 text-white'
              : 'border-slate-600 hover:border-amber-400'
          }`}
        >
          {item.separado && <Check size={14} />}
        </button>
        <div className="flex-1 min-w-0">
          <p className={`text-sm font-bold truncate ${item.separado ? 'text-slate-500 line-through' : 'text-white'}`}>
            {item.nome_produto}
          </p>
          <p className="text-xs text-slate-600">
            {item.sku && <span className="text-slate-500 font-mono">{item.sku} · </span>}
            Qtd: {item.quantidade}
          </p>
          {item.observacao && !item.separado && (
            <div className="mt-1.5 flex items-start gap-1.5 bg-amber-500/10 border border-amber-500/30 rounded-lg px-2 py-1">
              <AlertTriangle size={12} className="text-amber-400 shrink-0 mt-0.5" />
              <p className="text-xs text-amber-300 font-semibold leading-tight">{item.observacao}</p>
            </div>
          )}
          {/* Alerta ativo */}
          {item.alerta_tipo && !alertaOpen && (
            <div className={`mt-1.5 flex items-center gap-1.5 rounded-lg px-2 py-1 border text-xs font-bold ${alertaDef?.cor ?? ''}`}>
              <span className="flex-1">{alertaDef?.label ?? item.alerta_tipo}</span>
              {item.alerta_confirmado && <span className="text-emerald-400 text-[10px]">✓ Confirmado</span>}
            </div>
          )}
        </div>
        {/* Botão alerta */}
        {!item.separado && (
          <button
            onClick={() => { setTipo(item.alerta_tipo || ''); setObs(item.alerta_obs || ''); setFotoUrl(item.alerta_foto || ''); setAlertaOpen(o => !o) }}
            title="Sinalizar problema"
            className={`w-8 h-8 rounded-lg flex items-center justify-center shrink-0 border transition-all ${
              item.alerta_tipo
                ? 'bg-rose-500/20 border-rose-500/40 text-rose-400'
                : 'border-slate-700 text-slate-500 hover:text-amber-400 hover:border-amber-500/40'
            }`}
          >
            {item.alerta_tipo ? <BellOff size={14} /> : <Bell size={14} />}
          </button>
        )}
      </div>

      {/* Painel de alerta */}
      {alertaOpen && (
        <div className="border-t border-white/8 px-3 pb-3 pt-2 space-y-2">
          <p className="text-[10px] font-black uppercase tracking-widest text-slate-500">Sinalizar problema</p>
          <div className="flex gap-1.5 flex-wrap">
            {ALERTA_TIPOS.map(a => (
              <button key={a.id} onClick={() => setTipo(a.id)}
                className={`text-xs px-2.5 py-1 rounded-full border font-semibold transition-all ${
                  tipo === a.id ? a.cor : 'border-slate-700 text-slate-500 hover:border-slate-500'
                }`}>
                {a.label}
              </button>
            ))}
          </div>
          <input
            value={obs}
            onChange={e => setObs(e.target.value)}
            placeholder="Observação (opcional)"
            className="w-full bg-slate-800 border border-white/10 rounded-lg px-2.5 py-1.5 text-xs text-white placeholder:text-slate-600 focus:outline-none focus:border-amber-500/40"
          />
          <div className="flex items-center gap-1.5">
            <ImagePlus size={14} className="text-slate-500 shrink-0" />
            <input
              value={fotoUrl}
              onChange={e => setFotoUrl(e.target.value)}
              placeholder="URL da foto (opcional)"
              className="flex-1 bg-slate-800 border border-white/10 rounded-lg px-2.5 py-1.5 text-xs text-white placeholder:text-slate-600 focus:outline-none focus:border-amber-500/40"
            />
          </div>
          <div className="flex gap-2 pt-1">
            <button onClick={salvarAlerta} disabled={!tipo || saving}
              className="flex-1 bg-amber-500 text-black text-xs font-black py-1.5 rounded-lg disabled:opacity-40">
              {saving ? '…' : 'Salvar alerta'}
            </button>
            {item.alerta_tipo && (
              <button onClick={limparAlerta} disabled={saving}
                className="px-3 py-1.5 rounded-lg border border-rose-500/30 text-rose-400 text-xs font-bold">
                <X size={12} />
              </button>
            )}
            <button onClick={() => setAlertaOpen(false)}
              className="px-3 py-1.5 rounded-lg border border-white/10 text-slate-400 text-xs">
              Cancelar
            </button>
          </div>
        </div>
      )}
    </div>
  )
}

// ─── Tela de scan de um pedido ────────────────────────────────────────────────

function ScanScreen({ pedido, onBack }: { pedido: Pedido; onBack: () => void }) {
  const [itens, setItens]         = useState<Item[]>(pedido.itens || []);
  const [manual, setManual]       = useState('');
  const [flash, setFlash]         = useState<'ok' | 'err' | null>(null);
  const [flashMsg, setFlashMsg]   = useState('');
  const [camOn, setCamOn]         = useState(false);
  const [camErr, setCamErr]       = useState('');
  const videoRef                  = useRef<HTMLVideoElement>(null);
  const streamRef                 = useRef<MediaStream | null>(null);
  const scanningRef               = useRef(false);
  const detectorRef               = useRef<BarcodeDetector | null>(null);

  const separated = itens.filter(i => i.separado).length;
  const total     = itens.length;
  const done      = separated === total && total > 0;

  // ── Mark item separated ──────────────────────────────────────────────────────

  const markSeparado = useCallback(async (itemId: number, value: boolean) => {
    await api.patch(`/cotacoes/admin/pedidos/itens/${itemId}/separado`, { separado: value });
    setItens(prev => prev.map(i => i.id === itemId ? { ...i, separado: value } : i));
  }, []);

  // ── Try to match a scanned/typed SKU ──────────────────────────────────────────

  const handleSku = useCallback(async (raw: string) => {
    const sku = raw.trim().toUpperCase();
    if (!sku) return;

    // Find first unseparated item with matching SKU
    const item = itens.find(i => !i.separado && i.sku?.toUpperCase() === sku);
    if (item) {
      beep(true); vibrate(true);
      setFlash('ok'); setFlashMsg(`✓ ${item.nome_produto}`);
      await markSeparado(item.id, true);
    } else {
      // Already separated?
      const done = itens.find(i => i.separado && i.sku?.toUpperCase() === sku);
      if (done) {
        setFlash('err'); setFlashMsg('Já separado');
      } else {
        beep(false); vibrate(false);
        setFlash('err'); setFlashMsg(`SKU não encontrado: ${sku}`);
      }
    }
    setTimeout(() => setFlash(null), 1800);
  }, [itens, markSeparado]);

  // ── Camera / BarcodeDetector loop ─────────────────────────────────────────────

  const startCamera = useCallback(async () => {
    setCamErr('');
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: 'environment' },
      });
      streamRef.current = stream;
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        await videoRef.current.play();
      }

      // Init detector
      if ('BarcodeDetector' in window) {
        detectorRef.current = new BarcodeDetector({ formats: ['ean_13', 'ean_8', 'code_128', 'code_39', 'qr_code'] });
      }

      setCamOn(true);
      scanningRef.current = true;

      // Scan loop
      const loop = async () => {
        if (!scanningRef.current) return;
        if (detectorRef.current && videoRef.current && videoRef.current.readyState >= 2) {
          try {
            const results = await detectorRef.current.detect(videoRef.current);
            if (results.length > 0) {
              const code = results[0].rawValue;
              scanningRef.current = false;
              await handleSku(code);
              // Resume after flash
              setTimeout(() => { scanningRef.current = true; requestAnimationFrame(loop); }, 1900);
              return;
            }
          } catch {}
        }
        requestAnimationFrame(loop);
      };
      requestAnimationFrame(loop);
    } catch (err: any) {
      setCamErr(err?.message || 'Câmera indisponível');
    }
  }, [handleSku]);

  const stopCamera = useCallback(() => {
    scanningRef.current = false;
    streamRef.current?.getTracks().forEach(t => t.stop());
    streamRef.current = null;
    setCamOn(false);
  }, []);

  useEffect(() => () => { scanningRef.current = false; streamRef.current?.getTracks().forEach(t => t.stop()); }, []);

  // ── Manual submit ──────────────────────────────────────────────────────────────

  async function submitManual(e: React.FormEvent) {
    e.preventDefault();
    await handleSku(manual);
    setManual('');
  }

  return (
    <div className="flex flex-col min-h-screen bg-slate-950">
      {/* Header */}
      <div className="flex items-center gap-3 px-4 py-4 border-b border-white/5">
        <button onClick={onBack} className="text-slate-400 hover:text-white transition-colors">
          <ChevronLeft size={22} />
        </button>
        <div className="flex-1 min-w-0">
          <p className="text-white font-black text-sm truncate">
            {pedido.protocolo || `Pedido #${pedido.id}`}
          </p>
          <p className="text-slate-500 text-xs truncate">{pedido.cliente_nome}</p>
        </div>
        {/* Progress */}
        <div className="text-right shrink-0">
          <p className="text-sm font-black" style={{ color: done ? '#10b981' : '#f59e0b' }}>
            {separated}/{total}
          </p>
          <p className="text-[10px] text-slate-500">itens</p>
        </div>
      </div>

      {/* Progress bar */}
      <div className="h-1 bg-slate-800">
        <div
          className="h-1 transition-all duration-500"
          style={{
            width: total > 0 ? `${(separated / total) * 100}%` : '0%',
            background: done ? '#10b981' : '#f59e0b',
          }}
        />
      </div>

      {/* Flash feedback */}
      {flash && (
        <div className={`mx-4 mt-4 px-4 py-3 rounded-2xl flex items-center gap-2 text-sm font-bold transition-all ${
          flash === 'ok'
            ? 'bg-emerald-500/10 border border-emerald-500/30 text-emerald-400'
            : 'bg-rose-500/10 border border-rose-500/30 text-rose-400'
        }`}>
          {flash === 'ok' ? <CheckCircle2 size={18} /> : <AlertTriangle size={18} />}
          {flashMsg}
        </div>
      )}

      {/* Camera view */}
      <div className="relative mx-4 mt-4 rounded-2xl overflow-hidden bg-slate-900 border border-white/10" style={{ height: 220 }}>
        <video
          ref={videoRef}
          className="w-full h-full object-cover"
          playsInline
          muted
          style={{ display: camOn ? 'block' : 'none' }}
        />
        {!camOn && (
          <div className="absolute inset-0 flex flex-col items-center justify-center gap-2 text-slate-500">
            {camErr
              ? <><CameraOff size={32} /><p className="text-xs text-center px-4">{camErr}</p></>
              : <><Camera size={32} /><p className="text-xs">Toque para ativar a câmera</p></>
            }
          </div>
        )}
        {camOn && (
          /* Viewfinder overlay */
          <div className="absolute inset-0 pointer-events-none flex items-center justify-center">
            <div className="w-48 h-24 border-2 border-amber-400/60 rounded-lg" />
          </div>
        )}
        {/* Camera toggle */}
        <button
          onClick={camOn ? stopCamera : startCamera}
          className={`absolute bottom-3 right-3 p-2 rounded-xl text-sm font-bold transition-all ${
            camOn ? 'bg-rose-500/20 text-rose-400' : 'bg-amber-500/20 text-amber-400'
          }`}
        >
          {camOn ? <CameraOff size={18} /> : <Camera size={18} />}
        </button>
      </div>

      {/* Manual SKU input */}
      <form onSubmit={submitManual} className="mx-4 mt-3 flex gap-2">
        <div className="flex-1 flex items-center bg-slate-900 border border-white/10 rounded-xl px-3 gap-2">
          <Search size={16} className="text-slate-500 shrink-0" />
          <input
            type="text"
            value={manual}
            onChange={e => setManual(e.target.value)}
            placeholder="Digitar SKU manualmente…"
            className="flex-1 bg-transparent py-2.5 text-sm text-white placeholder-slate-600 focus:outline-none"
          />
        </div>
        <button type="submit"
          className="px-4 py-2.5 bg-amber-500 text-black rounded-xl font-black text-sm shrink-0">
          OK
        </button>
      </form>

      {/* Item list */}
      {done ? (
        <div className="flex flex-col items-center justify-center py-8 gap-2 text-emerald-400">
          <CheckCircle2 size={40} />
          <p className="font-black text-lg">Separação completa!</p>
          <p className="text-slate-500 text-sm">Todos os itens foram separados</p>
          <button onClick={onBack}
            className="mt-3 px-6 py-2 bg-emerald-500 text-black rounded-xl font-black text-sm">
            Voltar à lista
          </button>
        </div>
      ) : (
        <div className="flex-1 overflow-y-auto px-4 py-3 space-y-2">
          {itens.map(item => (
            <ItemCard
              key={item.id}
              item={item}
              onSeparado={(id, val) => markSeparado(id, val)}
              onAlerta={(id, alerta) =>
                setItens(prev => prev.map(i => i.id === id ? { ...i, ...alerta } : i))
              }
            />
          ))}
        </div>
      )}
    </div>
  );
}

// ─── Página principal ─────────────────────────────────────────────────────────

export default function SeparadorPage() {
  const [pedidos, setPedidos]   = useState<Pedido[]>([]);
  const [loading, setLoading]   = useState(true);
  const [selected, setSelected] = useState<Pedido | null>(null);
  const [loadingPed, setLoadingPed] = useState(false);

  async function load() {
    setLoading(true);
    try {
      const data = await api.get('/cotacoes/admin/pedidos', { params: { status: 'separacao', limit: 50 } }).then(r => r.data);
      setPedidos(Array.isArray(data) ? data : data.pedidos ?? []);
    } catch {}
    finally { setLoading(false); }
  }

  useEffect(() => { load(); }, []);

  async function openPedido(p: Pedido) {
    setLoadingPed(true);
    try {
      const data = await api.get(`/cotacoes/admin/pedidos/${p.id}`).then(r => r.data);
      setSelected(data);
    } catch { setSelected(p); }
    finally { setLoadingPed(false); }
  }

  if (selected) {
    return (
      <ScanScreen
        pedido={selected}
        onBack={() => { setSelected(null); load(); }}
      />
    );
  }

  return (
    <div className="max-w-lg mx-auto">
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-2xl font-black text-white flex items-center gap-2">
            <QrCode size={22} className="text-amber-400" /> Separador
          </h1>
          <p className="text-slate-400 text-sm mt-0.5">Pedidos aguardando separação</p>
        </div>
        <button onClick={load} disabled={loading}
          className="p-2 rounded-xl bg-slate-800 text-slate-400 hover:text-white transition-colors disabled:opacity-40">
          <RefreshCw size={16} className={loading ? 'animate-spin' : ''} />
        </button>
      </div>

      {/* Loading overlay */}
      {loadingPed && (
        <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50">
          <Loader2 size={36} className="animate-spin text-amber-400" />
        </div>
      )}

      {loading ? (
        <div className="flex items-center justify-center py-20">
          <Loader2 size={28} className="animate-spin text-amber-400" />
        </div>
      ) : pedidos.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-20 gap-3 text-slate-500">
          <Package size={40} />
          <p className="text-sm font-bold">Nenhum pedido em separação</p>
          <button onClick={load} className="text-xs text-amber-400 hover:text-amber-300">
            Atualizar
          </button>
        </div>
      ) : (
        <div className="space-y-3">
          {pedidos.map(p => (
            <PedidoCard key={p.id} pedido={p} onClick={() => openPedido(p)} />
          ))}
        </div>
      )}
    </div>
  );
}
