// js/components/common/OfflineQueueModal.jsx
// ════════════════════════════════════════════════════════════════════════════
// RG7 PWA Offline Queue — Modal lista de itens enfileirados (v218.16 ONDA-N3)
// ════════════════════════════════════════════════════════════════════════════
// Lista TODOS items da queue (pending+syncing+failed+done).
// Ações: Sincronizar agora (drainNow), Tentar de novo (per-item via markPending).
//
// Regras aplicadas:
//   - regra_state_id_vs_objeto (state guarda IDs, items são fetched fresh)
//   - regra_loading_state_obrigatorio (botões disabled durante drain)
// ════════════════════════════════════════════════════════════════════════════

(function(){
  'use strict';
  const { useState, useEffect, useCallback } = React;

  function OfflineQueueModal({ isOpen, onClose }){
    const [items, setItems] = useState([]);
    const [draining, setDraining] = useState(false);
    const [loading, setLoading] = useState(false);

    const refresh = useCallback(async () => {
      if(!window.znxOfflineQueue) { setItems([]); return; }
      setLoading(true);
      try{
        const all = await window.znxOfflineQueue.list(null); // todos status
        // Ordena: pending+syncing+failed primeiro (recentes), done depois
        const order = { pending:0, syncing:1, failed:2, done:3 };
        all.sort((a,b)=>{
          const oa = order[a.status]||9, ob = order[b.status]||9;
          if(oa !== ob) return oa - ob;
          return new Date(b.created_at) - new Date(a.created_at);
        });
        setItems(all);
      }catch(_){ setItems([]); }
      finally{ setLoading(false); }
    }, []);

    useEffect(() => { if(isOpen) refresh(); }, [isOpen, refresh]);

    const handleDrainNow = async () => {
      if(!window.znxOfflineDrainer) return;
      setDraining(true);
      try{
        const result = await window.znxOfflineDrainer.drainNow();
        if(typeof window.toast === 'function'){
          if(result.done > 0) window.toast('✅ '+result.done+' sincronizados', 'success');
          else if(result.reason === 'offline') window.toast('🔌 Ainda offline', 'warning');
          else if(result.processed === 0) window.toast('Nada pra sincronizar', 'info');
        }
        await refresh();
      }catch(e){
        if(typeof window.toast === 'function') window.toast('❌ Erro ao sincronizar: '+(e?.message||'unknown'), 'error');
      }finally{
        setDraining(false);
      }
    };

    // [v224.60] Descartar item individual (admin manual)
    const handleDiscard = async (itemId) => {
      if(!window.znxOfflineQueue?.discardItem) return;
      if(!window.confirm('Descartar este item da fila? Esta ação é permanente.')) return;
      try{
        await window.znxOfflineQueue.discardItem(itemId);
        if(typeof window.toast === 'function') window.toast('🗑 Item descartado', 'info');
        await refresh();
      }catch(e){
        if(typeof window.toast === 'function') window.toast('❌ Erro ao descartar: '+(e?.message||'unknown'), 'error');
      }
    };

    if(!isOpen) return null;

    const fmt = (iso) => {
      if(!iso) return '—';
      try{ return new Date(iso).toLocaleString('pt-BR', { hour:'2-digit', minute:'2-digit', day:'2-digit', month:'2-digit' }); }
      catch(_){ return iso; }
    };

    const statusColor = (s) => ({
      pending:'#FCD34D', syncing:'#60A5FA', failed:'#F87171', done:'#34D399', dead:'#6B7280'
    })[s] || '#9CA3AF';

    return React.createElement('div', {
      onClick: (e) => {
        e.stopPropagation();
        if(e.target === e.currentTarget && onClose) onClose();
      },
      // [v218.29 HOTFIX 2026-05-13] zIndex 9999→100001 (acima do toast container 99999).
      // Antes: toast em cima do overlay → cliques no overlay/botões NÃO funcionavam → modal "travado".
      // Reportado por Jamal no smoke E2E ONDA-P.
      style: {
        position:'fixed', inset:0, background:'rgba(0,0,0,0.6)', zIndex:100001,
        display:'flex', alignItems:'center', justifyContent:'center', padding:16
      }
    },
      React.createElement('div', {
        style: {
          background:'#1B2A4A', color:'#FFF', borderRadius:12, maxWidth:640, width:'100%',
          maxHeight:'80vh', display:'flex', flexDirection:'column', boxShadow:'0 20px 60px rgba(0,0,0,0.5)'
        }
      },
        // Header
        React.createElement('div', {
          style: { padding:'16px 20px', borderBottom:'1px solid #FFFFFF15', display:'flex', alignItems:'center', justifyContent:'space-between' }
        },
          React.createElement('div', null,
            React.createElement('div', { style:{fontSize:14, fontWeight:700} }, '📤 Fila Offline'),
            React.createElement('div', { style:{fontSize:11, color:'#9CA3AF', marginTop:2} }, items.length+' itens · '+items.filter(i=>i.status==='pending').length+' pendente · '+items.filter(i=>i.status==='failed').length+' falhou')
          ),
          React.createElement('button', {
            // [v218.29] stopPropagation explícito + onMouseDown como fallback se onClick falhar
            onClick: (e) => { e.stopPropagation(); if(onClose) onClose(); },
            onMouseDown: (e) => e.stopPropagation(),
            style: { background:'transparent', border:'none', color:'#FFF', fontSize:24, cursor:'pointer', padding:'4px 12px', minWidth:40, minHeight:40 }
          }, '×')
        ),
        // Body
        React.createElement('div', {
          style: { padding:'12px 20px', overflowY:'auto', flex:1 }
        },
          loading
            ? React.createElement('div', { style:{textAlign:'center', padding:32, color:'#9CA3AF'} }, 'Carregando...')
            : items.length === 0
              ? React.createElement('div', { style:{textAlign:'center', padding:32, color:'#9CA3AF'} }, 'Fila vazia ✨')
              : React.createElement('div', { style:{display:'flex', flexDirection:'column', gap:8} },
                  items.map(it => React.createElement('div', {
                    key: it.id,
                    style: {
                      padding:'10px 12px', background:'#FFFFFF08', borderRadius:8,
                      borderLeft:'3px solid '+statusColor(it.status), display:'flex',
                      justifyContent:'space-between', alignItems:'center', gap:12
                    }
                  },
                    React.createElement('div', { style:{flex:1, minWidth:0} },
                      React.createElement('div', { style:{fontSize:13, fontWeight:600, marginBottom:2} }, it.rpc_name),
                      React.createElement('div', { style:{fontSize:11, color:'#9CA3AF'} },
                        'Criado: ' + fmt(it.created_at) +
                        (it.last_retry_at ? ' · Última tentativa: ' + fmt(it.last_retry_at) : '') +
                        (it.retries > 0 ? ' · ' + it.retries + ' tentativas' : '')
                      ),
                      it.last_error && React.createElement('div', { style:{fontSize:11, color:'#F87171', marginTop:4, fontFamily:'monospace', wordBreak:'break-all'} }, it.last_error.slice(0,200))
                    ),
                    React.createElement('div', {style:{display:'flex',gap:6,alignItems:'center',whiteSpace:'nowrap'}},
                      React.createElement('div', {
                        style: {
                          fontSize:11, fontWeight:700, padding:'4px 8px', borderRadius:6,
                          background: statusColor(it.status) + '22', color: statusColor(it.status),
                          textTransform:'uppercase'
                        }
                      }, it.status),
                      // [v224.60] Botão Descartar pra failed/dead · admin remove manualmente
                      (it.status === 'failed' || it.status === 'dead') && React.createElement('button', {
                        onClick: (e) => { e.stopPropagation(); handleDiscard(it.id); },
                        title: 'Descartar este item (permanente)',
                        style: {
                          background:'transparent', border:'1px solid #F8717155',
                          color:'#F87171', borderRadius:6, padding:'4px 8px',
                          cursor:'pointer', fontSize:11, fontWeight:600
                        }
                      }, '🗑 Descartar')
                    )
                  ))
                )
        ),
        // Footer
        React.createElement('div', {
          style: { padding:'12px 20px', borderTop:'1px solid #FFFFFF15', display:'flex', gap:8, justifyContent:'flex-end' }
        },
          React.createElement('button', {
            onClick: refresh,
            disabled: loading || draining,
            style: {
              padding:'8px 14px', background:'transparent', border:'1px solid #FFFFFF22',
              color:'#FFF', borderRadius:8, cursor: (loading||draining)?'not-allowed':'pointer',
              fontSize:12, opacity: (loading||draining)?0.5:1
            }
          }, '🔄 Recarregar'),
          React.createElement('button', {
            onClick: handleDrainNow,
            disabled: draining || items.filter(i=>i.status==='pending').length === 0,
            style: {
              padding:'8px 14px', background:'#B89840', border:'none',
              color:'#FFF', borderRadius:8, fontWeight:700,
              cursor: draining?'not-allowed':'pointer', fontSize:12,
              opacity: (draining || items.filter(i=>i.status==='pending').length===0) ? 0.5 : 1
            }
          }, draining ? '⏳ Sincronizando...' : '📤 Sincronizar agora')
        )
      )
    );
  }

  window.OfflineQueueModal = OfflineQueueModal;
})();
