/* ============================================================
   Omnitok Analytics — Alcance del cliente (fase 1 Monitor)
   Sección del mantenedor: qué retailers CONTRATADOS cuentan para
   la vista Cobertura de cada cuenta + flag de exposición a cliente
   + accepts_script por retail. Solo retails homologados y visibles
   son seleccionables (los pending primero se homologan).
   Datos: GET/PUT /admin/client-scope (X-API-Key) + /impl/coverage.
   ============================================================ */
const { useState:sS, useEffect:sE } = React;
const sh = React.createElement;

function csPitch(brand, r, cov, es){
  const name = r.name || r.host;
  const obs = OA.fmt(r.observed), miss = OA.fmt(r.missing);
  const tot = OA.fmt((cov&&cov.funnel&&cov.funnel.observed)||0);
  return es
    ? 'Hola equipo '+name+' — según Omnitok Analytics, del catálogo activo de '+brand+' ('+tot+' SKUs con contenido enriquecido), '+obs+' fichas ya registran entregas en su sitio. Nos encantaría coordinar la activación de las '+miss+' restantes: el contenido ya está producido y aprobado, solo falta habilitarlo en esas páginas. ¿Agendamos?'
    : 'Hi '+name+' team — per Omnitok Analytics, out of '+brand+'’s active catalog ('+tot+' SKUs with enriched content), '+obs+' pages already record deliveries on your site. We’d love to coordinate activating the remaining '+miss+': the content is produced and approved. Shall we schedule?';
}

