/* ============================================================
   Omnitok Analytics — Cobertura (fase 1 Monitor de Implementación)
   Funnel contratadas → implementación observada → con entregas
   últimas 24 h (corte FIJO rodante, independiente de umbrales) +
   tabla por retailer con motivo dominante. Datos: /impl/coverage.
   Cara a cliente (flag por cuenta); uso interno la ve siempre.
   ============================================================ */
const { useState:cvS, useEffect:cvE } = React;
const cvh = React.createElement;

const CV_REASON_LBL = (es)=>({
  out_of_scope: es?'Fuera del alcance contratado':'Out of contracted scope',
  no_script:    es?'El retailer no acepta el script':'Retailer does not accept the script',
  host_pending: es?'Host pendiente de homologar':'Host pending homologation',
  no_url:       es?'Sin URL detectada':'No URL detected',
  no_events:    es?'Sin entregas registradas':'No deliveries recorded',
});

function CoverageView({account, isAdmin}){
  const es = OA.lang==='es';
  const [data,setData]=cvS(null);
  const [err,setErr]=cvS(null);
  const [oosOpen,setOosOpen]=cvS(false);
  const [drawer,setDrawer]=cvS(null);   // host abierto en el detalle

  cvE(()=>{ let alive=true;
    setData(null); setErr(null); setDrawer(null);
    OA.implCoverage({account: account||'all', out_of_scope: oosOpen?1:null})
      .then(d=>{ if(alive) setData(d); })
      .catch(e=>{ if(alive) setErr(String(e&&e.message||e)); });
    return ()=>{ alive=false; };
  },[account,oosOpen]);

  if(err) return cvh('div',{className:'card'},cvh('div',{className:'empty'},err));
  if(!data) return cvh('div',{className:'card'},
    cvh('div',{className:'empty'},cvh('div',{className:'spinner'}),OA.t('loading')||'Cargando…'));

  const F=data.funnel||{}, S=data.scope||{}, R=data.retailers||[];
  const rl=CV_REASON_LBL(es);
  const configured = S.configured===true;
  const pct=(a,b)=> b>0?Math.round(a/Math.max(1,b)*100):0;
  const oos = data.out_of_scope||{};

  const stage=(label,small,v,p,color)=>cvh('div',{className:'fstage'},
    cvh('div',{className:'fl'},label,cvh('small',null,small)),
    cvh('div',{className:'fbar'},cvh('i',{style:{width:(p==null?100:Math.max(2,p))+'%',background:color}})),
    cvh('div',{className:'fv tnum'},OA.fmt(v),cvh('small',null,p==null?'100%':p+'%')));

  const kpi=(icon,tint,label,value,desc)=>cvh(Kpi,{icon,tint,label,value,desc});

  return cvh('div',null,
    /* ---- KPIs ---- */
    cvh('div',{className:'grid g-kpi',style:{marginBottom:16,gridTemplateColumns:'repeat(4,1fr)'}},
      kpi(Icon.box,{bg:'#EEF0FB',fg:'#4D4A9D'},es?'Fichas contratadas':'Contracted pages',OA.fmt(F.contracted||0),es?'Catálogo según Data Manager':'Catalog per Data Manager'),
      kpi(Icon.check,{bg:'#FFE6F1',fg:'#FF177B'},es?'Implementación observada':'Observed implementation',OA.fmt(F.observed||0),(es?'≥1 entrega registrada · ':'≥1 recorded delivery · ')+data.window_days+' d · '+pct(F.observed,F.contracted)+'%'),
      kpi(Icon.clock,{bg:'#E6F7F4',fg:'#14B8A6'},es?'Con entregas últimas 24 h':'With deliveries last 24 h',OA.fmt(F.delivered_24h||0),es?'corte fijo, independiente de umbrales':'fixed cut, threshold-independent'),
      kpi(Icon.store,{bg:'#FEF3DC',fg:'#D97706'},es?'Retailers':'Retailers',
        String(S.with_deliveries||0)+' / '+String(S.retailers||0),
        configured?(es?'con entregas · alcance contratado':'with deliveries · contracted scope')
                  :(es?'con entregas · observados (sin alcance configurado)':'with deliveries · observed (no scope configured)'))),

    /* ---- funnel ---- */
    cvh('div',{className:'card'},
      cvh('div',{className:'card-head'},
        cvh('div',null,
          cvh('div',{className:'card-title'},es?'Funnel de implementación':'Implementation funnel'),
          cvh('div',{className:'card-desc'},es?'Del catálogo contratado a la entrega efectiva de contenido · ventana '+data.window_days+' días':'From contracted catalog to effective content delivery · '+data.window_days+'-day window'))),
      cvh('div',{className:'funnel'},
        stage(es?'Fichas contratadas':'Contracted pages',es?'Catálogo Data Manager':'Data Manager catalog',F.contracted||0,null,'var(--primary)'),
        stage(es?'Implementación observada':'Observed implementation',(es?'≥1 entrega en ':'≥1 delivery in ')+data.window_days+' d',F.observed||0,pct(F.observed,F.contracted),'#7B77C9'),
        stage(es?'Con entregas últimas 24 h':'With deliveries last 24 h',es?'ventana rodante de 24 h':'rolling 24 h window',F.delivered_24h||0,pct(F.delivered_24h,F.contracted),'#14B8A6'))),

    /* ---- tabla por retailer ---- */
    cvh('div',{className:'card',style:{padding:0}},
      cvh('div',{style:{padding:'16px 18px 4px'}},
        cvh('div',{className:'card-title'},es?'Cobertura por retailer':'Coverage by retailer'),
        cvh('div',{className:'card-desc'},configured
          ?(es?'Retailers del alcance contratado (mantenedor). Los que aún no registran entregas aparecen destacados.':'Retailers in the contracted scope. Those without deliveries yet are highlighted.')
          :(es?'Retailers observados (alcance sin configurar: pídele al equipo Omnitok curar tu alcance para ver contratados sin entregas).':'Observed retailers (scope not configured yet).'))),
      cvh('div',{className:'tbl-wrap'},cvh('table',{className:'tbl'},
        cvh('thead',null,cvh('tr',null,
          cvh('th',null,'Retailer'),
          cvh('th',{className:'num',title:es?'Referencia = SKUs activos de la marca (90 d); Data Manager aún no entrega alcance contratado por retailer':'Reference = active brand SKUs (90 d)'},es?'SKUs activos ⓘ':'Active SKUs ⓘ'),
          cvh('th',{className:'num'},es?'Impl. observada':'Observed'),
          cvh('th',{className:'num'},es?'Entregas 24 h':'Deliveries 24 h'),
          cvh('th',null,es?'Cobertura':'Coverage'),
          cvh('th',null,es?'Motivo dominante':'Dominant reason'),
          cvh('th',null,''))),
        cvh('tbody',null, R.map(r=>{
          const never = r.status==='no_deliveries_yet';
          const ref = never ? (F.observed||0) : Math.max(r.observed, (F.observed||0));
          const wDel = pct(r.delivered_24h, ref), wObs = Math.max(0, pct(r.observed, ref)-wDel);
          return cvh('tr',{key:r.host,className:never?'cov-never':''},
            cvh('td',null,
              cvh('span',{className:'cov-rname'},r.name||r.host),
              r.country?cvh('span',{className:'cov-cc'},r.country):null,
              (configured&&r.in_scope)?cvh('span',{className:'cov-badge'},es?'Contratado':'Contracted'):null,
              cvh('div',{className:'cov-host'},r.host)),
            cvh('td',{className:'num'},never?'—':OA.fmt(ref)),
            cvh('td',{className:'num'},OA.fmt(r.observed)),
            cvh('td',{className:'num',style:r.observed>0&&r.delivered_24h===0?{color:'var(--sev-crit,#DC2626)',fontWeight:800}:null},OA.fmt(r.delivered_24h)),
            cvh('td',null,never
              ? cvh('span',{className:'cov-badge cov-badge-new'},es?'Sin entregas aún':'No deliveries yet')
              : cvh('div',{style:{display:'flex',alignItems:'center',gap:8}},
                  cvh('div',{className:'covbar',title:(es?'Con entregas 24 h: ':'24 h deliveries: ')+OA.fmt(r.delivered_24h)+' · '+(es?'observadas: ':'observed: ')+OA.fmt(r.observed)},
                    cvh('span',{className:'s1',style:{width:wDel+'%'}}),
                    cvh('span',{className:'s2',style:{width:wObs+'%'}})),
                  cvh('span',{className:'tnum',style:{fontSize:12,fontWeight:800}},pct(r.observed,ref)+'%'))),
            cvh('td',null,(r.top_reason&&(never||r.missing>0||r.top_reason.key==='no_url'))
              ? cvh('span',{className:'cov-motivo'},rl[r.top_reason.key]||r.top_reason.key,
                  r.top_reason.count?cvh('b',null,' ('+OA.fmt(r.top_reason.count)+')'):null)
              : null),
            cvh('td',null,never
              ? cvh('span',{style:{fontSize:12,fontWeight:700,color:'var(--accent,#FF177B)'}},es?'Coordinar activación':'Coordinate activation')
              : cvh('button',{className:'btn-ghost',style:{border:'none',background:'none',color:'#4D4A9D',fontWeight:800,cursor:'pointer',fontSize:12.5},
                  onClick:()=>setDrawer(r)},es?'Ver fichas →':'View pages →')));
        })))),
      cvh('div',{style:{padding:'6px 18px 14px',fontSize:11.5,color:'#737373'}},
        es?'ⓘ Referencia por tienda = SKUs activos de la marca (90 d), no un compromiso contractual. Cuando Data Manager entregue el alcance SKU×retailer, esta columna pasará a «Contratadas».'
          :'ⓘ Per-store reference = active brand SKUs (90 d), not a contractual commitment.')),

    /* ---- fuera de alcance (nunca suma a KPIs) ---- */
    configured&&cvh('div',{className:'card',style:{padding:'12px 18px'}},
      cvh('button',{className:'cov-toggle'+(oosOpen?' open':''),onClick:()=>setOosOpen(o=>!o)},
        cvh('span',{className:'car'},'▸'),' ',
        (es?'Retailers con entregas fuera del alcance':'Retailers with deliveries out of scope')+' ('+(oos.count||0)+') — '+(es?'no suman a tus indicadores':'not counted in your KPIs')),
      oosOpen&&(oos.retailers&&oos.retailers.length
        ? cvh('table',{className:'tbl',style:{marginTop:8}},cvh('tbody',null,oos.retailers.map(r=>cvh('tr',{key:r.host},
            cvh('td',null,cvh('span',{className:'cov-rname'},r.name||r.host),r.country?cvh('span',{className:'cov-cc'},r.country):null,
              cvh('span',{className:'cov-badge cov-badge-obs'},es?'Detectado · sin contrato':'Detected · no contract')),
            cvh('td',{className:'num'},OA.fmt(r.observed)+(es?' fichas':' pages')),
            cvh('td',{className:'num'},OA.fmt(r.views_win)+(es?' entregas '+data.window_days+' d':' deliveries'))))))
        : cvh('div',{className:'empty',style:{padding:14}},es?'Sin retailers fuera de alcance.':'None.'))),

    /* ---- nota metodológica ---- */
    cvh('div',{className:'note-bar',style:{marginTop:4}},
      cvh('b',null,es?'Nota metodológica: ':'Methodology: '),
      es?'una entrega se registra cuando el script de Omnitok identifica una ficha compatible y entrega contenido enriquecido. No representa una sesión, un usuario único, una interacción ni una venta. '
        :'a delivery is recorded when the Omnitok script identifies a compatible product page and serves enriched content. It does not represent a session, a unique user, an interaction, or a sale. ',
      configured?(es?'Cobertura calculada dentro del alcance configurado ('+S.retailers+' retailers). ':'Coverage computed within the configured scope. '):null,
      es?'Datos refrescados cada 2 h.':'Data refreshed every 2 h.'),

    /* ---- drawer detalle de retailer (SKUs desde /impl/matrix del par) ---- */
    drawer&&cvh(CoverageDrawer,{account,retailer:drawer,windowDays:data.window_days,isAdmin,onClose:()=>setDrawer(null)}));
}

