(()=>{
'use strict';
if(window.__supervisorCommercialModulesV4324)return;
window.__supervisorCommercialModulesV4324=true;

const VERSION='4.3.31';
const ADMIN_BASE_PRICE=20000;
const DEFAULT_PRICE=10000;
const MODULES=[
 {key:'doctor',label:'Médico',detail:'Expediente, consultas, indicaciones, recetas y resultados'},
 {key:'nurse',label:'Enfermería',detail:'Signos, curaciones, notas y medicamentos'},
 {key:'assistant',label:'Asistentes',detail:'Cuidados, ingesta e incidentes'},
 {key:'cook',label:'Cocina',detail:'Plan nutricional e ingesta'},
 {key:'security',label:'Seguridad',detail:'Entradas, salidas e incidentes'},
 {key:'cleaning',label:'Miscelánea',detail:'Tareas operativas e incidentes'},
 {key:'maintenance',label:'Mantenimiento',detail:'Tareas, inventario e incidentes'}
];

const db=()=>window.seniorcareSupabase;
const root=()=>document.getElementById('mainContent');
const isSup=()=>String(window.currentUser?.role||'').toLowerCase()==='supervisor';
const toast=m=>window.showToast?window.showToast(m):alert(m);
const esc=v=>String(v??'').replace(/[&<>'"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[c]));
const money=n=>new Intl.NumberFormat('es-CR',{style:'currency',currency:'CRC',maximumFractionDigits:0}).format(Number(n||0));
const fmt=d=>d?new Date(d).toLocaleDateString('es-CR'):'Sin definir';
const statusLabel=l=>!l?'Pendiente':l.status==='suspended'?'Suspendida':l.status==='cancelled'?'Cancelada':l.payment_confirmed&&l.status==='active'?'Activa':'Pendiente';
const statusClass=l=>statusLabel(l)==='Activa'?'ok':statusLabel(l)==='Suspendida'||statusLabel(l)==='Cancelada'?'danger':'warn';
const moduleLabel=key=>MODULES.find(x=>x.key===key)?.label||key;
const normalizedPrice=value=>{
 const raw=String(value??'').trim();
 if(raw==='')return DEFAULT_PRICE;
 const amount=Number(raw);
 if(!Number.isFinite(amount))return DEFAULT_PRICE;
 return Math.max(0,Math.round(amount));
};
const enabledRows=rows=>(rows||[]).filter(x=>x.enabled===true);
const modulesSubtotal=rows=>enabledRows(rows).reduce((sum,row)=>sum+normalizedPrice(row.monthly_price),0);
const moduleTotal=rows=>ADMIN_BASE_PRICE+modulesSubtotal(rows);

async function auditEvent(orgId,action,details={}){
 const result=await db().from('audit_logs').insert({
  organization_id:orgId||null,
  user_id:window.currentUser?.id||null,
  action,
  table_name:'supervisor_commercial_v4325',
  record_id:orgId||null,
  details
 });
 if(result.error)throw result.error;
}

async function fetchModules(orgId=null){
 let q=db().from('organization_module_subscriptions').select('organization_id,module_key,enabled,monthly_price,currency,updated_at');
 if(orgId)q=q.eq('organization_id',orgId);
 const result=await q;
 if(result.error)throw result.error;
 return result.data||[];
}

async function fetchOrganizations(){
 const result=await db().from('organizations').select('id,name').order('name');
 if(result.error)throw result.error;
 return result.data||[];
}

function openModuleContract(orgId){
 if(!orgId){toast('No se encontró la organización.');return;}
 sessionStorage.setItem('seniorcare-selected-org',String(orgId));
 if(typeof window.go==='function')window.go('supervisorOrganizationDetail',{scope:'global'});
 else if(typeof window.renderSupervisorOrganizationDetail==='function'){
  window.activeScreen='supervisorOrganizationDetail';
  window.renderSupervisorOrganizationDetail();
 }
 let attempts=0;
 const timer=setInterval(()=>{
  attempts+=1;
  const panel=document.querySelector('.supervisor-module-panel');
  if(panel){
   clearInterval(timer);
   panel.classList.add('module-panel-focus-v4324');
   panel.scrollIntoView({behavior:'smooth',block:'start'});
   setTimeout(()=>panel.classList.remove('module-panel-focus-v4324'),2200);
  }else if(attempts>30)clearInterval(timer);
 },120);
}
window.BHSC_OPEN_MODULE_CONTRACT_V4324=openModuleContract;

async function syncLicenseAmount(orgId,total){
 const result=await db().from('licenses').update({
  price_monthly:Number(total||0),
  updated_at:new Date().toISOString(),
  updated_by:window.currentUser?.id||null
 }).eq('organization_id',orgId);
 if(result.error)throw result.error;
}

async function savePackageFromPanel(orgId,panel){
 const cards=[...panel.querySelectorAll('[data-sg-module]')];
 if(!cards.length)throw new Error('No se encontraron módulos para guardar.');
 const now=new Date().toISOString();
 const rows=cards.map(card=>{
  const checked=!!card.querySelector('input[type="checkbox"]')?.checked;
  const priceInput=card.querySelector('.sg-price');
  const price=normalizedPrice(priceInput?.value);
  if(priceInput)priceInput.value=String(price);
  return {
   organization_id:orgId,
   module_key:String(card.dataset.sgModule||''),
   enabled:checked,
   monthly_price:price,
   currency:'CRC',
   updated_at:now,
   updated_by:window.currentUser?.id||null
  };
 });
 const payload=rows.map(x=>({module_key:x.module_key,enabled:x.enabled,monthly_price:x.monthly_price,currency:'CRC'}));
 let rpc=null;
 if(window.BHSC_CALL_RPC){
  rpc=await window.BHSC_CALL_RPC(['bh_save_module_contract_v4331','bh_save_module_contract_v4330','bh_save_module_contract_v4328','bh_save_module_contract_v4327','bh_save_module_contract_v4325'],{p_org_id:orgId,p_modules:payload});
 }
 if(rpc?.error&&!window.BHSC_RPC_FUNCTION_MISSING?.(rpc.error))throw rpc.error;
 if(!rpc||rpc.error){
  const upsert=await db().from('organization_module_subscriptions').upsert(rows,{onConflict:'organization_id,module_key'});
  if(upsert.error)throw upsert.error;
 }
 const count=rows.filter(x=>x.enabled).length;
 const modulesTotal=rows.filter(x=>x.enabled).reduce((sum,x)=>sum+x.monthly_price,0);
 const total=ADMIN_BASE_PRICE+modulesTotal;
 let license=await db().from('licenses').update({price_monthly:total,plan_name:'Panel administrativo + módulos',updated_at:now,updated_by:window.currentUser?.id||null}).eq('organization_id',orgId).select('id');
 if(license.error)throw license.error;
 if(!(license.data||[]).length){
  license=await db().from('licenses').insert({organization_id:orgId,status:'pending',plan_name:'Panel administrativo + módulos',term_days:30,payment_confirmed:false,price_monthly:total,updated_at:now,updated_by:window.currentUser?.id||null}).select('id');
  if(license.error)throw license.error;
 }
 try{await auditEvent(orgId,'billing_contract_updated_v4331',{modules:payload,enabled_count:count,admin_base_price:ADMIN_BASE_PRICE,default_module_price:DEFAULT_PRICE,modules_subtotal:modulesTotal,monthly_total:total});}catch(auditError){console.warn('[BHSC V4.3.31] Contrato guardado; auditoría secundaria no disponible',auditError);}
 return {rows,total,count};
}

function recalcModulePanel(panel){
 const cards=[...panel.querySelectorAll('[data-sg-module]')];
 let count=0,total=ADMIN_BASE_PRICE;
 cards.forEach(card=>{
  const check=card.querySelector('input[type="checkbox"]');
  const priceInput=card.querySelector('.sg-price');
  if(check?.checked){
   count+=1;
   const price=normalizedPrice(priceInput?.value);
   if(priceInput&&String(priceInput.value??'').trim()==='')priceInput.value=String(price);
   total+=price;
   card.classList.add('contracted-v4324');
  }else card.classList.remove('contracted-v4324');
 });
 const totalEl=panel.querySelector('#sgModuleTotal');
 if(totalEl)totalEl.textContent=money(total);
 const countEl=panel.querySelector('[data-module-count-v4324]');
 if(countEl)countEl.textContent=String(count);
 const amountEl=panel.querySelector('[data-module-total-v4324]');
 if(amountEl)amountEl.textContent=money(total);
}

function enhanceModulePanel(){
 const panel=document.querySelector('.supervisor-module-panel');
 if(!panel||panel.dataset.v4324==='1')return;
 const orgId=sessionStorage.getItem('seniorcare-selected-org');
 if(!orgId)return;
 panel.dataset.v4324='1';
 const heading=panel.querySelector('.supervisor-module-head > div');
 if(heading){
  heading.innerHTML='<span>CONTRATO MODULAR</span><h3>Módulos contratados</h3><p>El panel administrativo tiene un costo fijo de ₡20.000 mensuales. Cada módulo inicia en ₡10.000, pero su precio puede ajustarse individualmente según el contrato.</p>';
 }
 const totalStrong=panel.querySelector('#sgModuleTotal');
 if(totalStrong)totalStrong.setAttribute('title','Total mensual: panel administrativo fijo más módulos adicionales');
 panel.querySelectorAll('[data-sg-module]').forEach(card=>{
  const input=card.querySelector('.sg-price');
  const check=card.querySelector('input[type="checkbox"]');
  if(input){
   input.min='0';
   input.removeAttribute('max');
   input.step='1000';
   input.readOnly=false;
   input.value=String(normalizedPrice(input.value));
   input.setAttribute('aria-label',`Precio mensual editable de ${moduleLabel(card.dataset.sgModule)}`);
   input.setAttribute('title','Precio mensual editable; base sugerida ₡10.000');
  }
  card.querySelectorAll('.module-base-badge-v4324').forEach(badge=>badge.remove());
  check?.addEventListener('change',()=>{
   if(check.checked&&input&&String(input.value??'').trim()==='')input.value=String(DEFAULT_PRICE);
   recalcModulePanel(panel);
  });
  input?.addEventListener('input',()=>recalcModulePanel(panel));
  input?.addEventListener('blur',()=>{input.value=String(normalizedPrice(input.value));recalcModulePanel(panel);});
 });
 const actions=panel.querySelector('.form-actions');
 if(actions){
  actions.classList.add('module-actions-v4324');
  actions.querySelectorAll('[data-fixed-price-v4328],[data-flex-price-v4330],.module-fixed-price-note-v4328').forEach(node=>node.remove());
 }
 const save=panel.querySelector('#sgSaveModules');
 if(save){
  save.textContent='Guardar módulos contratados';
  save.onclick=async()=>{
   try{
    save.disabled=true;
    save.textContent='Guardando contrato…';
    const result=await savePackageFromPanel(orgId,panel);
    toast(`Contrato guardado: ${result.count} módulo${result.count===1?'':'s'} · ${money(result.total)} al mes.`);
    recalcModulePanel(panel);
   }catch(error){const msg=String(error?.message||'');toast(/organization_module_subscriptions_module_key_check|violates check constraint/i.test(msg)?'La base de datos necesita la corrección V4.3.31. Ejecute el SQL incluido y vuelva a guardar.':(msg||'No se pudo guardar el contrato modular.'));}
   finally{save.disabled=false;save.textContent='Guardar módulos contratados';}
  };
 }
 if(!panel.querySelector('.module-contract-summary-v4324')){
  panel.querySelector('.supervisor-module-head')?.insertAdjacentHTML('afterend',`<div class="module-contract-summary-v4324"><span><small>Panel administrativo fijo</small><strong>${money(ADMIN_BASE_PRICE)}</strong></span><span><small>Módulos adicionales</small><strong data-module-count-v4324>0</strong></span><span><small>Mensualidad total</small><strong data-module-total-v4324>${money(ADMIN_BASE_PRICE)}</strong></span></div><div class="module-contract-note-v4324"><strong>Importante:</strong> la mensualidad se calcula con ₡20.000 del panel más la suma de los precios individuales de los módulos activos. Desactivar un módulo bloquea el acceso de ese tipo de trabajador.</div>`);
 }
 recalcModulePanel(panel);
}

async function enhanceOrganizationCards(){
 if(!isSup()||window.activeScreen!=='supervisorOrganizations')return;
 const r=root();
 if(!r)return;
 try{
  const modules=await fetchModules();
  const byOrg=new Map();
  modules.forEach(row=>{
   const key=String(row.organization_id||'');
   if(!byOrg.has(key))byOrg.set(key,[]);
   byOrg.get(key).push(row);
  });
  r.querySelectorAll('.supervisor-org-card').forEach(card=>{
   const open=card.querySelector('[data-sg-open]');
   if(!open)return;
   const orgId=String(open.dataset.sgOpen||'');
   const rows=byOrg.get(orgId)||[];
   const active=enabledRows(rows);
   const total=moduleTotal(rows);
   if(!card.querySelector('.module-contract-strip-v4324')){
    const meta=card.querySelector('.supervisor-org-meta');
    meta?.insertAdjacentHTML('afterend',`<div class="module-contract-strip-v4324"><div><span>CONTRATO MODULAR</span><strong>${active.length} módulo${active.length===1?'':'s'} · ${money(total)}</strong><small>${active.length?active.map(x=>esc(moduleLabel(x.module_key))).join(' · '):'Solo panel administrativo'}</small></div><button type="button" class="secondary-btn" data-open-modules-v4324="${esc(orgId)}">${active.length?'Editar módulos':'Asignar módulos'}</button></div>`);
   }
   const actions=card.querySelector('.supervisor-org-actions');
   if(actions&&!actions.querySelector('[data-open-modules-v4324]'))actions.insertAdjacentHTML('afterbegin',`<button type="button" class="secondary-btn" data-open-modules-v4324="${esc(orgId)}">Configurar módulos</button>`);
  });
 }catch(error){console.warn('[BHSC V4.3.25] No se pudo enriquecer Organizaciones',error);}
}

async function enhanceAdminCards(){
 if(!isSup()||window.activeScreen!=='supervisorAdmins')return;
 const r=root();
 if(!r)return;
 try{
  const [profilesResult,modules]=await Promise.all([
   db().from('profiles').select('id,organization_id').eq('role','administrator'),
   fetchModules()
  ]);
  if(profilesResult.error)throw profilesResult.error;
  const profileMap=new Map((profilesResult.data||[]).map(x=>[String(x.id),x]));
  const byOrg=new Map();
  modules.forEach(row=>{
   const key=String(row.organization_id||'');
   if(!byOrg.has(key))byOrg.set(key,[]);
   byOrg.get(key).push(row);
  });
  r.querySelectorAll('.supervisor-admin-list article').forEach(card=>{
   const toggle=card.querySelector('[data-sg-admin]');
   if(!toggle||card.querySelector('.admin-contract-v4324'))return;
   const profile=profileMap.get(String(toggle.dataset.sgAdmin||''));
   const orgId=String(profile?.organization_id||toggle.dataset.org||'');
   const rows=byOrg.get(orgId)||[];
   const active=enabledRows(rows);
   const total=moduleTotal(rows);
   card.insertAdjacentHTML('beforeend',`<div class="admin-contract-v4324"><div><small>Contrato de la organización</small><strong>${active.length} módulo${active.length===1?'':'s'} · ${money(total)} mensuales</strong><span>${active.length?active.map(x=>esc(moduleLabel(x.module_key))).join(' · '):'Aún no se han asignado módulos'}</span></div><button type="button" class="secondary-btn" data-open-modules-v4324="${esc(orgId)}">Módulos contratados</button></div>`);
  });
  const firstHistory=r.querySelector('.history-card');
  if(firstHistory&&!r.querySelector('.admin-code-expiry-note-v4324'))firstHistory.insertAdjacentHTML('afterbegin','<div class="admin-code-expiry-note-v4324"><strong>Vigencia del código ADM:</strong> el código sirve únicamente para inscribir la cuenta. Si vence sin utilizarse, queda inválido y el Supervisor genera uno nuevo. Una cuenta ya registrada no pierde acceso porque el código haya vencido.</div>');
 }catch(error){console.warn('[BHSC V4.3.25] No se pudo enriquecer Administradores',error);}
}

async function enhanceAdminModal(modal){
 if(!modal||modal.dataset.v4324==='1')return;
 modal.dataset.v4324='1';
 const id=String(modal.querySelector('input[name="id"]')?.value||'');
 if(!id)return;
 try{
  const profile=await db().from('profiles').select('id,organization_id').eq('id',id).eq('role','administrator').maybeSingle();
  if(profile.error)throw profile.error;
  const orgId=String(profile.data?.organization_id||'');
  const rows=await fetchModules(orgId);
  const active=enabledRows(rows);
  const total=moduleTotal(rows);
  const summary=modal.querySelector('.admin-modal-summary-v4323');
  summary?.insertAdjacentHTML('afterend',`<section class="admin-modal-contract-v4324"><div><span>CONTRATO MODULAR</span><h4>${active.length} módulo${active.length===1?'':'s'} contratados</h4><p>${active.length?active.map(x=>esc(moduleLabel(x.module_key))).join(' · '):'Esta organización todavía no tiene módulos asignados.'}</p></div><div><small>Mensualidad calculada</small><strong>${money(total)}</strong><button type="button" class="secondary-btn" data-open-modules-v4324="${esc(orgId)}">Configurar módulos</button></div></section>`);
 }catch(error){console.warn('[BHSC V4.3.25] No se pudo cargar contrato en ficha administrativa',error);}
}

async function updateLicenseDraft(id,days,price){
 let q=window.BHSC_CALL_RPC?await window.BHSC_CALL_RPC(['bh_update_license_draft_v4321','update_license_draft'],{
  p_license_id:id,
  p_term_days:days,
  p_renews_at:new Date(Date.now()+days*86400000).toISOString(),
  p_plan_name:'Panel administrativo + módulos',
  p_price_monthly:price
 }):null;
 if(!q||q.error){
  q=await db().from('licenses').update({
   term_days:days,
   price_monthly:price,
   plan_name:'Panel administrativo + módulos',
   updated_at:new Date().toISOString(),
   updated_by:window.currentUser?.id||null
  }).eq('id',id);
 }
 if(q?.error)throw q.error;
}

async function confirmPayment(id,days){
 const q=window.BHSC_CALL_RPC
  ?await window.BHSC_CALL_RPC(['bh_confirm_license_payment_v4331','bh_confirm_license_payment_v4330','bh_confirm_license_payment_v4329','bh_confirm_license_payment_v4325','bh_confirm_license_payment_v4321','supervisor_confirm_payment_v2','confirm_license_payment','supervisor_confirm_payment'],{p_license_id:id,p_term_days:days})
  :await db().rpc('bh_confirm_license_payment_v4331',{p_license_id:id,p_term_days:days});
 if(q?.error)throw q.error;

 const verify=await db().from('licenses')
  .select('id,organization_id,status,payment_confirmed,starts_at,renews_at,term_days,price_monthly')
  .eq('id',id)
  .maybeSingle();
 if(verify.error)throw verify.error;
 if(!verify.data?.payment_confirmed||String(verify.data?.status||'').toLowerCase()!=='active'||!verify.data?.renews_at){
  throw new Error('La licencia no quedó activada correctamente en Supabase.');
 }
 return q;
}

const page=(eyebrow,title,text,backScreen='home')=>`<section class="page-head supervisor-page-head">${backScreen?`<button class="back-btn supervisor-back-btn" data-go="${backScreen}" aria-label="Volver">‹<span>Volver</span></button>`:''}<div><span>${esc(eyebrow)}</span><h2>${esc(title)}</h2><p>${esc(text)}</p></div></section>`;

async function setOrganizationStatusV4324(orgId,next){
 const active=next==='active';
 const [licenseUpdate,orgUpdate]=await Promise.all([
  db().from('licenses').update({
   status:next,
   suspended_at:active?null:new Date().toISOString(),
   suspension_reason:active?null:'Suspendida por Supervisor',
   updated_by:window.currentUser?.id||null,
   updated_at:new Date().toISOString()
  }).eq('organization_id',orgId),
  db().from('organizations').update({active,updated_at:new Date().toISOString()}).eq('id',orgId)
 ]);
 if(licenseUpdate.error)throw licenseUpdate.error;
 if(orgUpdate.error)throw orgUpdate.error;
 await auditEvent(orgId,active?'organization_reactivated_v4324':'organization_suspended_v4324',{scope:'organization',profiles_preserved:true});
}

async function renderLicensesV4324(){
 if(!isSup())return;
 const r=root();
 if(!r)return;
 r.innerHTML=page('CONTROL DE LICENCIAS','Licencias','Estado, vigencia y suspensión de cada organización','home')+'<div class="supv-loading">Cargando licencias…</div>';
 setTimeout(()=>window.setActiveNav?.('supervisorLicenses'),0);
 try{
  const [orgsResult,licensesResult,modules]=await Promise.all([
   db().from('organizations').select('id,name').order('name'),
   db().from('licenses').select('*').order('renews_at',{ascending:true}),
   fetchModules()
  ]);
  if(orgsResult.error)throw orgsResult.error;
  if(licensesResult.error)throw licensesResult.error;
  const orgMap=new Map((orgsResult.data||[]).map(x=>[String(x.id),x]));
  const byOrg=new Map();
  modules.forEach(row=>{
   const key=String(row.organization_id||'');
   if(!byOrg.has(key))byOrg.set(key,[]);
   byOrg.get(key).push(row);
  });
  const licenses=licensesResult.data||[];
  const activeCount=licenses.filter(x=>statusLabel(x)==='Activa').length;
  const pendingCount=licenses.filter(x=>statusLabel(x)==='Pendiente').length;
  const suspendedCount=licenses.filter(x=>statusLabel(x)==='Suspendida').length;
  r.innerHTML=page('CONTROL DE LICENCIAS','Licencias','Estado, vigencia y suspensión de cada organización','home')+`
   <section class="commercial-tabs-v4323"><button type="button" class="active" data-go="supervisorLicenses">Licencias</button><button type="button" data-go="supervisorPayments">Pagos</button></section>
   <section class="license-summary-v4324"><article><span>Activas</span><strong>${activeCount}</strong><small>Operación autorizada</small></article><article><span>Pendientes</span><strong>${pendingCount}</strong><small>Pago o activación</small></article><article><span>Suspendidas</span><strong>${suspendedCount}</strong><small>Acceso institucional bloqueado</small></article></section>
   <section class="license-purpose-v4323"><div><strong>Licencias institucionales</strong><span>Aquí se controla el estado y la vigencia. La facturación se administra por separado en Pagos.</span></div><button type="button" class="secondary-btn" data-go="supervisorPayments">Ir a pagos</button></section>
   <div class="license-grid-v4324">${licenses.map(l=>{
    const org=orgMap.get(String(l.organization_id||''));
    const rows=byOrg.get(String(l.organization_id||''))||[];
    const activeModules=enabledRows(rows);
    const total=moduleTotal(rows);
    const next=l.status==='suspended'?'active':'suspended';
    return `<article class="license-card-v4324"><div class="license-card-head-v4324"><div><span>ORGANIZACIÓN</span><h3>${esc(org?.name||'Organización')}</h3><p>${l.payment_confirmed?'Pago confirmado':'Pago pendiente'}</p></div><span class="status ${statusClass(l)}">${statusLabel(l)}</span></div><div class="license-data-v4324"><span><small>Renovación</small><strong>${esc(fmt(l.renews_at))}</strong></span><span><small>Vigencia</small><strong>${Number(l.term_days||30)} días</strong></span><span><small>Módulos</small><strong>${activeModules.length}</strong></span><span><small>Mensualidad total</small><strong>${money(total)}</strong></span></div><div class="license-module-tags-v4324">${activeModules.map(x=>`<span>${esc(moduleLabel(x.module_key))}</span>`).join('')||'<span class="empty-tag-v4324">Solo panel administrativo</span>'}</div>${l.suspension_reason?`<p class="license-reason-v4324">${esc(l.suspension_reason)}</p>`:''}<div class="license-actions-v4324"><button type="button" class="secondary-btn" data-open-modules-v4324="${esc(l.organization_id)}">Configurar módulos</button><button type="button" class="secondary-btn" data-go="supervisorPayments">Ver pagos</button><button type="button" class="${next==='active'?'primary-btn':'mini-btn'}" data-license-status-v4324="${esc(l.organization_id)}" data-next="${next}">${next==='active'?'Reactivar':'Suspender'}</button></div></article>`;
   }).join('')||'<div class="empty-state"><strong>No hay licencias registradas</strong><span>Cree una organización para comenzar.</span></div>'}</div>`;
  r.querySelectorAll('[data-license-status-v4324]').forEach(button=>button.onclick=async()=>{
   const next=button.dataset.next;
   if(next==='suspended'&&!confirm('¿Suspender esta organización y bloquear el acceso institucional?'))return;
   try{
    button.disabled=true;
    await setOrganizationStatusV4324(button.dataset.licenseStatusV4324,next);
    toast(next==='active'?'Organización reactivada.':'Organización suspendida.');
    await renderLicensesV4324();
   }catch(error){toast(error.message||'No se pudo actualizar la licencia.');}
   finally{button.disabled=false;}
  });
  wireModuleButtons(r);
  setTimeout(()=>window.setActiveNav?.('supervisorLicenses'),0);
 }catch(error){
  r.innerHTML=page('CONTROL DE LICENCIAS','Licencias','Estado, vigencia y suspensión de cada organización','home')+`<div class="empty-state"><strong>No se pudo cargar Licencias</strong><span>${esc(error.message)}</span></div>`;
 }
}

async function renderPaymentsV4324(){
 if(!isSup())return;
 const r=root();
 if(!r)return;
 r.innerHTML=page('CONTROL FINANCIERO','Facturación y pagos','₡20.000 por el panel administrativo más la suma de los precios configurados en cada módulo','home')+'<div class="supv-loading">Cargando contratos y pagos…</div>';
 setTimeout(()=>window.setActiveNav?.('supervisorPayments'),0);
 try{
  const [orgsResult,licensesResult,modules]=await Promise.all([
   db().from('organizations').select('id,name').order('name'),
   db().from('licenses').select('*').order('renews_at',{ascending:true}),
   fetchModules()
  ]);
  if(orgsResult.error)throw orgsResult.error;
  if(licensesResult.error)throw licensesResult.error;
  const orgs=orgsResult.data||[];
  const licenses=licensesResult.data||[];
  const orgMap=new Map(orgs.map(x=>[String(x.id),x]));
  const byOrg=new Map();
  modules.forEach(row=>{
   const key=String(row.organization_id||'');
   if(!byOrg.has(key))byOrg.set(key,[]);
   byOrg.get(key).push(row);
  });
  const contracts=licenses.map(license=>{
   const rows=byOrg.get(String(license.organization_id||''))||[];
   return {license,rows,active:enabledRows(rows),total:moduleTotal(rows)};
  });
  const monthly=contracts.reduce((sum,x)=>sum+x.total,0);
  const confirmed=contracts.filter(x=>x.license.payment_confirmed===true);
  const pending=contracts.filter(x=>x.license.payment_confirmed!==true);
  const confirmedAmount=confirmed.reduce((sum,x)=>sum+x.total,0);
  r.innerHTML=page('CONTROL FINANCIERO','Facturación y pagos','₡20.000 por el panel administrativo más la suma de los precios configurados en cada módulo','home')+`
   <section class="commercial-tabs-v4323"><button type="button" data-go="supervisorLicenses">Licencias</button><button type="button" class="active" data-go="supervisorPayments">Pagos</button></section>
   <section class="payment-summary-v4323"><article><span>Facturación mensual</span><strong>${money(monthly)}</strong><small>Total mensual contratado</small></article><article><span>Pagos confirmados</span><strong>${confirmed.length}</strong><small>${money(confirmedAmount)}</small></article><article><span>Pagos pendientes</span><strong>${pending.length}</strong><small>Requieren confirmación</small></article></section>
   <section class="module-pricing-rule-v4324"><div><strong>Regla comercial</strong><span>El panel administrativo cuesta ${money(ADMIN_BASE_PRICE)} mensuales. Cada módulo inicia en ${money(DEFAULT_PRICE)}, pero puede tener un precio diferente. El total se actualiza automáticamente al guardar el contrato.</span></div><button type="button" class="secondary-btn" data-open-first-modules-v4324>Administrar módulos</button></section>
   <div class="payment-grid-v4323">${contracts.map(({license:l,active,total})=>{
    const org=orgMap.get(String(l.organization_id||''));
    const stored=Number(l.price_monthly||0);
    const differs=stored!==total;
    return `<article class="payment-card-v4323 payment-modular-card-v4324"><div class="payment-card-head-v4323"><div><span>ORGANIZACIÓN</span><h3>${esc(org?.name||'Organización')}</h3><p>${statusLabel(l)} · ${l.payment_confirmed?'Pago confirmado':'Pago pendiente'}</p></div><span class="status ${statusClass(l)}">${statusLabel(l)}</span></div><div class="payment-amount-v4323"><span>Mensualidad total</span><strong>${money(total)}</strong><small>Panel ${money(ADMIN_BASE_PRICE)} + ${active.length} módulo${active.length===1?'':'s'} adicional${active.length===1?'':'es'}</small></div><div class="module-payment-list-v4324"><span><b>Panel administrativo</b><strong>${money(ADMIN_BASE_PRICE)}</strong></span>${active.map(row=>`<span><b>${esc(moduleLabel(row.module_key))}</b><strong>${money(normalizedPrice(row.monthly_price))}</strong></span>`).join('')}</div>${differs?`<div class="payment-sync-warning-v4324">La licencia aún registra ${money(stored)}. Al guardar o confirmar se sincronizará con ${money(total)}.</div>`:''}<div class="payment-form-v4323 single-v4324"><label>Vigencia en días<input type="number" min="1" max="365" data-payment-days-v4324="${esc(l.id)}" value="${Number(l.term_days||30)}"></label></div><div class="payment-detail-v4323"><span><small>Próxima renovación</small><strong>${esc(fmt(l.renews_at))}</strong></span><span><small>Plan</small><strong>Panel + módulos</strong></span></div><div class="payment-actions-v4323"><button type="button" class="secondary-btn" data-open-modules-v4324="${esc(l.organization_id)}">Configurar módulos</button><button type="button" class="secondary-btn" data-sync-license-v4324="${esc(l.id)}" data-org="${esc(l.organization_id)}">Sincronizar monto</button><button type="button" class="primary-btn" data-confirm-payment-v4324="${esc(l.id)}" data-org="${esc(l.organization_id)}">${l.payment_confirmed?'Renovar licencia':'Confirmar pago'}</button></div></article>`;
   }).join('')||'<div class="empty-state"><strong>No hay licencias registradas</strong><span>Los pagos aparecerán al crear una organización.</span></div>'}</div>`;
  r.querySelector('[data-open-first-modules-v4324]')?.addEventListener('click',()=>{
   const first=contracts.find(x=>x.license?.organization_id)?.license?.organization_id;
   if(first)openModuleContract(first);else toast('No hay organizaciones disponibles.');
  });
  r.querySelectorAll('[data-sync-license-v4324]').forEach(button=>button.onclick=async()=>{
   const id=button.dataset.syncLicenseV4324;
   const contract=contracts.find(x=>String(x.license.id)===String(id));
   if(!contract)return;
   const days=Math.max(1,Math.min(365,Number(r.querySelector(`[data-payment-days-v4324="${id}"]`)?.value||30)));
   try{
    button.disabled=true;
    await updateLicenseDraft(id,days,contract.total);
    await auditEvent(contract.license.organization_id,'license_amount_synced_v4324',{license_id:id,days,monthly_total:contract.total,module_count:contract.active.length});
    toast(`Mensualidad sincronizada en ${money(contract.total)}.`);
    await renderPaymentsV4324();
   }catch(error){toast(error.message||'No se pudo sincronizar la mensualidad.');}
   finally{button.disabled=false;}
  });
  r.querySelectorAll('[data-confirm-payment-v4324]').forEach(button=>button.onclick=async()=>{
   const id=button.dataset.confirmPaymentV4324;
   const contract=contracts.find(x=>String(x.license.id)===String(id));
   if(!contract)return;
   const days=Math.max(1,Math.min(365,Number(r.querySelector(`[data-payment-days-v4324="${id}"]`)?.value||30)));
   try{
    button.disabled=true;
    button.textContent='Procesando…';
    await updateLicenseDraft(id,days,contract.total);
    await confirmPayment(id,days);
    await auditEvent(contract.license.organization_id,'license_payment_confirmed_v4331',{license_id:id,days,monthly_total:contract.total,module_count:contract.active.length,renewal:contract.license.payment_confirmed===true});
    toast('Pago confirmado, licencia actualizada y registro financiero creado.');
    await renderPaymentsV4324();
    await window.BHSC_REFRESH_PAYMENT_HISTORY_V4330?.();
   }catch(error){toast(error.message||'No se pudo confirmar el pago.');}
   finally{button.disabled=false;}
  });
  setTimeout(()=>window.setActiveNav?.('supervisorPayments'),0);
 }catch(error){
  r.innerHTML=page('CONTROL FINANCIERO','Facturación y pagos','₡20.000 por el panel administrativo más la suma de los precios configurados en cada módulo','home')+`<div class="empty-state"><strong>No se pudo cargar Pagos</strong><span>${esc(error.message)}</span></div>`;
 }
}

function wireModuleButtons(container=document){
 container.querySelectorAll?.('[data-open-modules-v4324]').forEach(button=>{
  if(button.dataset.boundV4324==='1')return;
  button.dataset.boundV4324='1';
  button.addEventListener('click',event=>{
   event.preventDefault();
   event.stopPropagation();
   const modal=button.closest('#adminProfileModalV4323');
   if(modal)modal.remove();
   openModuleContract(button.dataset.openModulesV4324);
  });
 });
}

const originalOrganizations=window.renderSupervisorOrganizations;
if(typeof originalOrganizations==='function'){
 window.renderSupervisorOrganizations=async function(...args){
  const out=await originalOrganizations.apply(this,args);
  await enhanceOrganizationCards();
  wireModuleButtons(root());
  return out;
 };
}

const originalOrganizationDetail=window.renderSupervisorOrganizationDetail;
if(typeof originalOrganizationDetail==='function'){
 window.renderSupervisorOrganizationDetail=async function(...args){
  const out=await originalOrganizationDetail.apply(this,args);
  enhanceModulePanel();
  wireModuleButtons(root());
  return out;
 };
}

const originalAdmins=window.renderSupervisorAdmins;
if(typeof originalAdmins==='function'){
 window.renderSupervisorAdmins=async function(...args){
  const out=await originalAdmins.apply(this,args);
  await enhanceAdminCards();
  wireModuleButtons(root());
  return out;
 };
}

window.renderSupervisorLicenses=renderLicensesV4324;
window.renderSupervisorPayments=renderPaymentsV4324;

const observer=new MutationObserver(records=>{
 if(!isSup())return;
 for(const record of records){
  for(const node of record.addedNodes){
   if(!(node instanceof Element))continue;
   if(node.id==='adminProfileModalV4323')enhanceAdminModal(node).then(()=>wireModuleButtons(node));
   else if(node.querySelector?.('#adminProfileModalV4323')){
    const modal=node.querySelector('#adminProfileModalV4323');
    enhanceAdminModal(modal).then(()=>wireModuleButtons(modal));
   }
  }
 }
 if(window.activeScreen==='supervisorOrganizationDetail')enhanceModulePanel();
 wireModuleButtons(document);
});
observer.observe(document.documentElement,{subtree:true,childList:true});

document.addEventListener('click',event=>{
 const button=event.target.closest?.('[data-open-modules-v4324]');
 if(!button)return;
 event.preventDefault();
 event.stopPropagation();
 const modal=button.closest('#adminProfileModalV4323');
 if(modal)modal.remove();
 openModuleContract(button.dataset.openModulesV4324);
},true);

window.BHSC_MODULE_BASE_PRICE=DEFAULT_PRICE;
window.BHSC_COMMERCIAL_MODULES_VERSION=VERSION;
console.info(`Supervisor módulos comerciales ${VERSION} listo`);
})();
