/* Bernard Health SeniorCare Enterprise V4.3.67 — Agenda médica aislada · regreso médico */
(function(){
  'use strict';

  const TABLE='seniorcare_medical_appointments';
  const CR_TZ='America/Costa_Rica';
  const state={
    month:firstOfMonth(new Date()),
    selectedDate:localDate(),
    appointments:[],
    doctors:[],
    residents:[],
    loading:false,
    initialized:false,
    formOpen:false,
    editingId:null,
    channel:null,
    pendingRefresh:false,
    filters:{doctor:'all',status:'all'}
  };

  const svg={
    calendar:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 2v3M17 2v3M3.5 9.2h17M5.5 4h13a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',
    plus:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>',
    chevron:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m9 5 7 7-7 7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
    back:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m15 5-7 7 7 7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',
    clock:'<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M12 7v5l3 2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',
    user:'<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="8" r="3.4" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M5 20c.7-4 3-6 7-6s6.3 2 7 6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>',
    location:'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 21s7-6.3 7-12a7 7 0 1 0-14 0c0 5.7 7 12 7 12Z" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="12" cy="9" r="2.2" fill="none" stroke="currentColor" stroke-width="1.8"/></svg>'
  };

  function user(){return window.currentUser||{};}
  function role(){return String(user().role||'').toLowerCase();}
  function org(){return user().organizationId||user().organization_id||null;}
  function db(){return window.seniorcareSupabase;}
  function main(){return document.getElementById('mainContent')||window.main;}
  function toast(message){if(typeof window.showToast==='function')window.showToast(message);else alert(message);}
  function esc(value){return String(value??'').replace(/[&<>"']/g,ch=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[ch]));}
  function attr(value){return esc(value).replace(/`/g,'&#96;');}
  function localDate(date=new Date()){
    return new Intl.DateTimeFormat('en-CA',{timeZone:CR_TZ,year:'numeric',month:'2-digit',day:'2-digit'}).format(date);
  }
  function firstOfMonth(date){return new Date(date.getFullYear(),date.getMonth(),1,12,0,0,0);}
  function isoDate(date){return `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`;}
  function parseDate(value){const [y,m,d]=String(value||'').split('-').map(Number);return new Date(y,m-1,d,12,0,0,0);}
  function monthTitle(date){return new Intl.DateTimeFormat('es-CR',{month:'long',year:'numeric'}).format(date).replace(/^./,c=>c.toUpperCase());}
  function dayTitle(value){return new Intl.DateTimeFormat('es-CR',{weekday:'long',day:'numeric',month:'long',year:'numeric'}).format(parseDate(value)).replace(/^./,c=>c.toUpperCase());}
  function timeLabel(value){return String(value||'').slice(0,5)||'--:--';}
  function friendly(error,fallback='No se pudo completar la operación.'){
    const text=String(error?.message||error||'').trim();
    if(/could not find the table|relation .* does not exist|schema cache/i.test(text))return 'La Agenda médica todavía no está activada en Supabase. Ejecute el SQL incluido con esta versión.';
    if(/duplicate key|medical_appointments_doctor_slot|horario se superpone/i.test(text))return 'Ese médico ya tiene otra cita que coincide con ese horario.';
    if(/failed to fetch|networkerror|load failed|offline/i.test(text))return 'No se pudo conectar con Supabase. Revise la conexión e inténtelo nuevamente.';
    return text||fallback;
  }
  function isAdmin(){return ['admin','administrator','supervisor'].includes(role());}
  function isDoctor(){return role()==='doctor';}
  function currentScreen(){return String(window.activeScreen||'');}
  function screenIsAgenda(){return ['medicalAppointmentsAdmin','medicalAppointmentsDoctor'].includes(currentScreen());}
  function statusClass(status){
    const s=String(status||'Programada').toLowerCase();
    if(s.includes('atendida'))return 'done';
    if(s.includes('cancel'))return 'cancelled';
    if(s.includes('presentó')||s.includes('no asist'))return 'missed';
    if(s.includes('confirm'))return 'confirmed';
    return 'scheduled';
  }
  function residentName(key,stored){return stored||state.residents.find(r=>String(r.key)===String(key))?.name||'Paciente';}
  function doctorName(id,stored){return stored||state.doctors.find(d=>String(d.id)===String(id))?.name||'Médico';}
  function normalizeAppointment(row){return {...row,start_time:timeLabel(row.start_time),duration_minutes:Number(row.duration_minutes)||30};}

  async function loadResidents(){
    const result=await db().from('seniorcare_residents').select('*').eq('organization_id',org()).eq('active',true);
    if(result.error)throw result.error;
    state.residents=(result.data||[]).map(r=>({key:String(r.resident_key||r.id),name:r.full_name||r.name||r.data?.name||'Residente',room:r.room||r.data?.room||''})).sort((a,b)=>a.name.localeCompare(b.name,'es'));
  }
  async function loadDoctors(){
    if(isDoctor()){
      state.doctors=[{id:user().id,name:user().name||user().email||'Médico'}];
      return;
    }
    const result=await db().from('profiles').select('*').eq('organization_id',org()).eq('active',true).eq('role','doctor');
    if(result.error)throw result.error;
    state.doctors=(result.data||[]).map(p=>({id:p.id,name:p.full_name||p.name||'Médico'})).sort((a,b)=>a.name.localeCompare(b.name,'es'));
  }
  function monthRange(){
    const start=isoDate(new Date(state.month.getFullYear(),state.month.getMonth(),1,12));
    const end=isoDate(new Date(state.month.getFullYear(),state.month.getMonth()+1,0,12));
    return {start,end};
  }
  async function loadAppointments(){
    const {start,end}=monthRange();
    let query=db().from(TABLE).select('*').eq('organization_id',org()).eq('active',true).gte('appointment_date',start).lte('appointment_date',end).order('appointment_date',{ascending:true}).order('start_time',{ascending:true});
    if(isDoctor())query=query.eq('doctor_id',user().id);
    const result=await query;
    if(result.error)throw result.error;
    state.appointments=(result.data||[]).map(normalizeAppointment);
  }
  async function loadAll(){
    if(!db())throw new Error('Supabase no está disponible.');
    if(!org())throw new Error('La organización de esta cuenta no está disponible.');
    state.loading=true;
    try{
      if(isDoctor()){
        state.residents=[];
        await Promise.all([loadDoctors(),loadAppointments()]);
      }else{
        await Promise.all([loadResidents(),loadDoctors(),loadAppointments()]);
      }
      state.initialized=true;
    }finally{state.loading=false;}
  }

  function subscribe(){
    if(!db()||!org())return;
    try{if(state.channel)db().removeChannel(state.channel);}catch(_e){}
    state.channel=db().channel(`bhsc-medical-agenda-${org()}-${user().id||'user'}`)
      .on('postgres_changes',{event:'*',schema:'public',table:TABLE,filter:`organization_id=eq.${org()}`},async()=>{
        try{
          await loadAppointments();
          if(state.formOpen){state.pendingRefresh=true;return;}
          if(screenIsAgenda())renderCurrent();
        }catch(error){console.warn('[BHSC Agenda] No se pudo actualizar en tiempo real:',error);}
      }).subscribe();
  }

  function filterAppointments(list){
    return list.filter(a=>(state.filters.doctor==='all'||String(a.doctor_id)===state.filters.doctor)&&(state.filters.status==='all'||String(a.status)===state.filters.status));
  }
  function appointmentsForDate(date){return filterAppointments(state.appointments).filter(a=>a.appointment_date===date).sort((a,b)=>String(a.start_time).localeCompare(String(b.start_time)));}
  function visibleMonthAppointments(){return filterAppointments(state.appointments);}
  function monthGrid(){
    const first=new Date(state.month.getFullYear(),state.month.getMonth(),1,12);
    const mondayOffset=(first.getDay()+6)%7;
    const start=new Date(first);start.setDate(first.getDate()-mondayOffset);
    return Array.from({length:42},(_,i)=>{const d=new Date(start);d.setDate(start.getDate()+i);return d;});
  }
  function calendarHtml(){
    const today=localDate();
    return `<section class="bh-agenda-calendar-card">
      <div class="bh-agenda-calendar-head">
        <button type="button" class="bh-agenda-icon-btn" data-agenda-month="prev" aria-label="Mes anterior">${svg.back}</button>
        <div><span>CALENDARIO MÉDICO</span><h3>${esc(monthTitle(state.month))}</h3></div>
        <button type="button" class="bh-agenda-icon-btn next" data-agenda-month="next" aria-label="Mes siguiente">${svg.chevron}</button>
      </div>
      <div class="bh-agenda-weekdays">${['Lun','Mar','Mié','Jue','Vie','Sáb','Dom'].map(x=>`<span>${x}</span>`).join('')}</div>
      <div class="bh-agenda-month-grid">${monthGrid().map(date=>{
        const value=isoDate(date),dayAppointments=appointmentsForDate(value),outside=date.getMonth()!==state.month.getMonth();
        return `<button type="button" class="bh-agenda-day${outside?' outside':''}${value===state.selectedDate?' selected':''}${value===today?' today':''}" data-agenda-date="${value}">
          <span class="bh-agenda-day-number">${date.getDate()}</span>
          <span class="bh-agenda-day-events">${dayAppointments.slice(0,2).map(a=>`<i class="${statusClass(a.status)}"><b>${esc(timeLabel(a.start_time))}</b>${esc(residentName(a.resident_key,a.resident_name).split(' ')[0])}</i>`).join('')}${dayAppointments.length>2?`<em>+${dayAppointments.length-2} más</em>`:''}</span>
        </button>`;
      }).join('')}</div>
    </section>`;
  }
  function appointmentCard(a,mode){
    const name=residentName(a.resident_key,a.resident_name),doc=doctorName(a.doctor_id,a.doctor_name);
    return `<article class="bh-agenda-appointment ${statusClass(a.status)}">
      <div class="bh-agenda-time"><strong>${esc(timeLabel(a.start_time))}</strong><span>${a.duration_minutes} min</span></div>
      <div class="bh-agenda-appt-main">
        <div class="bh-agenda-appt-title"><strong>${esc(name)}</strong><span class="bh-agenda-status ${statusClass(a.status)}">${esc(a.status||'Programada')}</span></div>
        <p>${esc(a.appointment_type||'Consulta médica')}${a.reason?` · ${esc(a.reason)}`:''}</p>
        <small>${svg.user}${esc(doc)}${a.location?`<span>${svg.location}${esc(a.location)}</span>`:''}</small>
      </div>
      <div class="bh-agenda-appt-actions">${mode==='admin'?`<button type="button" data-agenda-edit="${attr(a.id)}">Editar</button><button type="button" class="danger" data-agenda-delete="${attr(a.id)}">Eliminar</button>`:`${!['Atendida','Cancelada','No se presentó'].includes(a.status)?`<button type="button" class="success" data-agenda-status="Atendida" data-agenda-id="${attr(a.id)}">Atendida</button><button type="button" data-agenda-status="No se presentó" data-agenda-id="${attr(a.id)}">No se presentó</button>`:''}`}</div>
    </article>`;
  }
  function dayPanel(mode){
    const list=appointmentsForDate(state.selectedDate);
    return `<aside class="bh-agenda-day-panel">
      <div class="bh-agenda-day-head"><div><span>AGENDA DEL DÍA</span><h3>${esc(dayTitle(state.selectedDate))}</h3></div><b>${list.length}</b></div>
      <div class="bh-agenda-day-list">${list.length?list.map(a=>appointmentCard(a,mode)).join(''):`<div class="bh-agenda-empty">${svg.calendar}<strong>Sin citas programadas</strong><span>${mode==='admin'?'Seleccione “Nueva cita” para asignar un paciente.':'No tiene pacientes asignados para esta fecha.'}</span></div>`}</div>
    </aside>`;
  }
  function statsHtml(mode){
    const all=visibleMonthAppointments(),today=appointmentsForDate(localDate()),done=all.filter(a=>a.status==='Atendida').length,scheduled=all.filter(a=>['Programada','Confirmada'].includes(a.status)).length;
    const next=[...all].filter(a=>`${a.appointment_date}T${timeLabel(a.start_time)}`>=`${localDate()}T00:00`).sort((a,b)=>`${a.appointment_date}${a.start_time}`.localeCompare(`${b.appointment_date}${b.start_time}`))[0];
    return `<section class="bh-agenda-stats">
      <article><span>Hoy</span><strong>${today.length}</strong><small>Citas programadas</small></article>
      <article><span>${mode==='admin'?'Este mes':'Pendientes'}</span><strong>${mode==='admin'?all.length:scheduled}</strong><small>${mode==='admin'?'Total de citas':'Por atender'}</small></article>
      <article><span>Atendidas</span><strong>${done}</strong><small>En el mes</small></article>
      <article class="next"><span>Próxima cita</span><strong>${next?`${next.appointment_date.split('-').reverse().slice(0,2).join('/')} · ${timeLabel(next.start_time)}`:'Sin pendientes'}</strong><small>${next?esc(residentName(next.resident_key,next.resident_name)):'Agenda disponible'}</small></article>
    </section>`;
  }
  function filtersHtml(){
    return `<section class="bh-agenda-filters">
      <label>Médico<select data-agenda-filter="doctor"><option value="all">Todos los médicos</option>${state.doctors.map(d=>`<option value="${attr(d.id)}" ${state.filters.doctor===String(d.id)?'selected':''}>${esc(d.name)}</option>`).join('')}</select></label>
      <label>Estado<select data-agenda-filter="status"><option value="all">Todos los estados</option>${['Programada','Confirmada','Atendida','No se presentó','Cancelada'].map(s=>`<option ${state.filters.status===s?'selected':''}>${s}</option>`).join('')}</select></label>
      <button type="button" class="bh-agenda-today" data-agenda-today>Ir a hoy</button>
    </section>`;
  }
  function hero(mode){
    const admin=mode==='admin';
    if(admin){
      return `<section class="bh-agenda-hero admin">
        <div class="bh-agenda-hero-copy"><span>GESTIÓN DE CITAS MÉDICAS</span><h2>Agenda médica</h2><p>Asigne pacientes a cada médico por fecha y hora, con una vista clara y profesional.</p></div>
        <div class="bh-agenda-hero-icon">${svg.calendar}</div>
        <button type="button" class="bh-agenda-primary" data-agenda-new>${svg.plus}<span>Nueva cita</span></button>
      </section>`;
    }
    return `<section class="bh-agenda-hero doctor bh-agenda-doctor-hero">
      <div class="bh-agenda-doctor-top">
        <button type="button" class="bh-agenda-back" data-agenda-back aria-label="Volver al panel médico">${svg.back}<span>Volver</span></button>
        <span class="bh-agenda-doctor-badge">AGENDA MÉDICA</span>
      </div>
      <div class="bh-agenda-hero-copy"><span>MI AGENDA CLÍNICA</span><h2>Citas y pacientes asignados</h2><p>Consulte sus citas por fecha y mantenga actualizado el estado de cada atención.</p></div>
      <div class="bh-agenda-hero-icon">${svg.calendar}</div>
    </section>`;
  }
  function loadingView(mode){
    const m=main();if(!m)return;
    m.innerHTML=`${hero(mode)}<section class="bh-agenda-loading"><span></span><strong>Cargando agenda médica…</strong></section>`;
  }
  function errorView(mode,error){
    const m=main();if(!m)return;
    m.innerHTML=`${hero(mode)}<section class="bh-agenda-error"><strong>No se pudo abrir la agenda médica</strong><p>${esc(friendly(error))}</p><button type="button" data-agenda-retry>Reintentar</button></section>`;
    m.querySelector('[data-agenda-retry]')?.addEventListener('click',()=>open(mode));
  }
  function render(mode){
    const m=main();if(!m)return;
    m.innerHTML=`${hero(mode)}${statsHtml(mode)}${mode==='admin'?filtersHtml():`<section class="bh-agenda-doctor-tools"><button type="button" class="bh-agenda-today" data-agenda-today>Ir a hoy</button><span>${esc(user().name||user().email||'Médico')}</span></section>`}<section class="bh-agenda-layout">${calendarHtml()}${dayPanel(mode)}</section>`;
    bind(mode);
  }
  function renderCurrent(){render(isDoctor()?'doctor':'admin');}

  async function open(mode){
    if((mode==='admin'&&!isAdmin())||(mode==='doctor'&&!isDoctor())){
      window.go?.(isDoctor()?'medicalDashboard':'home',{scope:'global'},{replace:true});
      return;
    }
    loadingView(mode);
    try{
      await loadAll();
      subscribe();
      render(mode);
    }catch(error){console.error('[BHSC Agenda]',error);errorView(mode,error);}
  }

  function modalHtml(current){
    const editing=Boolean(current);
    const selectedDoctor=current?.doctor_id||state.doctors[0]?.id||'';
    const selectedResident=current?.resident_key||state.residents[0]?.key||'';
    return `<div class="bh-agenda-modal" role="dialog" aria-modal="true" aria-labelledby="bhAgendaFormTitle">
      <div class="bh-agenda-modal-card">
        <div class="bh-agenda-modal-head"><div><span>AGENDA MÉDICA</span><h3 id="bhAgendaFormTitle">${editing?'Editar cita':'Nueva cita'}</h3></div><button type="button" data-agenda-close aria-label="Cerrar">×</button></div>
        <form id="bhAgendaForm">
          <input type="hidden" name="id" value="${attr(current?.id||'')}">
          <div class="bh-agenda-form-grid">
            <label>Paciente<select name="resident_key" required>${state.residents.map(r=>`<option value="${attr(r.key)}" ${String(r.key)===String(selectedResident)?'selected':''}>${esc(r.name)}${r.room?` · ${esc(r.room)}`:''}</option>`).join('')}</select></label>
            <label>Médico<select name="doctor_id" required>${state.doctors.map(d=>`<option value="${attr(d.id)}" ${String(d.id)===String(selectedDoctor)?'selected':''}>${esc(d.name)}</option>`).join('')}</select></label>
            <label>Fecha<input type="date" name="appointment_date" required value="${attr(current?.appointment_date||state.selectedDate)}"></label>
            <label>Hora<input type="time" name="start_time" required value="${attr(timeLabel(current?.start_time||'08:00'))}"></label>
            <label>Duración<select name="duration_minutes">${[15,30,45,60,90].map(n=>`<option value="${n}" ${Number(current?.duration_minutes||30)===n?'selected':''}>${n} minutos</option>`).join('')}</select></label>
            <label>Tipo de cita<select name="appointment_type">${['Consulta médica','Control','Valoración inicial','Seguimiento','Revisión de resultados','Procedimiento','Teleconsulta'].map(x=>`<option ${current?.appointment_type===x?'selected':''}>${x}</option>`).join('')}</select></label>
            <label class="wide">Motivo de la cita<input name="reason" required maxlength="180" value="${attr(current?.reason||'')}" placeholder="Ej. Control de presión arterial y revisión de tratamiento"></label>
            <label>Ubicación<select name="location">${['Consultorio','Habitación del residente','Sala de procedimientos','Videollamada','Otra'].map(x=>`<option ${current?.location===x?'selected':''}>${x}</option>`).join('')}</select></label>
            <label>Estado<select name="status">${['Programada','Confirmada','Atendida','No se presentó','Cancelada'].map(x=>`<option ${current?.status===x?'selected':''}>${x}</option>`).join('')}</select></label>
            <label class="wide">Observaciones<textarea name="notes" rows="3" maxlength="1000" placeholder="Preparación, indicaciones o información relevante">${esc(current?.notes||'')}</textarea></label>
          </div>
          <div class="bh-agenda-form-actions"><button type="button" class="secondary" data-agenda-close>Cancelar</button><button type="submit" class="primary">${editing?'Guardar cambios':'Asignar cita'}</button></div>
        </form>
      </div>
    </div>`;
  }
  function openForm(id){
    if(!isAdmin())return;
    if(!state.doctors.length){toast('Primero debe existir una cuenta activa con rol Médico.');return;}
    if(!state.residents.length){toast('No hay residentes activos disponibles.');return;}
    const current=id?state.appointments.find(a=>String(a.id)===String(id)):null;
    state.formOpen=true;state.editingId=current?.id||null;
    const host=main();
    if(!host)return;
    host.insertAdjacentHTML('beforeend',modalHtml(current));
    const modal=host.querySelector('.bh-agenda-modal');
    modal?.querySelector('[name="resident_key"]')?.focus();
    modal?.querySelectorAll('[data-agenda-close]').forEach(b=>b.addEventListener('click',closeForm));
    modal?.addEventListener('click',e=>{if(e.target===modal)closeForm();});
    modal?.querySelector('#bhAgendaForm')?.addEventListener('submit',saveForm);
  }
  function closeForm(){
    main()?.querySelector('.bh-agenda-modal')?.remove();
    state.formOpen=false;state.editingId=null;
    if(state.pendingRefresh){state.pendingRefresh=false;renderCurrent();}
  }
  async function saveForm(event){
    event.preventDefault();
    const form=event.currentTarget,submit=form.querySelector('[type="submit"]');
    const fd=new FormData(form);
    const doctor=state.doctors.find(d=>String(d.id)===String(fd.get('doctor_id')));
    const resident=state.residents.find(r=>String(r.key)===String(fd.get('resident_key')));
    if(!doctor||!resident){toast('Seleccione un médico y un paciente válidos.');return;}
    const payload={
      organization_id:org(),
      resident_key:String(resident.key),
      resident_name:resident.name,
      doctor_id:String(doctor.id),
      doctor_name:doctor.name,
      appointment_date:String(fd.get('appointment_date')),
      start_time:String(fd.get('start_time')),
      duration_minutes:Number(fd.get('duration_minutes'))||30,
      appointment_type:String(fd.get('appointment_type')||'Consulta médica'),
      reason:String(fd.get('reason')||'').trim(),
      location:String(fd.get('location')||'Consultorio'),
      notes:String(fd.get('notes')||'').trim(),
      status:String(fd.get('status')||'Programada'),
      active:true,
      updated_at:new Date().toISOString()
    };
    if(!payload.reason){toast('Escriba el motivo de la cita.');return;}
    submit.disabled=true;submit.textContent='Guardando…';
    try{
      const id=String(fd.get('id')||'');
      let result;
      if(id){
        result=await db().from(TABLE).update(payload).eq('id',id).eq('organization_id',org());
      }else{
        payload.created_by=user().id||null;
        payload.created_by_name=user().name||user().email||'Administración';
        result=await db().from(TABLE).insert(payload);
      }
      if(result.error)throw result.error;
      state.selectedDate=payload.appointment_date;
      state.month=firstOfMonth(parseDate(payload.appointment_date));
      await loadAppointments();
      closeForm();
      render('admin');
      toast(id?'Cita actualizada correctamente.':'Cita asignada correctamente.');
    }catch(error){console.error('[BHSC Agenda] Guardado',error);toast(friendly(error));submit.disabled=false;submit.textContent=state.editingId?'Guardar cambios':'Asignar cita';}
  }
  async function deleteAppointment(id){
    const current=state.appointments.find(a=>String(a.id)===String(id));
    if(!current||!confirm(`¿Eliminar la cita de ${residentName(current.resident_key,current.resident_name)}?`))return;
    try{
      const result=await db().from(TABLE).update({active:false,updated_at:new Date().toISOString()}).eq('id',id).eq('organization_id',org());
      if(result.error)throw result.error;
      await loadAppointments();render('admin');toast('Cita eliminada.');
    }catch(error){toast(friendly(error));}
  }
  async function setDoctorStatus(id,status){
    try{
      const result=await db().from(TABLE).update({status,updated_at:new Date().toISOString()}).eq('id',id).eq('doctor_id',user().id).eq('organization_id',org());
      if(result.error)throw result.error;
      await loadAppointments();render('doctor');toast(`Cita marcada como ${status.toLowerCase()}.`);
    }catch(error){toast(friendly(error));}
  }
  function moveMonth(delta){
    state.month=new Date(state.month.getFullYear(),state.month.getMonth()+delta,1,12);
    state.selectedDate=isoDate(new Date(state.month.getFullYear(),state.month.getMonth(),1,12));
    loadingView(isDoctor()?'doctor':'admin');
    loadAppointments().then(renderCurrent).catch(error=>errorView(isDoctor()?'doctor':'admin',error));
  }
  function bind(mode){
    const m=main();if(!m)return;
    m.querySelector('[data-agenda-back]')?.addEventListener('click',()=>{
      if(typeof window.go==='function')window.go('medicalDashboard',{scope:'global'});
      else if(typeof window.goBack==='function')window.goBack();
      else history.back();
    });
    m.querySelector('[data-agenda-new]')?.addEventListener('click',()=>openForm());
    m.querySelectorAll('[data-agenda-month]').forEach(b=>b.addEventListener('click',()=>moveMonth(b.dataset.agendaMonth==='next'?1:-1)));
    m.querySelectorAll('[data-agenda-date]').forEach(b=>b.addEventListener('click',()=>{state.selectedDate=b.dataset.agendaDate;const d=parseDate(state.selectedDate);if(d.getMonth()!==state.month.getMonth()){state.month=firstOfMonth(d);loadAppointments().then(renderCurrent).catch(error=>errorView(mode,error));}else render(mode);}));
    m.querySelectorAll('[data-agenda-edit]').forEach(b=>b.addEventListener('click',()=>openForm(b.dataset.agendaEdit)));
    m.querySelectorAll('[data-agenda-delete]').forEach(b=>b.addEventListener('click',()=>deleteAppointment(b.dataset.agendaDelete)));
    m.querySelectorAll('[data-agenda-status]').forEach(b=>b.addEventListener('click',()=>setDoctorStatus(b.dataset.agendaId,b.dataset.agendaStatus)));
    m.querySelectorAll('[data-agenda-filter]').forEach(el=>el.addEventListener('change',()=>{state.filters[el.dataset.agendaFilter]=el.value;render(mode);}));
    m.querySelector('[data-agenda-today]')?.addEventListener('click',()=>{state.selectedDate=localDate();state.month=firstOfMonth(parseDate(state.selectedDate));loadingView(mode);loadAppointments().then(()=>render(mode)).catch(error=>errorView(mode,error));});
  }

  window.renderMedicalAppointmentsAdmin=()=>open('admin');
  window.renderMedicalAppointmentsDoctor=()=>open('doctor');
  window.BHSC_MEDICAL_APPOINTMENTS={reload:async()=>{await loadAll();if(screenIsAgenda())renderCurrent();},state};

  addEventListener('seniorcare:user-ready',()=>{if(['admin','administrator','supervisor','doctor'].includes(role()))subscribe();});
})();
