/* ============================================================
   Omnitok Analytics — CatalogView (mantenedor de catálogo)
   Corrige marca/categoría/nombre/estado de los SKUs del catálogo
   maestro (product_catalog). Los cambios son overrides manuales
   que sobreviven el refresh de 12h desde Mongo.
   ============================================================ */
const { useState:cS, useEffect:cE, useRef:cR } = React;

function CatalogView(){
  const es = OA.lang==='es';
  const [mode,setMode]=cS('brand');             // 'brand' | 'category' (dimensión maestra)
  const [facets,setFacets]=cS([]); const [fLoading,setFLoading]=cS(true);
  const [fq,setFq]=cS(''); const [fpage,setFpage]=cS(0);
  const [sel,setSel]=cS(null);                  // {id, skus}
  const [rows,setRows]=cS([]); const [total,setTotal]=cS(0); const [loading,setLoading]=cS(false);
  const [q,setQ]=cS(''); const [qLive,setQLive]=cS('');
  const [fOvr,setFOvr]=cS('');                  // '' | '1' (solo editados)
  const [page,setPage]=cS(0);
  const [checked,setChecked]=cS({});            // {sku_key: true}
  const [busy,setBusy]=cS('');
  const [edit,setEdit]=cS(null);                // fila en SlideOver
  const [ev,setEv]=cS({});                      // valores del editor
  const [bulkField,setBulkField]=cS('category');
  const [bulkVal,setBulkVal]=cS('');
  const [keyVal,setKeyVal]=cS(OA.adminKey());
  const [err,setErr]=cS('');
  const [applyState,setApplyState]=cS(null);    // job Iceberg
  const FP=12, PAGE=100;
  const seq=cR(0);

  const inp={padding:'8px 11px',border:'1px solid #E5E5E5',borderRadius:8,fontSize:13,boxSizing:'border-box'};
  const btn=(c,bg)=>({padding:'6px 11px',border:'1px solid '+c,color:c,background:bg||'#fff',borderRadius:8,fontSize:12,fontWeight:600,cursor:'pointer'});
  const RED='#B91C1C', GRN='#15803D', PUR='#4D4A9D';
  const pgBtn=(dis)=>({padding:'3px 9px',border:'1px solid #E5E5E5',borderRadius:6,background:dis?'#F5F5F5':'#fff',color:'#525252',cursor:dis?'default':'pointer'});
  const pager=(pg,pages,tot,setter)=> pages<=1 ? null : React.createElement('div',{style:{display:'flex',gap:8,alignItems:'center',justifyContent:'center',marginTop:10,fontSize:12,color:'#737373'}},
    React.createElement('button',{disabled:pg<=0,onClick:()=>setter(pg-1),style:pgBtn(pg<=0)},'‹'),
    React.createElement('span',null,(pg+1)+' / '+pages+(tot!=null?(' · '+tot):'')),
    React.createElement('button',{disabled:pg>=pages-1,onClick:()=>setter(pg+1),style:pgBtn(pg>=pages-1)},'›'));

  const wErr=(e)=> setErr(e&&e.status===401 ? (es?'X-API-Key inválida o no configurada (candado del encabezado).':'Invalid or missing X-API-Key (see header).')
    : e&&e.status===503 ? (es?'API key no configurada en el servidor.':'API key not configured on the server.')
    : String((e&&e.message)||e));

  // --- carga ---
  const loadFacets=()=>{ setFLoading(true);
    OA.loadCatalogFacets(mode,{limit:2000}).then(r=>{ setFacets(r.rows||[]); setFLoading(false); })
      .catch(()=>{ setFacets([]); setFLoading(false); }); };
  const loadRows=(s,opts)=>{ const o=opts||{};
    const hasQ=(o.q!=null?o.q:q); const target=(o.sel!==undefined?o.sel:sel);
    if(!target && !hasQ){ setRows([]); setTotal(0); return; }
    const my=++seq.current; setLoading(true);
    const params={limit:PAGE, offset:(o.page!=null?o.page:page)*PAGE};
    if(hasQ) params.q=hasQ;
    if(target){ if(mode==='brand') params.brand=target.id; else params.category=(target.id==='—'?'':target.id); }
    if((o.fOvr!=null?o.fOvr:fOvr)==='1') params.overridden=true;
    OA.loadCatalogProducts(params).then(r=>{ if(my!==seq.current) return;
      setRows(r.rows||[]); setTotal(r.total||0); setLoading(false); })
      .catch(()=>{ if(my===seq.current){ setRows([]); setTotal(0); setLoading(false); } }); };

  cE(()=>{ setSel(null); setRows([]); setTotal(0); setFq(''); setFpage(0); setQ(''); setQLive(''); setPage(0); setChecked({}); loadFacets(); },[mode]);
  cE(()=>{ const t=setTimeout(()=>{ if(qLive!==q){ setQ(qLive); setPage(0); loadRows(sel,{q:qLive,page:0}); } },350); return ()=>clearTimeout(t); },[qLive]);

  const selectEntity=(item)=>{ setSel(item); setPage(0); setChecked({}); loadRows(item,{page:0}); };
  const reload=()=>{ loadRows(sel); loadFacets(); };

  // --- escritura ---
  const saveEdit=()=>{ if(!edit) return;
    const set={}, clear=[];
    ['brand','category','name'].forEach(f=>{
      const v=(ev[f]||'').trim(); const cur=edit[f]||'';
      if(ev['rv_'+f]) clear.push(f);
      else if(v && v!==cur) set[f]=v;
    });
    if(ev.rv_state) clear.push('state');
    else if((ev.state?1:0)!==(edit.state?1:0)) set.state=ev.state?1:0;
    if(!Object.keys(set).length && !clear.length){ setEdit(null); return; }
    setBusy('save'); setErr('');
    OA.setCatalogProduct([edit.sku_key],set,clear,(ev.note||'').trim()||null)
      .then(()=>{ setBusy(''); setEdit(null); reload(); })
      .catch(e=>{ setBusy(''); wErr(e); }); };
  const bulk=()=>{ const keys=Object.keys(checked).filter(k=>checked[k]); const v=(bulkVal||'').trim();
    if(!keys.length||!v) return; setBusy('bulk'); setErr('');
    const chunks=[]; for(let i=0;i<keys.length;i+=1000) chunks.push(keys.slice(i,i+1000));
    (async()=>{ for(const c of chunks){ await OA.bulkCatalog(c,{[bulkField]:v},[],null); } })()
      .then(()=>{ setBusy(''); setChecked({}); setBulkVal(''); reload(); })
      .catch(e=>{ setBusy(''); wErr(e); }); };
  const applyIceberg=()=>{ setErr(''); setApplyState({running:true});
    OA.applyCatalogIceberg().then(()=>{
      const poll=()=>OA.applyCatalogIcebergStatus().then(st=>{
        if(st && st.running) setTimeout(poll,2500);
        else setApplyState(st?{running:false,result:st.result}:null); });
      setTimeout(poll,2500);
    }).catch(e=>{ setApplyState(null); wErr(e); }); };

  // --- facets (client-side como AssociationsView) ---
  const fFil=facets.filter(x=> !fq || String(x.id).toLowerCase().includes(fq.toLowerCase()));
  const fPages=Math.max(1,Math.ceil(fFil.length/FP)); const fp=Math.min(fpage,fPages-1);
  const fSlice=fFil.slice(fp*FP,fp*FP+FP);
  const pages=Math.max(1,Math.ceil(total/PAGE)); const pg=Math.min(page,pages-1);
  const nChecked=Object.keys(checked).filter(k=>checked[k]).length;
  const allChecked=rows.length>0 && rows.every(r=>checked[r.sku_key]);
  const toggleAll=()=>{ const n={...checked}; const on=!allChecked; rows.forEach(r=>{ n[r.sku_key]=on; }); setChecked(n); };

  // --- header ---
  const keyBox=React.createElement('div',{style:{display:'flex',gap:6,alignItems:'center'}},
    React.createElement('span',{title:es?'X-API-Key para editar':'X-API-Key to edit',style:{fontSize:14}},'🔑'),
    React.createElement('input',{type:'password',placeholder:'X-API-Key',value:keyVal,
      onChange:e=>setKeyVal(e.target.value),onBlur:()=>OA.setAdminKey(keyVal.trim()),
      style:{...inp,width:130,padding:'6px 9px',fontSize:12}}));
  const header=React.createElement('div',{style:{display:'flex',gap:10,alignItems:'center',flexWrap:'wrap',marginBottom:12}},
    React.createElement('div',{className:'seg'},[['brand',es?'Por marca':'By brand'],['category',es?'Por categoría':'By category']].map(([v,l])=>
      React.createElement('button',{key:v,className:mode===v?'on':'',onClick:()=>setMode(v)},l))),
    React.createElement('input',{placeholder:es?'Buscar SKU/nombre en todo el catálogo…':'Search SKU/name across the catalog…',
      value:qLive,onChange:e=>setQLive(e.target.value),style:{...inp,minWidth:250,flex:1}}),
    keyBox,
    React.createElement('button',{onClick:applyIceberg,disabled:!!(applyState&&applyState.running),
      style:{padding:'8px 12px',border:'1px solid #E5E5E5',borderRadius:8,fontSize:13,fontWeight:600,background:(applyState&&applyState.running)?'#F5F5F5':'#fff',color:'#525252',cursor:(applyState&&applyState.running)?'default':'pointer'},
      title:es?'Reescribe Iceberg desde D1 para que las vistas en vivo tomen los cambios ya':'Rewrite Iceberg from D1 so live views pick changes now'},
      (applyState&&applyState.running)?(es?'Aplicando…':'Applying…'):(es?'⇪ Aplicar a Iceberg':'⇪ Apply to Iceberg')));

  const note=React.createElement('div',{className:'note-bar',style:{marginBottom:12}},React.createElement(Icon.info,null),
    React.createElement('span',null, es
      ? 'Corrige marca, categoría, nombre o estado de un SKU del catálogo maestro. El cambio queda al instante en el catálogo (D1) y sobrevive los refreshes automáticos desde Mongo; el Monitor de Implementación lo toma en ≤2h y las vistas en vivo tras el próximo refresh (≤12h) o al pulsar “Aplicar a Iceberg”. Solo re-etiqueta eventos sin marca/categoría propia.'
      : 'Fix brand, category, name or state of a SKU in the master catalog. Changes apply instantly to the catalog (D1) and survive automatic refreshes from Mongo; the Implementation Monitor picks them up in ≤2h and live views on the next refresh (≤12h) or when you press “Apply to Iceberg”. Only re-labels events without their own brand/category.'));

  const errBar= err && React.createElement('div',{style:{padding:'8px 12px',background:'#FEF2F2',color:RED,borderRadius:8,fontSize:13,marginBottom:10}},err,
    React.createElement('button',{onClick:()=>setErr(''),style:{marginLeft:10,border:'none',background:'none',color:RED,cursor:'pointer',fontWeight:700}},'×'));
  const applyBar= applyState && !applyState.running && React.createElement('div',{style:{padding:'8px 12px',background:'#F0FDF4',color:GRN,borderRadius:8,fontSize:13,marginBottom:10}},
    (applyState.result&&applyState.result.status==='ok') ? ((es?'Iceberg actualizado (':'Iceberg updated (')+(applyState.result.rows||'?')+(es?' filas).':' rows).'))
      : ((es?'Aplicar a Iceberg falló: ':'Apply to Iceberg failed: ')+JSON.stringify((applyState.result&&applyState.result.error)||applyState.result)),
    React.createElement('button',{onClick:()=>setApplyState(null),style:{marginLeft:10,border:'none',background:'none',color:GRN,cursor:'pointer',fontWeight:700}},'×'));

  // --- panel maestro (izq) ---
  const master=React.createElement('div',{style:{width:300,flexShrink:0,borderRight:'1px solid #EEE',paddingRight:12}},
    React.createElement('input',{placeholder:mode==='brand'?(es?'Buscar marca…':'Search brand…'):(es?'Buscar categoría…':'Search category…'),
      value:fq,onChange:e=>{setFq(e.target.value);setFpage(0);},style:{...inp,width:'100%',marginBottom:8}}),
    fLoading ? React.createElement('div',{className:'empty'},React.createElement('div',{className:'spinner'}))
    : fSlice.length===0 ? React.createElement('div',{className:'empty',style:{fontSize:13}},OA.t('noData'))
    : React.createElement('div',null,
        fSlice.map(item=>{ const isSel=sel&&sel.id===item.id;
          return React.createElement('button',{key:item.id,onClick:()=>selectEntity(item),
            style:{display:'flex',width:'100%',textAlign:'left',gap:8,alignItems:'center',padding:'8px 10px',borderRadius:8,
              border:'1px solid '+(isSel?PUR:'transparent'),background:isSel?'#F5F4FF':'transparent',cursor:'pointer',marginBottom:2}},
            React.createElement('div',{style:{minWidth:0,flex:1}},
              React.createElement('div',{style:{fontWeight:600,fontSize:13,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}, item.id),
              React.createElement('div',{style:{fontSize:11,color:'#9CA3AF'}},
                item.active+(es?' activos':' active')+(item.overridden?(' · '+item.overridden+(es?' editados':' edited')):''))),
            React.createElement('span',{className:'ct'}, OA.fmtCompact(item.skus)));
        }),
        pager(fp,fPages,fFil.length,setFpage)));

  // --- tabla de detalle ---
  const ovrDot=(r,f)=> r['ovr_'+f]!=null && React.createElement('span',{title:(es?'Original: ':'Original: ')+(r['orig_'+f]||'—'),
    style:{display:'inline-block',width:7,height:7,borderRadius:99,background:PUR,marginLeft:5,verticalAlign:'middle'}});
  const detailTable=loading
    ? React.createElement('div',{className:'empty'},React.createElement('div',{className:'spinner'}))
    : rows.length===0 ? React.createElement('div',{className:'empty'},React.createElement(Icon.search,null),
        (sel||q)?OA.t('noData'):(es?'Selecciona una '+(mode==='brand'?'marca':'categoría')+' a la izquierda o busca en todo el catálogo':'Select a '+(mode==='brand'?'brand':'category')+' on the left or search the catalog'))
    : React.createElement('div',{style:{overflowX:'auto'}}, React.createElement('table',{className:'table'},
        React.createElement('thead',null,React.createElement('tr',null,
          React.createElement('th',{style:{width:28}}, React.createElement('input',{type:'checkbox',checked:allChecked,onChange:toggleAll})),
          React.createElement('th',null,'SKU'),
          React.createElement('th',null, es?'Nombre':'Name'),
          React.createElement('th',null, es?'Marca':'Brand'),
          React.createElement('th',null, es?'Categoría':'Category'),
          React.createElement('th',null, es?'Estado':'State'),
          React.createElement('th',null,''))),
        React.createElement('tbody',null, rows.map(r=>{ const edited=r.has_override;
          return React.createElement('tr',{key:r.sku_key,style:edited?{background:'#F5F4FF'}:null},
            React.createElement('td',null, React.createElement('input',{type:'checkbox',checked:!!checked[r.sku_key],onChange:()=>setChecked(c=>({...c,[r.sku_key]:!c[r.sku_key]}))})),
            React.createElement('td',null, React.createElement('div',{style:{fontWeight:600,fontSize:13}},r.sku),
              (r.sku_key!==String(r.sku||'').toLowerCase())?React.createElement('div',{style:{fontSize:11,color:'#9CA3AF'}},r.sku_key):null),
            React.createElement('td',{style:{maxWidth:340}}, React.createElement('span',{style:{fontSize:13}}, r.name||'—'), ovrDot(r,'name')),
            React.createElement('td',null, r.brand, ovrDot(r,'brand')),
            React.createElement('td',null, r.category||'—', ovrDot(r,'category')),
            React.createElement('td',null, React.createElement('span',{style:{fontSize:12,fontWeight:700,padding:'3px 9px',borderRadius:99,
              background:r.state?'#DCFCE7':'#FEE2E2',color:r.state?GRN:RED}}, r.state?(es?'Activo':'Active'):(es?'Inactivo':'Inactive')), ovrDot(r,'state')),
            React.createElement('td',null,
              edited?React.createElement('span',{className:'ct',title:(r.ovr_note||'')+((r.ovr_updated_at)?(' · '+r.ovr_updated_at):''),style:{marginRight:6,color:PUR}},es?'editado':'edited'):null,
              React.createElement('button',{onClick:()=>{ setEdit(r); setEv({brand:r.brand||'',category:r.category||'',name:r.name||'',state:!!r.state,note:r.ovr_note||''}); },style:btn(PUR)}, es?'Editar':'Edit')));
        }))));

  // --- barra bulk ---
  const bulkBar= nChecked>0 && React.createElement('div',{style:{display:'flex',gap:8,alignItems:'center',padding:'8px 10px',background:'#F5F4FF',borderRadius:8,marginBottom:8,flexWrap:'wrap'}},
    React.createElement('span',{style:{fontSize:12,fontWeight:700}}, nChecked+(es?' seleccionados':' selected')),
    React.createElement('div',{className:'seg'},[['category',es?'Categoría':'Category'],['brand',es?'Marca':'Brand']].map(([v,l])=>
      React.createElement('button',{key:v,className:bulkField===v?'on':'',onClick:()=>setBulkField(v)},l))),
    React.createElement('input',{list:'oa-cat-bulk-options',placeholder:es?'Nuevo valor…':'New value…',value:bulkVal,
      onChange:e=>setBulkVal(e.target.value),style:{...inp,minWidth:170}}),
    React.createElement('datalist',{id:'oa-cat-bulk-options'},
      (bulkField==='category'?(mode==='category'?facets:[]):(mode==='brand'?facets:[])).map(f=>React.createElement('option',{key:f.id,value:f.id}))),
    React.createElement('button',{onClick:bulk,disabled:busy==='bulk'||!bulkVal.trim(),style:btn(PUR,'#fff')},
      busy==='bulk'?'…':((es?'Aplicar a ':'Apply to ')+nChecked+' SKUs')),
    React.createElement('button',{onClick:()=>setChecked({}),style:btn('#9CA3AF','#fff')}, es?'Limpiar':'Clear'));

  // --- panel detalle (der) ---
  const detail=React.createElement('div',{style:{flex:1,minWidth:0,paddingLeft:14}},
    React.createElement('div',{style:{display:'flex',gap:8,alignItems:'center',flexWrap:'wrap',marginBottom:8}},
      sel?React.createElement('h3',{style:{margin:0,fontSize:16}}, sel.id):React.createElement('span',{style:{fontSize:13,color:'#9CA3AF'}}, q?(es?'Resultados en todo el catálogo':'Results across the catalog'):''),
      React.createElement('div',{style:{flex:1}}),
      React.createElement('div',{className:'seg'},[['',es?'Todos':'All'],['1',es?'Editados':'Edited']].map(([v,l])=>
        React.createElement('button',{key:v||'all',className:fOvr===v?'on':'',onClick:()=>{setFOvr(v);setPage(0);loadRows(sel,{fOvr:v,page:0});}},l))),
      React.createElement('span',{style:{fontSize:12,color:'#737373'}}, total+' SKUs')),
    bulkBar,
    detailTable,
    pager(pg,pages,total,(p)=>{ setPage(p); loadRows(sel,{page:p}); }));

  // --- SlideOver de edición ---
  const fieldRow=(f,label)=>{ const orig=edit&&edit['ovr_'+f]!=null?edit['orig_'+f]:null;
    return React.createElement('div',{style:{marginBottom:12}},
      React.createElement('div',{style:{fontSize:11,fontWeight:700,color:'#737373',textTransform:'uppercase',letterSpacing:'.04em',marginBottom:4}},label),
      React.createElement('input',{value:ev[f]||'',disabled:!!ev['rv_'+f],onChange:e=>setEv(v=>({...v,[f]:e.target.value})),style:{...inp,width:'100%',opacity:ev['rv_'+f]?0.5:1}}),
      (edit&&edit['ovr_'+f]!=null)&&React.createElement('div',{style:{fontSize:11,color:'#9CA3AF',marginTop:3,display:'flex',gap:8,alignItems:'center'}},
        React.createElement('span',null,(es?'Original: ':'Original: ')+(orig||'—')),
        React.createElement('label',{style:{cursor:'pointer',color:PUR,fontWeight:600}},
          React.createElement('input',{type:'checkbox',checked:!!ev['rv_'+f],onChange:e=>setEv(v=>({...v,['rv_'+f]:e.target.checked})),style:{marginRight:4}}),
          es?'Revertir al original':'Revert to original'))); };
  const editor= edit && React.createElement(SlideOver,{onClose:()=>setEdit(null),title:edit.sku,sub:es?'Editar producto':'Edit product'},
    React.createElement('div',{style:{padding:'4px 2px'}},
      fieldRow('name',es?'Nombre':'Name'),
      fieldRow('brand',es?'Marca':'Brand'),
      fieldRow('category',es?'Categoría':'Category'),
      React.createElement('div',{style:{marginBottom:12,display:'flex',gap:14,alignItems:'center'}},
        React.createElement('label',{style:{fontSize:13,cursor:'pointer'}},
          React.createElement('input',{type:'checkbox',checked:!!ev.state,disabled:!!ev.rv_state,onChange:e=>setEv(v=>({...v,state:e.target.checked})),style:{marginRight:6}}),
          es?'Activo':'Active'),
        (edit['ovr_state']!=null)&&React.createElement('label',{style:{fontSize:12,cursor:'pointer',color:PUR,fontWeight:600}},
          React.createElement('input',{type:'checkbox',checked:!!ev.rv_state,onChange:e=>setEv(v=>({...v,rv_state:e.target.checked})),style:{marginRight:4}}),
          es?'Revertir estado':'Revert state')),
      React.createElement('div',{style:{marginBottom:14}},
        React.createElement('div',{style:{fontSize:11,fontWeight:700,color:'#737373',textTransform:'uppercase',letterSpacing:'.04em',marginBottom:4}},es?'Nota':'Note'),
        React.createElement('input',{value:ev.note||'',placeholder:es?'Motivo del cambio (opcional)':'Reason (optional)',onChange:e=>setEv(v=>({...v,note:e.target.value})),style:{...inp,width:'100%'}})),
      React.createElement('div',{style:{display:'flex',gap:8}},
        React.createElement('button',{onClick:saveEdit,disabled:busy==='save',style:btn('#fff',PUR)}, busy==='save'?'…':(es?'Guardar':'Save')),
        React.createElement('button',{onClick:()=>setEdit(null),style:btn('#9CA3AF','#fff')}, es?'Cancelar':'Cancel')),
      err&&React.createElement('div',{style:{marginTop:10,fontSize:12,color:RED}},err)));

  return React.createElement('div',null,
    React.createElement(Card,{title:es?'Catálogo de productos':'Product catalog',
      desc:es?'Corrige marca, categoría y nombre de los SKUs del catálogo maestro':'Fix brand, category and name of master-catalog SKUs', pad:true},
      header, note, errBar, applyBar,
      React.createElement('div',{style:{display:'flex',alignItems:'flex-start'}}, master, detail)),
    editor);
}
window.CatalogView=CatalogView;