/* Detalle por retailer: reusa /impl/matrix scoped al host (mismos datos del
   Monitor; sin endpoint nuevo). Muestra estado + URL verificada/inferida. */
function CoverageDrawer({account,retailer,windowDays,isAdmin,onClose}){
  const es=OA.lang==='es';
  const [rows,setRows]=cvS(null);
  cvE(()=>{ let alive=true;
    OA.impl('/impl/matrix',{account:account||'all',retailers:retailer.host,include:'present',per:200,sort:'views'})
      .then(d=>{ if(alive) setRows((d&&d.rows)||[]); })
      .catch(()=>{ if(alive) setRows([]); });
    return ()=>{ alive=false; };
  },[account,retailer.host]);
  const cell=(r)=> (r.cells&&r.cells[retailer.host])||null;
  return cvh('div',null,
    cvh('div',{className:'cov-scrim',onClick:onClose}),
    cvh('div',{className:'cov-drawer'},
      cvh('div',{className:'cov-dh'},
        cvh('div',{style:{minWidth:0}},
          cvh('div',{style:{fontSize:16,fontWeight:900}},retailer.name||retailer.host,
            retailer.country?cvh('span',{className:'cov-cc'},retailer.country):null),
          cvh('div',{style:{fontSize:12,color:'#737373',fontWeight:600}},retailer.host+' · '+
            OA.fmt(retailer.observed)+(es?' con implementación observada · ':' observed · ')+
            OA.fmt(retailer.delivered_24h)+(es?' con entregas 24 h':' with 24 h deliveries'))),
        cvh('button',{className:'btn',onClick:onClose},'× '+(es?'Cerrar':'Close'))),
      cvh('div',{className:'cov-db'},
        rows===null
          ? cvh('div',{className:'empty'},cvh('div',{className:'spinner'}),OA.t('loading')||'Cargando…')
          : cvh('table',{className:'tbl'},
              cvh('thead',null,cvh('tr',null,
                cvh('th',null,'SKU'),cvh('th',null,es?'Producto':'Product'),
                cvh('th',null,es?'Última entrega':'Last delivery'),cvh('th',null,'URL'))),
              cvh('tbody',null,rows.filter(r=>cell(r)).slice(0,120).map(r=>{ const c=cell(r);
                return cvh('tr',{key:r.sku_key},
                  cvh('td',{className:'mono',style:{fontFamily:'ui-monospace,Menlo,monospace',fontSize:12}},r.sku),
                  cvh('td',null,cvh('span',{style:{fontWeight:700}},r.name)),
                  cvh('td',null,(c.hours!=null&&c.hours<24)
                    ? cvh('span',{style:{color:'#12A150',fontWeight:800}},c.hours+' h')
                    : cvh('span',null,Math.floor((c.hours||0)/24)+' d')),
                  cvh('td',null,
                    c.url?cvh('a',{href:c.url,target:'_blank',rel:'noopener',style:{fontWeight:800,color:'#4D4A9D',textDecoration:'none'}},'↗')
                      :c.url_inferred?cvh('a',{href:c.url_inferred,target:'_blank',rel:'noopener',
                        title:es?'URL INFERIDA por nombre (no verificada)':'INFERRED URL (unverified)',
                        style:{fontWeight:800,color:'#D97706',textDecoration:'none',borderBottom:'1px dashed #D97706'}},'≈↗')
                      :cvh('span',{style:{color:'#A3A3A3',fontSize:11.5}},es?'sin URL':'no URL')));
              }))),
        isAdmin&&cvh('div',{style:{marginTop:12,fontSize:12,color:'#737373'}},
          es?'Detalle operativo (severidades, alertas, diagnóstico) en el Monitor de Implementación.':'Operational detail lives in the Implementation Monitor.'))));
}
window.CoverageView=CoverageView;
