// js/components/widgets/CampaignModal.jsx
// Modal de Bulk Reativação — fluxo enfileirado (1 cliente por vez).
// Criado em 2026-05-05 (sistema 4 onda 4a).
// [Wave 40 v224.21 NUCLEAR EXTRACT 2026-05-24] 383L -> ~190L (-50%) · 15ª replicação NUCLEAR · MILESTONE WAVE 40
// Padrão NUCLEAR mixed multi-step state machine (Wave 26 Vendas calibrado · 3 steps + overlay)
//
// Props:
//   selectedClients: array de clientes selecionados (max 25)
//   sales, quotes, products: arrays do app
//   user: usuário logado
//   health: clientHealthMap (Map<id, healthData>) opcional
//   onClose: callback fechar
//
// Fluxo:
//   1) Vendedora escolhe 1 template da lista
//   2) Sistema mostra preview do PRIMEIRO cliente da fila
//   3) Vendedora ajusta texto se quiser, clica "Abrir WhatsApp"
//   4) Tab abre wa.me/55XXX?text=...
//   5) Vendedora envia, volta, clica "Marcar enviado + próximo"
//   6) Sistema registra em client_outreach + avança fila
//   7) Quando termina, fecha modal e mostra resumo
//
// Deps runtime: Modal, Icon, MESSAGE_TEMPLATES, buildTemplateContext, applyTemplate,
//               getTemplatesForRole, sb, toast, ApprovalRequestModal (globals)
// Deps Wave 40: ZNX.lib['campaign-modal'].calcs + ZNX.widgets['campaign-modal'].{
//   CampaignStepPickTemplate, CampaignStepQueue, CampaignStepDone}
(function() {
  'use strict';
  const {useState, useMemo, useEffect} = React;

  // [Wave 40 v224.21 + v224.55 2026-05-28] vars+check MOVED to component body (preventivo)
  // regra_validacao_helpers_runtime_quando_ordem_scripts_uncertain

function CampaignModal({selectedClients, sales, quotes, products, user, health, todayOutreachMap, todaySentByMe, maxBulk, onClose, presetApproval}){
  // [v224.55 FIX-PREV-9 2026-05-28] vars+check em render time
  const cmW = (window.ZNX && window.ZNX.widgets && window.ZNX.widgets['campaign-modal']) || {};
  const cmCalcs = window.ZNX && window.ZNX.lib && window.ZNX.lib['campaign-modal'] && window.ZNX.lib['campaign-modal'].calcs;
  if(!cmCalcs || !cmW.CampaignStepPickTemplate || !cmW.CampaignStepQueue || !cmW.CampaignStepDone){
    const _msg = '[CampaignModal v224.21 wave40] deps faltando: calcs='+!!cmCalcs+', CampaignStepPickTemplate='+!!cmW.CampaignStepPickTemplate+', CampaignStepQueue='+!!cmW.CampaignStepQueue+', CampaignStepDone='+!!cmW.CampaignStepDone;
    console.error(_msg);
    if(window.Sentry && typeof window.Sentry.captureMessage === 'function') window.Sentry.captureMessage(_msg, 'error');
  }
  const role = user?.role || 'vendedor';
  // [Onda 4b] Vendedora vê TODOS templates (livres + restritos), mas restritos abrem flow de aprovação.
  // Admin/financeiro continua vendo todos com badge.
  const availableTemplates = useMemo(()=>{
    if(typeof MESSAGE_TEMPLATES==='undefined')return[];
    return MESSAGE_TEMPLATES;
  },[]);
  // [Onda 4b] Modal de pedido de aprovação
  const[approvalRequestOpen,setApprovalRequestOpen]=useState(false);
  const MAX = maxBulk || 25;
  const sentToday = todaySentByMe || 0;
  const remaining = Math.max(0, MAX - sentToday);
  const outreachMap = todayOutreachMap || new Map();
  // [Wave 40 v224.21] filterEligibleClients via lib (era inline L42-45)
  const filteredClients = useMemo(
    () => cmCalcs.filterEligibleClients(selectedClients, outreachMap, remaining),
    [selectedClients, outreachMap, remaining]
  );
  const skippedDupes = selectedClients.length - filteredClients.length;

  // Estado: 'pick_template' | 'queue' | 'done'
  const[step,setStep]=useState('pick_template');
  const[selectedTemplateId,setSelectedTemplateId]=useState(null);
  const[customText,setCustomText]=useState('');
  const[currentIdx,setCurrentIdx]=useState(0);
  const[messageOverride,setMessageOverride]=useState(''); // texto editável pelo cliente atual
  const[results,setResults]=useState([]); // {clientId, status: 'sent'|'skipped'|'no_phone'}
  const[loading,setLoading]=useState(false);

  const selectedTemplate = useMemo(()=>availableTemplates.find(t=>t.id===selectedTemplateId),[selectedTemplateId,availableTemplates]);
  const currentClient = filteredClients[currentIdx];

  // Constrói preview pra cliente atual quando muda (PRESERVED LITERAL · buildTemplateContext + applyTemplate cadeia global)
  useEffect(()=>{
    if(step!=='queue'||!currentClient||!selectedTemplate)return;
    const ctx = buildTemplateContext(currentClient,sales,quotes,products,user);
    const txt = applyTemplate(selectedTemplate,ctx,customText);
    setMessageOverride(txt||'');
  },[step,currentIdx,selectedTemplate,customText,currentClient]);

  function pickTemplate(t){
    setSelectedTemplateId(t.id);
  }

  function startQueue(){
    if(!selectedTemplateId){toast('⚠ Escolha um template');return;}
    if(selectedTemplate.id==='custom'&&!customText.trim()){toast('⚠ Digite a mensagem personalizada');return;}
    // [Onda 4b] Template restrito: vendedora pede aprovação ao invés de disparar direto.
    // Admin/financeiro pode disparar direto (eles aprovam pra si próprios = autorização implícita).
    const isRestricted = selectedTemplate.requires_approval;
    const isAdminFin = role === 'admin' || role === 'financeiro';
    const hasPresetApproval = presetApproval && presetApproval.templateId === selectedTemplate.id;
    if(isRestricted && !isAdminFin && !hasPresetApproval){
      setApprovalRequestOpen(true);
      return;
    }
    setCurrentIdx(0);
    setResults([]);
    setStep('queue');
  }

  // [Wave 40 v224.21] openWhatsApp REMOVIDO — era dead code no original (render L324 usa inline <a href=...>)
  // Função estava definida (L95-105 do original) mas nunca chamada. Cleanup safe pra trazer shrink dentro range.

  async function markSentAndNext(){
    if(!currentClient){return;}
    setLoading(true);
    try {
      // INSERT em client_outreach
      const {error} = await sb.from('client_outreach').insert({
        client_id: currentClient.id,
        vendedora_name: user?.name || 'sistema',
        template_id: selectedTemplate.id,
        message_sent: messageOverride,
        created_by_id: user?.id || null
      });
      // [BUG-FIX 20260506] swallowed error — ANTES: erro logado mas avançava marcando 'sent' falso.
      // Vendedora achava que registrou 4 disparos, banco tinha 0. Caso real Ana Carolina + Mohamed.
      // AGORA: aborta, mostra erro visivel, NAO avança — vendedora re-tenta o mesmo cliente.
      if(error){
        console.warn('[ZNX] outreach insert failed:',error.message);
        if(typeof Sentry!=='undefined')Sentry.captureException(new Error(error.message),{extra:{context:'outreach_insert',clientId:currentClient.id}});
        toast('❌ Falha ao registrar disparo: '+(error.message||'erro desconhecido')+' — tente de novo','error');
        setResults(prev=>[...prev,{clientId:currentClient.id,name:currentClient.name,status:'error',errorMsg:error.message}]);
        setLoading(false);
        return; // NÃO avança
      }
      // [Onda 4b] Se está usando aprovação, marca como used no primeiro dispatch
      if(presetApproval?.requestId && results.length===0){
        sb.from('template_approval_requests').update({status:'used',used_at:new Date().toISOString()}).eq('id',presetApproval.requestId)
          .then(({error:upErr})=>{if(upErr)console.warn('[ZNX] approval used_at fail:',upErr.message);})
          .catch(e=>console.warn('[ZNX] approval used_at exc:',e.message));
      }
      setResults(prev=>[...prev,{clientId:currentClient.id,name:currentClient.name,status:'sent'}]);
      advance();
    } catch(e){
      toast('❌ Erro ao registrar: '+(e?.message||'desconhecido')+' — re-tente','error');
      if(typeof Sentry!=='undefined')Sentry.captureException(e,{extra:{context:'campaign_markSent'}});
      setResults(prev=>[...prev,{clientId:currentClient.id,name:currentClient.name,status:'error',errorMsg:e?.message}]);
      // NÃO avança em caso de erro — vendedora re-tenta
    } finally {
      setLoading(false);
    }
  }

  function registerSkipped(reason){
    setResults(prev=>[...prev,{clientId:currentClient.id,name:currentClient.name,status:reason}]);
    advance();
  }

  function advance(){
    if(currentIdx+1>=filteredClients.length){
      setStep('done');
    } else {
      setCurrentIdx(idx=>idx+1);
    }
  }

  function back(){
    if(currentIdx>0)setCurrentIdx(idx=>idx-1);
  }

  // ═════════════ APPROVAL REQUEST OVERLAY (Onda 4b) ═════════════
  if(approvalRequestOpen && selectedTemplate){
    return(
      <ApprovalRequestModal
        template={selectedTemplate}
        selectedClients={filteredClients}
        user={user}
        onClose={()=>{setApprovalRequestOpen(false);}}
        onSubmitted={()=>{setApprovalRequestOpen(false);onClose();}}
      />
    );
  }

  // ═════════════ STEP 1: PICK TEMPLATE (extracted → CampaignStepPickTemplate) ═════════════
  if(step==='pick_template'){
    return cmW.CampaignStepPickTemplate ? (
      <cmW.CampaignStepPickTemplate
        filteredClients={filteredClients}
        selectedClients={selectedClients}
        availableTemplates={availableTemplates}
        selectedTemplateId={selectedTemplateId}
        selectedTemplate={selectedTemplate}
        customText={customText} setCustomText={setCustomText}
        onPickTemplate={pickTemplate} onStart={startQueue} onClose={onClose}
        role={role} sentToday={sentToday} MAX={MAX} remaining={remaining} skippedDupes={skippedDupes}
        presetApproval={presetApproval}
      />
    ) : null;
  }

  // ═════════════ STEP 2: QUEUE (extracted → CampaignStepQueue) ═════════════
  if(step==='queue'){
    const phone = cmCalcs.getPhone(currentClient);
    return cmW.CampaignStepQueue ? (
      <cmW.CampaignStepQueue
        currentIdx={currentIdx} filteredClients={filteredClients} currentClient={currentClient}
        messageOverride={messageOverride} setMessageOverride={setMessageOverride}
        health={health} phone={phone} loading={loading}
        onBack={back} onSkip={()=>registerSkipped(cmCalcs.getPhone(currentClient) ? 'skipped' : 'no_phone')}
        onMarkSent={markSentAndNext} onClose={onClose} onForceDone={()=>setStep('done')}
        results={results} sentToday={sentToday} MAX={MAX}
      />
    ) : null;
  }

  // ═════════════ STEP 3: DONE (extracted → CampaignStepDone) ═════════════
  return cmW.CampaignStepDone ? (
    <cmW.CampaignStepDone results={results} onClose={onClose} calcResultStats={cmCalcs.calcResultStats}/>
  ) : null;
}

  // Namespace
  window.ZNX = window.ZNX || {};
  window.ZNX.widgets = window.ZNX.widgets || {};
  window.ZNX.widgets.CampaignModal = CampaignModal;
  window.CampaignModal = CampaignModal;
  // [Wave 40 marker v224.21] confirma extract executado · MILESTONE WAVE 40
  window.CampaignModal_v224_21_wave40 = true;
})();