function ClientScopeSection({onErr}){
  const es = OA.lang==='es';
  const inp={padding:'8px 11px',border:'1px solid #E5E5E5',borderRadius:8,fontSize:13,boxSizing:'border-box'};
  const [account,setAccount]=sS('');
  const [retails,setRetails]=sS(null);   // filas homologadas visibles del mantenedor
  const [pendingN,setPendingN]=sS(0);
  const [sel,setSel]=sS(new Set());      // hosts en el alcance (edición local)
  const [savedSel,setSavedSel]=sS(new Set());
  const [flag,setFlag]=sS(false); const [savedFlag,setSavedFlag]=sS(false);
  const [loadingScope,setLoadingScope]=sS(false);
  const [saving,setSaving]=sS(false); const [savedMsg,setSavedMsg]=sS('');
  const [q,setQ]=sS('');
  const [cov,setCov]=sS(null);           // /impl/coverage de la cuenta (potencial referencial)
  const [pitchHost,setPitchHost]=sS('');
  const [copied,setCopied]=sS(false);
  const [busyAs,setBusyAs]=sS('');       // host guardando accepts_script

  sE(()=>{ OA.loadRetailsAdmin({filter:'named'}).then(r=>{
      setRetails((r.rows||[]).filter(x=>!x.hidden&&!x.pending));
    }).catch(e=>{ setRetails([]); onErr&&onErr(e); });
    OA.loadRetailsAdmin({filter:'pending'}).then(r=>setPendingN((r.rows||[]).length)).catch(()=>{});
  },[]);

  const loadScope=(acc)=>{ if(!acc){ return; }
    setLoadingScope(true); setSavedMsg(''); setCov(null);
    OA.clientScopeGet(acc).then(d=>{
      const s=new Set(d.hosts||[]); setSel(new Set(s)); setSavedSel(s);
      setFlag(!!d.coverage_client); setSavedFlag(!!d.coverage_client);
      setLoadingScope(false);
      OA.implCoverage({account:acc}).then(c=>{ setCov(c);
        const first=((c&&c.retailers)||[]).find(r=>r.missing>0);
        setPitchHost(first?first.host:'');
      }).catch(()=>{});
    }).catch(e=>{ setLoadingScope(false); onErr&&onErr(e); });
  };
  sE(()=>{ const t=setTimeout(()=>{ if(account.trim()) loadScope(account.trim()); },400);
    return ()=>clearTimeout(t); },[account]);

  const dirty = flag!==savedFlag || sel.size!==savedSel.size || [...sel].some(x=>!savedSel.has(x));
  const doSave=()=>{ if(!account.trim()) return;
    setSaving(true); setSavedMsg('');
    OA.clientScopePut(account.trim(),{hosts:[...sel],coverage_client:flag})
      .then(d=>{ setSaving(false);
        const s=new Set(d.hosts||[]); setSel(new Set(s)); setSavedSel(s);
        setFlag(!!d.coverage_client); setSavedFlag(!!d.coverage_client);
        setSavedMsg(es?('Alcance guardado: '+s.size+' retailers · Cobertura para el cliente: '+(d.coverage_client?'VISIBLE':'oculta')):('Saved: '+s.size+' retailers'));
        OA.implCoverage({account:account.trim()}).then(setCov).catch(()=>{});
      })
      .catch(e=>{ setSaving(false); onErr&&onErr(e); });
  };
  const setAccepts=(host,v)=>{ setBusyAs(host);
    OA.setRetail(host,{accepts_script:v})
      .then(()=>{ setBusyAs(''); setRetails(rs=>(rs||[]).map(r=>r.host===host?{...r,accepts_script:v}:r)); })
      .catch(e=>{ setBusyAs(''); onErr&&onErr(e); });
  };

  const shown=(retails||[]).filter(r=>{ if(!q) return true; const s=q.toLowerCase();
    return r.host.toLowerCase().includes(s)||String(r.name||'').toLowerCase().includes(s); });
  const brandOpts=(OA.brands||[]).map(b=>b.name).filter(Boolean);
  const covRet=((cov&&cov.retailers)||[]).filter(r=>r.missing>0&&r.observed>0);
  const pitchRow=covRet.find(r=>r.host===pitchHost)||covRet[0]||null;
  const potential=(cov&&cov.reference_potential)||null;

  return sh('div',null,
    sh('div',{className:'note-bar',style:{marginBottom:12}},sh(Icon.info,null),
      sh('span',null,es
        ?'El alcance define el denominador de la vista Cobertura del cliente y habilita la fila «sin entregas aún» (retailers contratados que jamás registraron eventos — hoy invisibles). Solo retails ya homologados son seleccionables'+(pendingN?(' ('+pendingN+' hosts pendientes de homologar en la pestaña Hostnames)'):'')+'. La cuenta cliente ve Cobertura solo con el interruptor activado.'
        :'The scope defines the denominator of the client Coverage view and enables the "no deliveries yet" row. Only homologated retails are selectable. Client accounts see Coverage only when the switch is on.')),

    sh('div',{style:{display:'flex',gap:10,alignItems:'center',flexWrap:'wrap',marginBottom:12}},
      sh('span',{className:'filt-label'},es?'Cuenta (marca)':'Account (brand)'),
      sh('input',{list:'oa-cscope-brands',value:account,onChange:e=>setAccount(e.target.value),
        placeholder:es?'p.ej. HP, Rosen…':'e.g. HP',style:{...inp,minWidth:200}}),
      sh('datalist',{id:'oa-cscope-brands'},brandOpts.map(n=>sh('option',{key:n,value:n}))),
      account.trim()&&sh('span',{style:{fontSize:12.5,fontWeight:800,color:'#4D4A9D'}},
        loadingScope?(es?'cargando…':'loading…'):(sel.size+(es?' retailers en el alcance':' retailers in scope'))),
      sh('span',{style:{flex:1}}),
      account.trim()&&sh('label',{style:{display:'flex',alignItems:'center',gap:7,fontSize:12.5,fontWeight:700,cursor:'pointer',
          color:flag?'#0E7490':'#737373'}},
        sh('input',{type:'checkbox',checked:flag,onChange:e=>setFlag(e.target.checked)}),
        es?'Cobertura visible para el cliente':'Coverage visible to client'),
      account.trim()&&sh('button',{onClick:doSave,disabled:!dirty||saving,
        style:{padding:'8px 14px',border:'1px solid #4D4A9D',borderRadius:8,fontSize:13,fontWeight:700,
          background:dirty?'#4D4A9D':'#F5F5F5',color:dirty?'#fff':'#A3A3A3',cursor:dirty?'pointer':'default'}},
        saving?(es?'Guardando…':'Saving…'):(dirty?(es?'Guardar alcance':'Save scope'):(es?'Guardado':'Saved')))),
    sh('div',{style:{fontSize:11.5,color:'#737373',fontWeight:600,margin:'-4px 0 10px'}},
      es?'Precarga desde Data Manager (canon_brand_retail) — próximamente':'Preload from Data Manager — coming soon'),
    savedMsg&&sh('div',{style:{padding:'8px 12px',background:'#F0FDF4',color:'#15803D',borderRadius:8,fontSize:13,marginBottom:10}},savedMsg),

    !account.trim()
      ? sh('div',{className:'card'},sh('div',{className:'empty'},es?'Elige una cuenta (marca) para configurar su alcance.':'Pick an account (brand) to configure its scope.'))
      : sh('div',null,
          sh('div',{style:{marginBottom:8}},
            sh('input',{placeholder:es?'Filtrar retailers…':'Filter retailers…',value:q,onChange:e=>setQ(e.target.value),style:{...inp,minWidth:240}})),
          sh('div',{className:'card',style:{padding:0}},
            retails===null
              ? sh('div',{className:'empty'},sh('div',{className:'spinner'}),OA.t('loading')||'Cargando…')
              : sh('table',{className:'tbl'},
                  sh('thead',null,sh('tr',null,
                    sh('th',{style:{width:90}},es?'En alcance':'In scope'),
                    sh('th',null,'Retailer'),
                    sh('th',{className:'num'},es?'Eventos 30d':'Events 30d'),
                    sh('th',null,es?'Acepta script':'Accepts script'))),
                  sh('tbody',null,shown.slice(0,400).map(r=>sh('tr',{key:r.host,
                      style:sel.has(r.host)?{background:'#F7F7FD'}:null},
                    sh('td',null,sh('input',{type:'checkbox',checked:sel.has(r.host),
                      onChange:()=>{ setSel(p=>{ const n=new Set(p); if(n.has(r.host)) n.delete(r.host); else n.add(r.host); return n; }); }})),
                    sh('td',null,
                      sh('span',{style:{fontWeight:800}},r.name||r.host),
                      r.country?sh('span',{className:'cov-cc'},r.country):null,
                      sh('div',{style:{fontSize:11,color:'#A3A3A3',fontWeight:600}},r.host)),
                    sh('td',{className:'num'},OA.fmtCompact(r.events_count||0)),
                    sh('td',null,
                      sh('select',{value:r.accepts_script||'unknown',disabled:busyAs===r.host,
                        onChange:e=>setAccepts(r.host,e.target.value),
                        title:es?'“No” genera el motivo «retailer no acepta el script» en Cobertura (auditado en el historial)':'"No" produces the "retailer does not accept the script" reason',
                        style:{...inp,padding:'5px 8px',fontSize:12,
                          color:r.accepts_script==='no'?'#B91C1C':(r.accepts_script==='yes'?'#0E7490':'#737373')}},
                        sh('option',{value:'unknown'},es?'desconocido':'unknown'),
                        sh('option',{value:'yes'},es?'sí':'yes'),
                        sh('option',{value:'no'},'no'))))))),
            shown.length>400&&sh('div',{style:{padding:'8px 14px',fontSize:12,color:'#737373'}},
              es?('Mostrando 400 de '+shown.length+' — usa el filtro para acotar.'):('Showing 400 of '+shown.length))),

          /* ---- potencial referencial + copiar argumento (SOLO admin/comercial) ---- */
          cov&&potential&&sh('div',{className:'card',style:{marginTop:14}},
            sh('div',{className:'card-head'},
              sh('div',null,
                sh('div',{className:'card-title'},(es?'Potencial referencial — ':'Reference potential — ')+account.trim(),
                  sh('span',{className:'cov-badge',style:{marginLeft:8}},es?'solo admin / comercial':'admin / sales only')),
                sh('div',{className:'card-desc'},es?'Herramienta de pitch: el cliente NO ve esta tarjeta.':'Pitch tool: clients never see this card.'))),
            sh('div',{style:{display:'flex',gap:22,alignItems:'flex-start',flexWrap:'wrap'}},
              sh('div',{style:{minWidth:210}},
                sh('div',{style:{fontSize:30,fontWeight:900,color:'#26243F'}},'~'+OA.fmtCompact(potential.value||0)),
                sh('div',{style:{fontSize:12,color:'#737373',fontWeight:700}},(es?'entregas de referencia · ':'reference deliveries · ')+potential.window_days+' d'),
                sh('div',{style:{fontSize:11.5,color:'#A3A3A3',marginTop:6,maxWidth:230}},
                  (es?'mediana ':'median ')+OA.fmt(potential.median_per_observed||0)+(es?' entregas/ficha × ':' deliveries/page × ')+OA.fmt(potential.missing_total||0)+(es?' por activar. No representa visitas incrementales ni ventas.':' to activate. Not incremental visits nor sales.'))),
              pitchRow&&sh('div',{style:{flex:1,minWidth:280}},
                sh('div',{style:{display:'flex',gap:8,alignItems:'center',marginBottom:6}},
                  sh('span',{className:'filt-label'},es?'Argumento para':'Pitch for'),
                  sh('select',{value:pitchRow.host,onChange:e=>setPitchHost(e.target.value),style:{...inp,padding:'6px 9px',fontSize:12.5}},
                    covRet.map(r=>sh('option',{key:r.host,value:r.host},(r.name||r.host)+' · '+OA.fmt(r.missing)+(es?' por activar':' to activate'))))),
                sh('textarea',{readOnly:true,value:csPitch(account.trim(),pitchRow,cov,es),
                  style:{...inp,width:'100%',minHeight:96,fontSize:12.5,lineHeight:1.5,resize:'vertical'}}),
                sh('button',{onClick:()=>{ const t=csPitch(account.trim(),pitchRow,cov,es);
                    if(navigator.clipboard&&navigator.clipboard.writeText) navigator.clipboard.writeText(t); else window.prompt('Copy:',t);
                    setCopied(true); setTimeout(()=>setCopied(false),1600); },
                  style:{marginTop:6,padding:'8px 14px',border:'1px solid #4D4A9D',borderRadius:8,fontSize:12.5,fontWeight:700,
                    background:copied?'#F0FDF4':'#4D4A9D',color:copied?'#15803D':'#fff',cursor:'pointer'}},
                  copied?(es?'Copiado ✓':'Copied ✓'):(es?'Copiar argumento':'Copy pitch')))))));
}
window.ClientScopeSection=ClientScopeSection;
