/* Bernard Health SeniorCare Enterprise V4.3.26
   Alertas seguras de medicación — exclusivo del módulo de Enfermería */
(()=>{
'use strict';
if(window.__BHSC_MEDICATION_ALERTS_V4326)return;
window.__BHSC_MEDICATION_ALERTS_V4326=true;

const VERSION='4.3.61';
const TIME_ZONE='America/Costa_Rica';
const CHECK_INTERVAL_MS=30_000;
const REFRESH_INTERVAL_MS=60_000;
const VAPID_PUBLIC_KEY=String(window.SENIORCARE_CONFIG?.VAPID_PUBLIC_KEY||'');
const state={doses:[],channel:null,org:null,lastRefresh:0,backendReady:true,focusDoseId:null,pushEnabled:false,audioUnlocked:false};
let alarmTimer=null;
let refreshTimer=null;
let audioContext=null;

const db=()=>window.seniorcareSupabase||null;
const user=()=>window.currentUser||null;
const org=()=>user()?.organizationId||user()?.organization_id||null;
const role=()=>String(user()?.role||'').toLowerCase();
const isNurse=()=>role()==='nurse';
const esc=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const toast=m=>window.showToast?.(m);
const meds=()=>Array.isArray(window.meds)?window.meds:[];
const getResidents=()=>Array.isArray(residents)?residents:[];
const residentKey=r=>String(r?.resident_key||r?.residentKey||r?.id||'');
const localDate=(value=new Date())=>window.BHSC_LOCAL_DATE?window.BHSC_LOCAL_DATE(value):new Intl.DateTimeFormat('en-CA',{timeZone:TIME_ZONE}).format(value);
const localTime=value=>value?new Date(value).toLocaleTimeString('es-CR',{timeZone:TIME_ZONE,hour:'2-digit',minute:'2-digit'}):'—';
const time12=value=>{if(!/^([01]\d|2[0-3]):[0-5]\d$/.test(String(value||'')))return String(value||'');const [h,m]=String(value).split(':').map(Number);return `${h%12||12}:${String(m).padStart(2,'0')} ${h>=12?'PM':'AM'}`;};
const localDateTime=value=>value?new Date(value).toLocaleString('es-CR',{timeZone:TIME_ZONE,dateStyle:'short',timeStyle:'short'}):'—';
const todayRange=()=>{
  const date=localDate();
  const start=new Date(`${date}T00:00:00-06:00`);
  const end=new Date(start.getTime()+86_400_000);
  return {date,start:start.toISOString(),end:end.toISOString()};
};
const effectiveAt=d=>new Date((d.status==='snoozed'&&d.snoozed_until)||d.scheduled_for||0).getTime();
const medByKey=key=>meds().find(m=>String(m.id)===String(key));
const doseDrug=d=>d.drug_name||medByKey(d.medication_key)?.drug||'Medicamento';
const doseAmount=d=>d.dose||medByKey(d.medication_key)?.dose||'';
const doseRoute=d=>d.route||medByKey(d.medication_key)?.route||'';
const doseResident=d=>d.resident_name||medByKey(d.medication_key)?.resident||'Residente';
function isMedicationFormOpen(){
  const form=document.getElementById('medicationForm');
  return !!form&&!form.classList.contains('hidden');
}

function statusInfo(d){
  if(d.status==='administered')return {key:'administered',label:'Administrado'};
  if(d.status==='not_administered')return {key:'not-administered',label:'No administrada'};
  const now=Date.now(),at=effectiveAt(d);
  if(d.status==='snoozed'&&at>now)return {key:'snoozed',label:`Pospuesta hasta ${localTime(d.snoozed_until)}`};
  if(at<=now-10*60_000)return {key:'overdue',label:'Pendiente'};
  if(at<=now)return {key:'due',label:'Pendiente'};
  if(at<=now+10*60_000)return {key:'soon',label:'Pendiente'};
  return {key:'scheduled',label:'Pendiente'};
}
function activeDoses(){return state.doses.filter(d=>['pending','snoozed'].includes(String(d.status||'')));}
function counts(){
  const result={due:0,overdue:0,upcoming:0,completed:0,notAdministered:0};
  state.doses.forEach(d=>{
    const s=statusInfo(d).key;
    if(s==='due')result.due++;
    else if(s==='overdue')result.overdue++;
    else if(['soon','scheduled','snoozed'].includes(s))result.upcoming++;
    else if(s==='administered')result.completed++;
    else if(s==='not-administered')result.notAdministered++;
  });
  return result;
}
function sortedDoses(){
  return [...state.doses].sort((a,b)=>{
    const terminal=x=>['administered','not_administered'].includes(x.status)?1:0;
    return terminal(a)-terminal(b)||effectiveAt(a)-effectiveAt(b);
  });
}
function isMissingBackend(error){
  return /does not exist|could not find the function|could not find the table|schema cache|PGRST202|42P01/i.test(String(error?.message||error||''));
}

async function generateToday(){
  if(!db()||!org()||!isNurse())return;
  const {date}=todayRange();
  const {error}=await db().rpc('bh_generate_medication_doses_v4326',{p_date:date});
  if(error)throw error;
}
async function loadDoses({rerender=false,quiet=false}={}){
  if(!db()||!org()||!isNurse())return [];
  try{
    await generateToday();
    const range=todayRange();
    const {data,error}=await db().from('seniorcare_medication_doses')
      .select('*')
      .eq('organization_id',org())
      .gte('scheduled_for',range.start)
      .lt('scheduled_for',range.end)
      .order('scheduled_for',{ascending:true});
    if(error)throw error;
    state.doses=data||[];
    state.backendReady=true;
    state.lastRefresh=Date.now();
    if(rerender&&window.activeScreen==='medications'&&!isMedicationFormOpen())window.render?.();
    if(window.activeScreen==='home')injectHomeWidget();
    return state.doses;
  }catch(error){
    state.backendReady=!isMissingBackend(error);
    if(!quiet)console.error('[BHSC medication alerts] No se pudieron cargar las dosis',error);
    if(!quiet&&!isMissingBackend(error))toast(error.message||'No se pudieron cargar las dosis programadas.');
    return [];
  }
}

function backendNotice(){
  if(state.backendReady)return '';
  return `<section class="med-alert-setup-warning"><strong>Alertas pendientes de activar</strong><span>Ejecute el SQL V4.3.26 en Supabase para habilitar la programación de dosis. Los medicamentos existentes siguen disponibles.</span></section>`;
}
function notificationState(){
  if(!('Notification' in window))return {key:'unsupported',label:'Este dispositivo no admite notificaciones web'};
  if(Notification.permission==='denied')return {key:'denied',label:'Notificaciones bloqueadas en el dispositivo'};
  if(Notification.permission!=='granted')return {key:'pending',label:'Alertas aún no activadas'};
  if(!state.pushEnabled)return {key:'local',label:'Permiso concedido · verificando dispositivo'};
  return {key:'enabled',label:'Alertas activas en este dispositivo'};
}
function renderAlertControls(){
  const ns=notificationState();
  return `<section class="med-alert-control ${ns.key}">
    <div class="med-alert-control-copy"><span>ALERTAS DE MEDICACIÓN</span><h3>${esc(ns.label)}</h3><p>Enfermería recibirá un aviso 10 minutos antes, a la hora programada y recordatorios mientras la dosis continúe pendiente.</p></div>
    <div class="med-alert-control-actions"><button class="primary-btn" id="enableMedicationAlerts">${ns.key==='enabled'?'Revalidar alertas':'Activar alertas'}</button><button class="secondary-btn" id="testMedicationAlerts">Probar sonido y aviso</button></div>
  </section>`;
}
function renderDoseSummary(){
  const c=counts();
  return `<section class="med-dose-summary">
    <article class="overdue"><span>Atrasadas</span><strong>${c.overdue}</strong><small>Requieren atención inmediata</small></article>
    <article class="due"><span>Pendientes ahora</span><strong>${c.due}</strong><small>Dentro de la hora indicada</small></article>
    <article class="upcoming"><span>Próximas</span><strong>${c.upcoming}</strong><small>Programadas para hoy</small></article>
    <article class="completed"><span>Administradas</span><strong>${c.completed}</strong><small>Confirmadas por Enfermería</small></article>
  </section>`;
}
function renderDoseCard(d){
  const info=statusInfo(d);
  const terminal=['administered','not_administered'].includes(d.status);
  const amount=doseAmount(d);
  const details=[amount,doseRoute(d)].filter(Boolean).join(' · ');
  const actual=d.administered_at?`Aplicada ${localTime(d.administered_at)} por ${esc(d.administered_by_name||'Enfermería')}`:d.not_administered_reason?esc(d.not_administered_reason):'';
  return `<article class="med-dose-card ${info.key}" data-dose-id="${esc(d.id)}">
    <div class="med-dose-time"><strong>${localTime(d.scheduled_for)}</strong><span>${esc(info.label)}</span></div>
    <div class="med-dose-copy"><span>${esc(doseResident(d))}</span><h3>${esc(doseDrug(d))}</h3><p>${esc(details||'Dosis según indicación')}${d.instructions?` · ${esc(d.instructions)}`:''}</p>${actual?`<small>${actual}</small>`:''}</div>
    ${terminal?'':`<div class="med-dose-actions"><button class="dose-action administered" data-dose-action="administered" data-dose-id="${esc(d.id)}">Administrar</button><button class="dose-action missed" data-dose-action="not_administered" data-dose-id="${esc(d.id)}">No administrada</button></div>`}
  </article>`;
}
function medicationForm(){
  const scoped=!!residentScoped;
  const selected=selectedResident;
  const today=localDate();
  return `<form class="form-card hidden med-schedule-form-v4326" id="medicationForm"><input type="hidden" name="medicationId"><div class="form-grid">
    ${scoped&&selected?`<input type="hidden" name="resident" value="${esc(selected.name)}"><label>Residente<input value="${esc(selected.name)}" disabled></label>`:`<label>Residente<select name="resident" required>${getResidents().map(r=>`<option>${esc(r.name)}</option>`).join('')}</select></label>`}
    <label>Medicamento<input name="drug" required placeholder="Ej. Losartán 50 mg"></label>
    <label>Dosis a administrar<input name="dose" required placeholder="Ej. 1 tableta"></label>
    <label>Frecuencia<select name="frequency" id="medFrequency"><option>Cada 6 horas</option><option>Cada 8 horas</option><option>Cada 12 horas</option><option>Cada 24 horas</option><option selected>Horarios específicos</option><option>Inmediato</option></select></label>
    <label class="wide" id="medTimesWrap">Horas de administración<input name="times" placeholder="Ej. 6:00 AM, 2:00 PM, 10:00 PM"><small>Puede usar AM/PM y separar varias horas con comas.</small></label>
    <label>Vía<select name="route"><option>VO</option><option>SC</option><option>IM</option><option>IV</option><option>Tópica</option><option>Inhalada</option><option>Otra</option></select></label>
    <label>Tipo de tratamiento<select name="treatmentType" id="medTreatmentType"><option value="continuous" selected>Continuo</option><option value="period">Por período</option><option value="single">Única dosis</option></select></label><input type="hidden" name="status" value="Pendiente">
    <label><span id="medStartDateLabel">Fecha de inicio</span><input type="date" name="startDate" value="${today}" required></label>
    <label id="medEndDateWrap" class="hidden">Fecha de finalización<input type="date" name="endDate"></label>
    <label class="wide med-reminder-toggle"><input type="checkbox" name="remindersEnabled" checked><span>Activar recordatorios para este medicamento</span></label>
    <input type="hidden" name="preAlertMinutes" value="10"><input type="hidden" name="repeatMinutes" value="5">
    <label class="wide">Indicaciones especiales<textarea name="instructions" rows="3" placeholder="Ej. Administrar después de alimentos"></textarea></label>
  </div><div class="form-actions"><button type="button" class="secondary-btn" id="cancelMedication">Cancelar</button><button class="primary-btn">Guardar medicamento y horarios</button></div></form>`;
}
function renderMedicationSchedules(){
  const scoped=!!residentScoped;
  const selected=selectedResident;
  const visible=scoped&&selected?meds().filter(m=>m.resident===selected.name):meds();
  return `<section class="med-schedules-section"><div class="med-section-head"><div><span>TRATAMIENTOS PROGRAMADOS</span><h2>Medicamentos y horarios</h2><p>${scoped&&selected?`Tratamiento de ${esc(selected.name)}`:'Configuración que genera las dosis diarias.'}</p></div><button class="primary-btn" id="addMedication">${svg?.plus||'+'} Añadir medicamento</button></div>
    ${medicationForm()}
    <div class="list-stack">${visible.length?visible.map(m=>{
      const reminder=m.remindersEnabled!==false&&!m.immediate;
      const details=[m.dose,medicationScheduleLabel?.(m)||'',m.route].filter(Boolean).join(' · ');
      const todayDoses=state.doses.filter(d=>String(d.medication_key)===String(m.id));
      const pendingDoses=todayDoses.filter(d=>['pending','snoozed'].includes(String(d.status||'')));
      const administeredDoses=todayDoses.filter(d=>String(d.status||'')==='administered');
      const notAdministeredDoses=todayDoses.filter(d=>String(d.status||'')==='not_administered');
      let displayStatus='Sin dosis hoy';
      let statusClass='status-neutral-v4350';
      if(pendingDoses.length&&administeredDoses.length){
        displayStatus=`${administeredDoses.length} administrada${administeredDoses.length===1?'':'s'} · ${pendingDoses.length} pendiente${pendingDoses.length===1?'':'s'}`;
        statusClass='status-mixed-v4351';
      }else if(pendingDoses.length){
        displayStatus=`${pendingDoses.length} pendiente${pendingDoses.length===1?'':'s'} hoy`;
        statusClass='status-pending-v4345';
      }else if(administeredDoses.length&&administeredDoses.length+notAdministeredDoses.length===todayDoses.length){
        displayStatus=notAdministeredDoses.length
          ?`${administeredDoses.length} administrada${administeredDoses.length===1?'':'s'} · ${notAdministeredDoses.length} no administrada${notAdministeredDoses.length===1?'':'s'}`
          :`${administeredDoses.length} administrada${administeredDoses.length===1?'':'s'} hoy`;
        statusClass=notAdministeredDoses.length?'status-mixed-v4351':'status-completed-v4345';
      }else if(notAdministeredDoses.length){
        displayStatus=`${notAdministeredDoses.length} no administrada${notAdministeredDoses.length===1?'':'s'}`;
        statusClass='status-not-administered-v4350';
      }
      const statusHtml=`<span class="status-pill treatment-dose-summary-v4351 ${statusClass}">${displayStatus}</span>`;
      return `<article class="data-row medication-row med-schedule-row-v4326"><div class="time-badge">${m.immediate?'Ahora':esc(time12((medicationTimes?.(m)||[])[0]||'--'))}</div><div class="row-main"><strong>${esc(scoped?m.drug:m.resident)}</strong><span>${esc(scoped?details:`${m.drug} · ${details}`)}</span><small>${reminder?'Alertas activas':'Sin recordatorios'}${m.startDate?` · Desde ${esc(m.startDate)}`:''}${m.endDate?` hasta ${esc(m.endDate)}`:''}</small></div>${statusHtml}<div class="card-actions"><button class="mini-btn" data-med-edit="${esc(m.id)}">Editar</button><button class="icon-delete" data-med-delete="${esc(m.id)}">×</button></div></article>`;
    }).join(''):(empty?.('No hay medicamentos programados.')||'<p>No hay medicamentos programados.</p>')}</div></section>`;
}
function renderNurseMedications(){
  const scoped=!!residentScoped;
  const selected=selectedResident;
  const subtitle=scoped&&selected?`Dosis y tratamiento de ${selected.name}`:'Programación, alertas y administración segura de dosis';
  const list=sortedDoses().filter(d=>['pending','snoozed'].includes(String(d.status||'')));
  main.innerHTML=pageHeader('SEGURIDAD DE MEDICACIÓN','Medicamentos',subtitle)+backendNotice()+renderAlertControls()+renderDoseSummary()+`
    <section class="med-dose-section"><div class="med-section-head"><div><span>DOSIS DEL DÍA</span><h2>Medicamentos por administrar</h2><p>La confirmación queda registrada con usuario, hora real y resultado.</p></div><button class="secondary-btn" id="refreshMedicationDoses">Actualizar</button></div>
    <div class="med-dose-list">${list.length?list.map(renderDoseCard).join(''):(empty?.('No hay medicamentos pendientes por administrar.')||'<p>No hay medicamentos pendientes por administrar.</p>')}</div></section>
    ${renderMedicationSchedules()}`;
  requestAnimationFrame(()=>{
    const target=state.focusDoseId&&[...document.querySelectorAll('[data-dose-id]')].find(el=>String(el.dataset.doseId)===String(state.focusDoseId));
    if(target){target.classList.add('focused-dose-v4326');target.scrollIntoView({behavior:'smooth',block:'center'});state.focusDoseId=null;}
  });
}

const originalRenderMedications=window.renderMedications;
if(typeof originalRenderMedications==='function'){
  window.renderMedications=function(...args){
    if(!isNurse())return originalRenderMedications.apply(this,args);
    return renderNurseMedications();
  };
  try{renderMedications=window.renderMedications;}catch(_){ }
}

function injectHomeWidget(){
  if(!isNurse()||window.activeScreen!=='home')return;
  const root=document.getElementById('mainContent');
  if(!root)return;
  root.querySelector('[data-med-home-widget-v4326]')?.remove();
  const c=counts();
  const section=document.createElement('section');
  section.dataset.medHomeWidgetV4326='1';
  section.className=`med-home-widget-v4326 ${(c.overdue||c.due)?'attention':''}`;
  section.innerHTML=`<button data-go="medications"><div><span>MEDICACIÓN DEL TURNO</span><h3>${c.overdue?`${c.overdue} dosis atrasada${c.overdue===1?'':'s'}`:c.due?`${c.due} dosis pendiente${c.due===1?'':'s'} ahora`:'Dosis del día controladas'}</h3><p>${c.upcoming} próxima${c.upcoming===1?'':'s'} · ${c.completed} administrada${c.completed===1?'':'s'}</p></div><strong>Ver dosis ›</strong></button>`;
  const clock=root.querySelector('.self-clock-card');
  if(clock)clock.insertAdjacentElement('afterend',section);else root.prepend(section);
  section.querySelector('[data-go]')?.addEventListener('click',()=>window.go?.('medications'));
}
const originalRenderHome=window.renderHome;
if(typeof originalRenderHome==='function'){
  window.renderHome=function(...args){const out=originalRenderHome.apply(this,args);if(isNurse())requestAnimationFrame(injectHomeWidget);return out;};
  try{renderHome=window.renderHome;}catch(_){ }
}

function base64UrlToUint8Array(value){
  const padding='='.repeat((4-value.length%4)%4);
  const base64=(value+padding).replace(/-/g,'+').replace(/_/g,'/');
  const raw=atob(base64);return Uint8Array.from([...raw].map(c=>c.charCodeAt(0)));
}
function arrayBufferToBase64Url(buffer){
  const bytes=new Uint8Array(buffer);let binary='';bytes.forEach(b=>binary+=String.fromCharCode(b));
  return btoa(binary).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'');
}
async function registerSubscription(subscription){
  const json=subscription.toJSON();
  const p256dh=json.keys?.p256dh||arrayBufferToBase64Url(subscription.getKey('p256dh'));
  const auth=json.keys?.auth||arrayBufferToBase64Url(subscription.getKey('auth'));
  const {error}=await db().rpc('bh_register_push_subscription_v4326',{
    p_endpoint:subscription.endpoint,
    p_p256dh:p256dh,
    p_auth:auth,
    p_user_agent:navigator.userAgent,
    p_device_label:`${navigator.platform||'Dispositivo'} · ${/Mobile|Android|iPhone|iPad/i.test(navigator.userAgent)?'Móvil/Tablet':'Computadora'}`
  });
  if(error)throw error;
}
async function ensurePushSubscription({requestPermission=true}={}){
  if(!isNurse())throw new Error('Las alertas de medicación están disponibles únicamente para Enfermería.');
  if(!('serviceWorker' in navigator)||!('PushManager' in window)||!('Notification' in window))throw new Error('Este dispositivo no admite notificaciones Push. Mantenga SeniorCare abierto para recibir la alarma interna.');
  let permission=Notification.permission;
  if(permission==='default'&&requestPermission)permission=await Notification.requestPermission();
  if(permission!=='granted')throw new Error(permission==='denied'?'Las notificaciones están bloqueadas. Actívelas en la configuración del dispositivo.':'Debe permitir las notificaciones para activar las alertas.');
  if(!VAPID_PUBLIC_KEY)throw new Error('Falta la clave pública de notificaciones.');
  const registration=await navigator.serviceWorker.ready;
  let subscription=await registration.pushManager.getSubscription();
  if(!subscription){subscription=await registration.pushManager.subscribe({userVisibleOnly:true,applicationServerKey:base64UrlToUint8Array(VAPID_PUBLIC_KEY)});}
  await registerSubscription(subscription);
  state.pushEnabled=true;
  unlockAudio();
  return subscription;
}
async function detectSubscription(){
  if(!isNurse()||!('serviceWorker' in navigator)||!('PushManager' in window)||!('Notification' in window)||Notification.permission!=='granted'){state.pushEnabled=false;return;}
  try{const reg=await navigator.serviceWorker.ready;const sub=await reg.pushManager.getSubscription();state.pushEnabled=!!sub;if(sub)await registerSubscription(sub);}catch(error){console.warn('[BHSC medication alerts] suscripción',error);state.pushEnabled=false;}
}
function unlockAudio(){
  try{audioContext=audioContext||new (window.AudioContext||window.webkitAudioContext)();audioContext.resume?.();state.audioUnlocked=true;}catch(_){state.audioUnlocked=false;}
}
function playAlarmPattern(){
  unlockAudio();
  if(!audioContext||audioContext.state==='suspended')return;
  [0,420,840].forEach((delay,index)=>setTimeout(()=>{
    try{
      const oscillator=audioContext.createOscillator();const gain=audioContext.createGain();
      oscillator.type='sine';oscillator.frequency.value=index===1?880:740;gain.gain.setValueAtTime(0.0001,audioContext.currentTime);gain.gain.exponentialRampToValueAtTime(0.22,audioContext.currentTime+0.02);gain.gain.exponentialRampToValueAtTime(0.0001,audioContext.currentTime+0.28);oscillator.connect(gain).connect(audioContext.destination);oscillator.start();oscillator.stop(audioContext.currentTime+0.3);
    }catch(_){ }
  },delay));
}
async function showSystemNotification(dose,{test=false,pre=false}={}){
  if(!('Notification' in window)||Notification.permission!=='granted'||!('serviceWorker' in navigator))return;
  const reg=await navigator.serviceWorker.ready;
  await reg.showNotification(test?'Prueba de alertas SeniorCare':pre?'Dosis próxima':'Dosis de medicamento pendiente',{
    body:test?'El dispositivo está listo para recibir avisos de Enfermería.':'Abra SeniorCare para revisar y confirmar la dosis.',
    icon:'/assets/icon-192.png',badge:'/assets/icon-192.png',tag:test?'bhsc-med-test':`bhsc-med-${dose?.id||'dose'}`,renotify:!pre,requireInteraction:!pre,vibrate:pre?[100]:[250,120,250,120,350],data:{url:`/?medDose=${encodeURIComponent(dose?.id||'')}`,doseId:dose?.id||null}
  });
}
function localAlarmKey(dose){return `seniorcare-medication-alarm-${dose.id}`;}
function shouldLocalAlarm(dose){
  const last=Number(localStorage.getItem(localAlarmKey(dose))||0);
  return Date.now()-last>=4*60_000;
}
function markLocalAlarm(dose){localStorage.setItem(localAlarmKey(dose),String(Date.now()));}
function closeAlarmOverlay(){
  document.querySelector('.medication-alarm-overlay-v4326')?.remove();
  document.body.classList.remove('medication-alarm-open-v4326');
}
function showAlarmOverlay(dose){
  if(document.querySelector('.medication-alarm-overlay-v4326'))return;
  const overlay=document.createElement('div');overlay.className='medication-alarm-overlay-v4326';overlay.dataset.alarmDoseId=dose.id;
  overlay.innerHTML=`<div class="medication-alarm-card-v4326"><div class="medication-alarm-icon-v4326">${svg?.bell||'!'}</div><span>ALERTA DE MEDICACIÓN</span><h2>${esc(doseResident(dose))}</h2><h3>${esc(doseDrug(dose))}</h3><p>${esc([doseAmount(dose),doseRoute(dose)].filter(Boolean).join(' · ')||'Dosis según indicación')} · Programada ${localTime(dose.scheduled_for)}</p><div class="medication-alarm-actions-v4326"><button type="button" data-alarm-dose-action="administered" data-dose-id="${esc(dose.id)}">Administrar</button><button type="button" data-alarm-dose-action="not_administered" data-dose-id="${esc(dose.id)}">No administrar</button></div></div>`;
  document.body.appendChild(overlay);
  document.body.classList.add('medication-alarm-open-v4326');
}
async function checkForegroundAlarms(){
  if(!isNurse()||!user()?.id)return;
  if(Date.now()-state.lastRefresh>REFRESH_INTERVAL_MS)await loadDoses({quiet:true});
  const now=Date.now();
  const due=activeDoses().filter(d=>effectiveAt(d)<=now).sort((a,b)=>effectiveAt(a)-effectiveAt(b));
  if(!due.length)return;
  const dose=due[0];
  if(!shouldLocalAlarm(dose))return;
  markLocalAlarm(dose);playAlarmPattern();showAlarmOverlay(dose);showSystemNotification(dose).catch(()=>{});
}
async function updateDose(id,action,button=null,reasonOverride=null){
  if(!id)throw new Error('No se encontró la dosis que desea actualizar.');
  const dose=state.doses.find(d=>String(d.id)===String(id))||{id};
  let reason=reasonOverride;
  if(action==='not_administered'&&!reason){
    reason=prompt('Motivo de no administración (obligatorio):','Paciente rechazó');
    if(!reason?.trim())return false;
  }
  const originalText=button?.textContent||'';
  if(button){button.disabled=true;button.setAttribute('aria-busy','true');button.textContent='Guardando…';}
  try{
    const client=db();
    if(!client)throw new Error('No hay conexión disponible con Supabase.');
    const runRpc=async()=>{
      const result=await client.rpc('bh_update_medication_dose_v4326',{
        p_dose_id:id,
        p_action:action,
        p_reason:reason,
        p_notes:null
      });
      if(result?.error)throw result.error;
      return result;
    };
    try{
      if(window.BHSC_WITH_RETRY)await window.BHSC_WITH_RETRY(runRpc,2,700);
      else await runRpc();
    }catch(rpcError){
      if(window.BHSC_IS_NETWORK_ERROR?.(rpcError))throw rpcError;
      const now=new Date().toISOString();
      const profile=user();
      const payload={
        status:action==='administered'?'administered':'not_administered',
        snoozed_until:null,
        administered_at:action==='administered'?now:null,
        administered_by:action==='administered'?(profile?.id||null):null,
        administered_by_name:action==='administered'?(profile?.name||profile?.fullName||'Enfermería'):null,
        not_administered_reason:action==='not_administered'?reason:null,
        updated_at:now
      };
      const {error}=await client.from('seniorcare_medication_doses').update(payload).eq('id',id).eq('organization_id',org());
      if(error)throw error;
    }
    closeAlarmOverlay();
    localStorage.removeItem(localAlarmKey(dose));
    await loadDoses({rerender:true,quiet:true});
    toast(action==='administered'?'Dosis registrada como administrada.':'Dosis registrada como no administrada.');
    return true;
  }catch(error){
    closeAlarmOverlay();
    console.error('[BHSC medication dose]',error);
    const message=window.BHSC_FRIENDLY_ERROR?.(error,'No se pudo actualizar la dosis.')||error.message||'No se pudo actualizar la dosis.';
    toast(`${message} La dosis continúa pendiente.`);
    return false;
  }finally{
    if(button&&button.isConnected){button.disabled=false;button.removeAttribute('aria-busy');button.textContent=originalText;}
  }
}

function updateTreatmentFields(){
  const f=document.getElementById('medicationForm');if(!f)return;
  const type=f.elements.treatmentType?.value||'continuous';
  const period=type==='period',single=type==='single';
  document.getElementById('medEndDateWrap')?.classList.toggle('hidden',!period);
  const label=document.getElementById('medStartDateLabel');if(label)label.textContent=single?'Fecha de la dosis':'Fecha de inicio';
  if(f.elements.endDate){f.elements.endDate.required=period;if(!period)f.elements.endDate.value='';}
  if(single&&f.elements.frequency)f.elements.frequency.value='Horarios específicos';
}
window.BHSC_UPDATE_MED_TREATMENT_FIELDS=updateTreatmentFields;
document.addEventListener('change',event=>{if(event.target?.id==='medTreatmentType')updateTreatmentFields();},true);
document.addEventListener('click',event=>{if(event.target?.closest?.('#addMedication'))setTimeout(updateTreatmentFields,0);},true);

async function start(){
  if(!isNurse()||!db()||!org()){stop();return;}
  if(state.org!==org()){
    if(state.channel)try{await db().removeChannel(state.channel);}catch(_){ }
    state.org=org();
    state.channel=db().channel(`bhsc-medication-doses-${org()}`).on('postgres_changes',{event:'*',schema:'public',table:'seniorcare_medication_doses',filter:`organization_id=eq.${org()}`},()=>loadDoses({rerender:window.activeScreen==='medications'&&!isMedicationFormOpen(),quiet:true})).subscribe();
  }
  await detectSubscription();
  await loadDoses({rerender:window.activeScreen==='medications'&&!isMedicationFormOpen(),quiet:true});
  clearInterval(alarmTimer);alarmTimer=setInterval(()=>checkForegroundAlarms().catch(console.warn),CHECK_INTERVAL_MS);
  clearInterval(refreshTimer);refreshTimer=setInterval(()=>loadDoses({rerender:false,quiet:true}),REFRESH_INTERVAL_MS);
  checkForegroundAlarms().catch(()=>{});
}
function stop(){clearInterval(alarmTimer);clearInterval(refreshTimer);alarmTimer=null;refreshTimer=null;state.doses=[];state.org=null;}

window.BHSC_MED_ALERTS_AFTER_MED_SAVE=async()=>{await loadDoses({rerender:window.activeScreen==='medications'&&!isMedicationFormOpen(),quiet:true});};
window.BHSC_MEDICATION_ALERTS={version:VERSION,load:loadDoses,enable:ensurePushSubscription,test:()=>showSystemNotification(null,{test:true}),state};

window.addEventListener('pointerup',event=>{
  const button=event.target?.closest?.('[data-alarm-dose-action]');
  if(!button)return;
  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();
  const action=button.dataset.alarmDoseAction;
  const reason=action==='not_administered'?'No administrada desde la alerta de medicación':null;
  updateDose(button.dataset.doseId,action,button,reason).catch(error=>{
    console.error('[BHSC alarm direct action]',error);
    closeAlarmOverlay();
    toast('No se pudo registrar la dosis. Continúa pendiente.');
  });
},true);

document.addEventListener('click',event=>{
  const enable=event.target.closest?.('#enableMedicationAlerts');
  const test=event.target.closest?.('#testMedicationAlerts');
  const refresh=event.target.closest?.('#refreshMedicationDoses');
  const action=event.target.closest?.('[data-dose-action]');
  const edit=event.target.closest?.('[data-med-edit]');
  if(enable){event.preventDefault();ensurePushSubscription().then(()=>{toast('Alertas activadas en este dispositivo.');if(window.activeScreen==='medications')window.render?.();}).catch(error=>{console.error(error);toast(window.BHSC_FRIENDLY_ERROR?.(error,'No se pudieron activar las alertas.')||error.message||'No se pudieron activar las alertas.');});}
  if(test){event.preventDefault();(async()=>{try{await ensurePushSubscription();playAlarmPattern();await showSystemNotification(null,{test:true});toast('Prueba enviada. Verifique sonido y notificación.');}catch(error){toast(window.BHSC_FRIENDLY_ERROR?.(error,'No se pudo realizar la prueba.')||error.message||'No se pudo realizar la prueba.');}})();}
  if(refresh){event.preventDefault();loadDoses({rerender:!isMedicationFormOpen()}).then(()=>toast('Dosis actualizadas.'));}
  if(action){
    event.preventDefault();
    event.stopPropagation();
    event.stopImmediatePropagation();
    updateDose(action.dataset.doseId,action.dataset.doseAction,action);
  }
  const add=event.target.closest?.('#addMedication');
  const cancel=event.target.closest?.('#cancelMedication');
  if(add&&isNurse()){
    event.preventDefault();event.stopPropagation();event.stopImmediatePropagation();
    const f=document.getElementById('medicationForm');
    if(f){f.reset();if(f.elements.medicationId)f.elements.medicationId.value='';f.classList.remove('hidden');updateTreatmentFields();f.scrollIntoView({behavior:'smooth',block:'start'});}
    return;
  }
  if(cancel&&isNurse()){
    event.preventDefault();event.stopPropagation();event.stopImmediatePropagation();
    const f=document.getElementById('medicationForm');if(f){f.reset();if(f.elements.medicationId)f.elements.medicationId.value='';f.classList.add('hidden');}
    return;
  }
  if(edit&&isNurse()){
    event.preventDefault();
    event.stopPropagation();
    event.stopImmediatePropagation();
    const m=meds().find(x=>String(x.id)===String(edit.dataset.medEdit));
    const f=document.getElementById('medicationForm');
    if(!m||!f){toast('No se pudo abrir este tratamiento para editar.');return;}
    f.classList.remove('hidden');
    if(f.elements.medicationId)f.elements.medicationId.value=m.id||'';
    if(f.elements.resident)f.elements.resident.value=m.resident||'';
    if(f.elements.drug)f.elements.drug.value=m.drug||'';
    if(f.elements.dose)f.elements.dose.value=m.dose||'';
    if(f.elements.frequency)f.elements.frequency.value=m.immediate?'Inmediato':(m.frequency||'Horarios específicos');
    if(f.elements.times)f.elements.times.value=(m.times||[]).map(time12).join(', ');
    if(f.elements.route)f.elements.route.value=m.route||'VO';
    if(f.elements.status)f.elements.status.value='Pendiente';
    if(f.elements.treatmentType)f.elements.treatmentType.value=m.treatmentType||(m.endDate?'period':'continuous');
    if(f.elements.startDate)f.elements.startDate.value=m.startDate||localDate();
    if(f.elements.endDate)f.elements.endDate.value=m.endDate||'';
    if(f.elements.remindersEnabled)f.elements.remindersEnabled.checked=m.remindersEnabled!==false;
    if(f.elements.instructions)f.elements.instructions.value=m.instructions||'';
    updateTreatmentFields();
    f.scrollIntoView({behavior:'smooth',block:'start'});
    return;
  }
},true);

document.addEventListener('visibilitychange',()=>{if(!document.hidden&&isNurse()){loadDoses({rerender:window.activeScreen==='medications'&&!isMedicationFormOpen(),quiet:true});checkForegroundAlarms().catch(()=>{});}});
window.addEventListener('online',()=>isNurse()&&loadDoses({rerender:window.activeScreen==='medications'&&!isMedicationFormOpen(),quiet:true}));
window.addEventListener('seniorcare:user-ready',start);
window.addEventListener('message',event=>{if(event.data?.type==='OPEN_MEDICATION_DOSE'){state.focusDoseId=event.data.doseId;window.go?.('medications');loadDoses({rerender:true,quiet:true});}});
navigator.serviceWorker?.addEventListener?.('message',event=>{if(event.data?.type==='OPEN_MEDICATION_DOSE'){state.focusDoseId=event.data.doseId;window.go?.('medications');loadDoses({rerender:true,quiet:true});}});

const params=new URLSearchParams(location.search);
if(params.get('medDose'))state.focusDoseId=params.get('medDose');
window.addEventListener('load',()=>setTimeout(()=>{if(isNurse())start();},1800));
console.info(`Alertas de medicación ${VERSION} listas`);
})();
