(()=>{
  'use strict';
  if(window.__staffGlobalV371) return;
  window.__staffGlobalV371=true;
  const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
  const roleCode={
    'Enfermería':'nurse','Enfermera':'nurse','Asistente':'assistant','Cuidador':'assistant',
    'Cocina':'cook','Guarda de seguridad':'security','Seguridad':'security',
    'Miscelánea':'cleaning','Limpieza':'cleaning','Mantenimiento':'maintenance','Médico':'doctor','Administración':'administrator'
  };
  const days=['Lun','Mar','Mié','Jue','Vie','Sáb','Dom'];
  const list=()=>Array.isArray(window.staffMembers)?window.staffMembers:(typeof staffMembers!=='undefined'&&Array.isArray(staffMembers)?staffMembers:[]);
  const save=()=>{ try{window.saveStaff?.();}catch(e){console.error(e);} };
  const toast=m=>window.showToast?.(m);
  const att=m=>{
    try{
      const logs=Array.isArray(window.attendanceLog)?window.attendanceLog:[];
      const linked=String(m?.linkedUserId||m?.linked_user_id||'');
      const name=String(m?.name||'').trim().toLowerCase();
      const rows=logs.filter(x=>
        (linked&&(String(x.userId||'')===linked||String(x.staffId||'')===`user:${linked}`))||
        String(x.staffId||'')===String(m?.id||'')||
        (name&&String(x.name||'').trim().toLowerCase()===name)
      ).sort((a,b)=>String(b.date||b.clockIn||'').localeCompare(String(a.date||a.clockIn||'')));
      const latest=rows[0]||null;
      if(latest)return {present:Boolean(latest.clockIn&&!latest.clockOut),lastEntry:latest.clockIn||null,lastExit:latest.clockOut||null};
      return typeof getAttendanceState==='function'?getAttendanceState(m.id):{present:false,lastEntry:null,lastExit:null};
    }catch(_){return {present:false,lastEntry:null,lastExit:null};}
  };
  const attLabel=v=>{try{return typeof attendanceLabel==='function'?attendanceLabel(v):(v?new Date(v).toLocaleString('es-CR'):'No registrada');}catch(_){return 'No registrada';}};
  const pill=v=>{try{return typeof statusPill==='function'?statusPill(v):`<span class="status">${esc(v)}</span>`;}catch(_){return `<span class="status">${esc(v)}</span>`;}};
  const links=()=>{try{return JSON.parse(localStorage.getItem('seniorcare-staff-code-links')||'{}')||{};}catch(_){return {};}};
  const codeLabel=m=>{const l=links()[String(m.id)];if(m.linkedUserId)return '<span class="status ok">Cuenta vinculada</span>';if(l?.code)return '<span class="status warn">Código vigente</span>';return '<span class="status">Sin vincular</span>';};
  const fmtShift=m=>m.shiftName?`${m.shiftName} · ${m.startTime||'--:--'}–${m.endTime||'--:--'}`:(m.shift||'Sin turno');
  const fmtDays=m=>Array.isArray(m.workDays)&&m.workDays.length?m.workDays.join(', '):'Sin días definidos';
  const stableResidentKey=r=>String(window.residentKey?.(r)||r?.resident_key||r?.id||'').trim();
  const isAssistantMember=m=>['asistente','cuidador','assistant'].includes(String(m?.role||'').normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase());
  const assignmentKeys=m=>{
    const map=window.residentAssignments||{};
    const aliases=[String(m?.id||''),String(m?.linkedUserId||m?.linked_user_id||'')].filter(Boolean);
    if(m?.linkedUserId||m?.linked_user_id)aliases.push(`user:${m.linkedUserId||m.linked_user_id}`);
    return new Set(aliases.flatMap(k=>Array.isArray(map[k])?map[k]:[]).map(String));
  };
  const assignmentPanel=m=>{
    if(!isAssistantMember(m))return '';
    const selected=assignmentKeys(m),residents=Array.isArray(window.residents)?window.residents:[];
    const names=residents.filter(r=>selected.has(String(r.id))||selected.has(stableResidentKey(r))).map(r=>r.name);
    return `<details class="assistant-assignment-box global-assignment-box" data-assignment-box="${esc(m.id)}"><summary><span>RESIDENTES ASIGNADOS</span><strong>${names.length?esc(names.join(', ')):'Sin residentes asignados'}</strong></summary><div class="assistant-assignment-list">${residents.length?residents.map(r=>{const key=stableResidentKey(r);const checked=selected.has(String(r.id))||selected.has(key);return `<label><input type="checkbox" value="${esc(key)}" ${checked?'checked':''}><span><strong>${esc(r.name||'Residente')}</strong><small>${esc(r.room||'Sin habitación')}</small></span></label>`}).join(''):'<p>No hay residentes activos disponibles.</p>'}</div><div class="form-actions"><button type="button" class="primary-btn" data-save-resident-assignment="${esc(m.id)}" ${m.linkedUserId||m.linked_user_id?'':'disabled'}>${m.linkedUserId||m.linked_user_id?'Guardar asignación':'Vincule primero la cuenta'}</button></div></details>`;
  };
  function render(){
    const members=list();
    const present=members.filter(m=>att(m).present).length;
    const active=members.filter(m=>(m.employmentStatus||m.status||'Activo')!=='Inactivo').length;
    const linked=members.filter(m=>m.linkedUserId).length;
    window.main.innerHTML=window.pageHeader('GESTIÓN DE PERSONAL','Personal y turnos','Colaboradores, horarios estructurados, asignaciones, accesos y asistencia')+`
      <section class="staff-dashboard-pro global-staff-dashboard">
        <article><span>Colaboradores</span><strong>${members.length}</strong><small>Registrados</small></article>
        <article><span>Activos</span><strong>${active}</strong><small>Disponibles para operar</small></article>
        <article><span>Presentes</span><strong>${present}</strong><small>Con entrada marcada</small></article>
        <article><span>Cuentas vinculadas</span><strong>${linked}</strong><small>Acceso individual activo</small></article>
        <button class="primary-btn staff-add-pro" id="addStaffGlobal">${window.svg.plus} Añadir personal</button>
      </section>
      <section class="staff-attendance-banner"><div><strong>Turnos, accesos y asistencia integrados</strong><span>El horario programado es independiente de la entrada y salida real. Las marcas y cambios se sincronizan entre dispositivos.</span></div><small>Supabase · Realtime</small></section>
      <form class="form-card staff-form hidden" id="staffFormGlobal"><input type="hidden" name="staffId"><div class="form-grid">
        <label>Nombre completo<input name="name" required></label>
        <label>Puesto o función<select name="role"><option>Enfermería</option><option>Asistente</option><option>Cuidador</option><option>Cocina</option><option>Guarda de seguridad</option><option>Miscelánea</option><option>Mantenimiento</option><option>Médico</option><option>Administración</option></select></label>
        <label>Turno<select name="shiftName"><option>Matutino</option><option>Vespertino</option><option>Nocturno</option><option>Rotativo</option><option>Administrativo</option></select></label>
        <label>Estado laboral<select name="employmentStatus"><option>Activo</option><option>Libre</option><option>Vacaciones</option><option>Permiso</option><option>Inactivo</option></select></label>
        <label>Hora de entrada<input name="startTime" type="time" required></label>
        <label>Hora de salida<input name="endTime" type="time" required></label>
        <fieldset class="wide staff-days-field"><legend>Días programados</legend><div class="staff-days-grid">${days.map(d=>`<label><input type="checkbox" name="workDays" value="${d}"><span>${d}</span></label>`).join('')}</div></fieldset>
        <label class="wide">Asignación principal<input name="assignment" placeholder="Residentes, habitaciones, cocina, vigilancia o responsabilidades"></label>
      </div><div class="form-actions"><button type="button" class="secondary-btn" id="cancelStaffGlobal">Cancelar</button><button class="primary-btn" type="submit">Guardar colaborador y turno</button></div></form>
      <div class="staff-grid-pro global-staff-grid">${members.map(m=>{const a=att(m);const role=roleCode[m.role]||'';const codeBtn=role?`<button class="secondary-btn staff-code-btn" data-create-staff-code="${esc(m.id)}" data-role="${role}">${m.linkedUserId?'Acceso vinculado':(links()[String(m.id)]?.code?'Reenviar código':'Crear código')}</button>`:'';return `<article class="staff-card-pro global-staff-card" data-staff-id="${esc(m.id)}">
        <div class="staff-card-pro-head"><div class="avatar staff-avatar">${esc(m.name).split(' ').map(x=>x[0]).slice(0,2).join('')}</div><div class="staff-name"><strong>${esc(m.name)}</strong><span>${esc(m.role||'Sin puesto')}</span></div>${pill(a.present?'Presente':(m.employmentStatus||m.status||'Activo'))}</div>
        <div class="staff-card-pro-body"><div><span>Turno programado</span><strong>${esc(fmtShift(m))}</strong></div><div><span>Días</span><strong>${esc(fmtDays(m))}</strong></div><div><span>Asignación</span><strong>${esc(m.assignment||'Sin asignación')}</strong></div></div>
        <div class="attendance-log"><div><span>Última entrada</span><strong>${esc(attLabel(a.lastEntry))}</strong></div><div><span>Última salida</span><strong>${esc(attLabel(a.lastExit))}</strong></div><div><span>Acceso</span>${codeLabel(m)}</div></div>
        ${assignmentPanel(m)}
        <div class="staff-card-pro-actions">${codeBtn}<button class="secondary-btn" data-view-staff-attendance="${esc(m.id)}">Ver asistencia</button><button class="mini-btn" data-staff-global-edit="${esc(m.id)}">Editar ficha</button><button class="danger-outline-btn entity-delete-btn-v4368" data-staff-delete-v4368="${esc(m.id)}" aria-label="Eliminar trabajador">Eliminar</button></div>
      </article>`}).join('')}</div>`;
  }

  function showAttendance(member){
    const state=att(member);
    const history=(Array.isArray(window.attendanceLog)?window.attendanceLog:[])
      .filter(x=>String(x.staffId||'')===String(member.id)||String(x.userId||'')===String(member.linkedUserId||'')||String(x.name||'').trim().toLowerCase()===String(member.name||'').trim().toLowerCase())
      .sort((a,b)=>String(b.date||b.clockIn||'').localeCompare(String(a.date||a.clockIn||'')))
      .slice(0,20);
    document.getElementById('staffAttendanceModal')?.remove();
    const modal=document.createElement('section');
    modal.id='staffAttendanceModal';
    modal.className='record-modal';
    modal.innerHTML=`<div class="record-modal-backdrop" data-close-staff-attendance></div><article class="record-modal-card"><header class="record-modal-head"><div><span>CONTROL DE ASISTENCIA</span><h3>${esc(member.name)}</h3></div><button class="modal-close" data-close-staff-attendance aria-label="Cerrar">×</button></header><div class="record-modal-body"><div class="attendance-log staff-attendance-summary"><div><span>Estado actual</span><strong>${state.present?'Presente':'Fuera de turno'}</strong></div><div><span>Última entrada</span><strong>${esc(attLabel(state.lastEntry))}</strong></div><div><span>Última salida</span><strong>${esc(attLabel(state.lastExit))}</strong></div></div><div class="staff-attendance-history">${history.length?history.map(x=>`<article><div><strong>${esc(x.date||'Sin fecha')}</strong><span>${esc(x.role||member.role||'Personal')}</span></div><div><span>Entrada</span><strong>${esc(attLabel(x.clockIn))}</strong></div><div><span>Salida</span><strong>${esc(attLabel(x.clockOut))}</strong></div></article>`).join(''):'<div class="empty-state"><strong>Sin historial disponible</strong><span>Las marcas aparecerán aquí cuando el colaborador registre su entrada o salida.</span></div>'}</div></div><footer class="record-modal-actions"><button class="danger-outline-btn" data-reset-staff-attendance="${esc(member.id)}">Reiniciar marca de hoy</button><button class="secondary-btn" data-close-staff-attendance>Cerrar</button></footer></article>`;
    document.body.appendChild(modal);
  }


  async function resetTodayAttendance(member){
    if(!member||!window.seniorcareSupabase||!window.currentUser)return;
    const orgId=window.currentUser.organizationId||window.currentUser.organization_id;
    const day=new Date().toLocaleDateString('en-CA',{timeZone:'America/Costa_Rica'});
    if(!orgId)throw new Error('No se identificó la organización.');
    const db=window.seniorcareSupabase;
    const ids=[String(member.id||''),String(member.staff_key||'')].filter(Boolean);
    for(const key of [...new Set(ids)]){
      const q=await db.from('attendance_records').delete().eq('organization_id',orgId).eq('work_date',day).eq('staff_key',key);
      if(q.error)throw q.error;
    }
    const uid=String(member.linkedUserId||member.linked_user_id||'');
    if(uid){const q=await db.from('attendance_records').delete().eq('organization_id',orgId).eq('work_date',day).eq('user_id',uid);if(q.error)throw q.error;}
    const log=Array.isArray(window.attendanceLog)?window.attendanceLog:[];
    window.attendanceLog=log.filter(x=>!(String(x.date)===day&&(ids.includes(String(x.staffId||''))||(uid&&String(x.userId||'')===uid))));
    try{localStorage.setItem('seniorcare-attendance-log',JSON.stringify(window.attendanceLog));}catch(_){ }
    await window.syncSeniorCareAttendanceGlobal?.();
  }

  function openForm(member){
    const f=document.getElementById('staffFormGlobal'); if(!f)return;
    f.reset(); f.classList.remove('hidden');
    f.elements.staffId.value=member?.id??'';
    f.elements.name.value=member?.name??'';
    f.elements.role.value=member?.role||'Enfermería';
    f.elements.shiftName.value=member?.shiftName||'Matutino';
    f.elements.employmentStatus.value=member?.employmentStatus||member?.status||'Activo';
    f.elements.startTime.value=member?.startTime||String(member?.shift||'').split('–')[0]||'06:00';
    f.elements.endTime.value=member?.endTime||String(member?.shift||'').split('–')[1]||'14:00';
    f.elements.assignment.value=member?.assignment||'';
    const selected=new Set(Array.isArray(member?.workDays)?member.workDays:[]);
    f.querySelectorAll('input[name="workDays"]').forEach(x=>x.checked=selected.has(x.value));
    f.scrollIntoView({behavior:'smooth',block:'start'});
  }
  document.addEventListener('click',async e=>{
    const add=e.target.closest?.('#addStaffGlobal'); if(add){e.preventDefault();e.stopImmediatePropagation();openForm(null);return;}
    const cancel=e.target.closest?.('#cancelStaffGlobal'); if(cancel){e.preventDefault();e.stopImmediatePropagation();document.getElementById('staffFormGlobal')?.classList.add('hidden');return;}
    const view=e.target.closest?.('[data-view-staff-attendance]'); if(view){e.preventDefault();e.stopImmediatePropagation();const m=list().find(x=>String(x.id)===String(view.dataset.viewStaffAttendance));if(m)showAttendance(m);return;}
    const reset=e.target.closest?.('[data-reset-staff-attendance]'); if(reset){e.preventDefault();e.stopImmediatePropagation();const m=list().find(x=>String(x.id)===String(reset.dataset.resetStaffAttendance));if(!m||!confirm(`¿Reiniciar la marca de entrada y salida de hoy para ${m.name}?`))return;reset.disabled=true;resetTodayAttendance(m).then(()=>{document.getElementById('staffAttendanceModal')?.remove();render();toast('Marca de hoy reiniciada. El colaborador puede volver a marcar entrada.');}).catch(err=>{toast(`No se pudo reiniciar: ${err.message||err}`);reset.disabled=false;});return;}
    const close=e.target.closest?.('[data-close-staff-attendance]'); if(close){e.preventDefault();e.stopImmediatePropagation();document.getElementById('staffAttendanceModal')?.remove();return;}
    const edit=e.target.closest?.('[data-staff-global-edit]'); if(edit){e.preventDefault();e.stopImmediatePropagation();const m=list().find(x=>String(x.id)===String(edit.dataset.staffGlobalEdit));openForm(m);return;}
    const del=e.target.closest?.('[data-staff-delete-v4368]'); if(del){
      e.preventDefault();e.stopImmediatePropagation();
      const id=String(del.dataset.staffDeleteV4368);const m=list().find(x=>String(x.id)===id);
      if(!m||!confirm(`¿Eliminar a ${m.name}? Su ficha dejará de aparecer y, si tiene cuenta vinculada, su acceso será desactivado. El historial de asistencia se conservará.`))return;
      del.disabled=true;
      try{
        if(typeof window.deleteStaffMemberFromCloud!=='function')throw new Error('La función de eliminación no está disponible.');
        await window.deleteStaffMemberFromCloud(m);
        render();toast('Trabajador eliminado correctamente.');
      }catch(error){toast(`No se pudo eliminar: ${error?.message||error}`);del.disabled=false;}
      return;
    }
  },true);
  document.addEventListener('submit',e=>{
    const f=e.target;if(!(f instanceof HTMLFormElement)||f.id!=='staffFormGlobal')return;
    e.preventDefault();e.stopImmediatePropagation();
    const fd=new FormData(f),raw=String(fd.get('staffId')||''),id=raw||((crypto.randomUUID&&crypto.randomUUID())||String(Date.now()));
    const start=String(fd.get('startTime')||'06:00'),end=String(fd.get('endTime')||'14:00');
    const data={id,name:String(fd.get('name')||'').trim(),role:String(fd.get('role')||''),shiftName:String(fd.get('shiftName')||'Matutino'),employmentStatus:String(fd.get('employmentStatus')||'Activo'),status:String(fd.get('employmentStatus')||'Activo'),startTime:start,endTime:end,shift:`${start}–${end}`,workDays:fd.getAll('workDays').map(String),assignment:String(fd.get('assignment')||'').trim()};
    const arr=list(),idx=arr.findIndex(x=>String(x.id)===String(id));if(idx>=0)arr[idx]={...arr[idx],...data};else arr.push(data);
    if(typeof staffMembers!=='undefined')staffMembers=arr;window.staffMembers=arr;save();render();toast('Personal y turno actualizados.');
  },true);
  window.renderStaffGlobal=render;
  window.renderStaff=render;
  window.SENIORCARE_STAFF_GLOBAL_VERSION='4.3.68';
})();
