/* Bernard Health SeniorCare Enterprise V3.6.4
   Notas de enfermería + cierres/entregas de turno globales.
   Administrador: solo consulta y archiva notas para el expediente.
   Enfermería/Asistentes: registran entregas ligadas a organización y usuario. */
(()=>{
  'use strict';
  const VERSION='3.6.4';
  const NOTES='seniorcare_nursing_notes';
  const HANDOFFS='seniorcare_handoff_records';
  let notesChannel=null,handoffChannel=null,notesBusy=false,handoffBusy=false;
  const db=()=>window.seniorcareSupabase||null;
  const me=()=>window.currentUser||null;
  const org=()=>me()?.organizationId||me()?.organization_id||null;
  const role=()=>String(me()?.role||'').toLowerCase();
  const isAdmin=()=>['admin','administrator'].includes(role());
  const isNurse=()=>role()==='nurse';
  const isAssistant=()=>role()==='assistant';
  const canSubmitHandoff=()=>isNurse()||isAssistant();
  const esc=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
  const uuid=()=>crypto.randomUUID?.()||`${Date.now()}-${Math.random().toString(16).slice(2)}`;
  const localDate=v=>{if(!v)return 'Sin fecha';const d=new Date(v);return Number.isNaN(d.getTime())?String(v):d.toLocaleString('es-CR');};
  const residentStable=r=>String(window.residentKey?.(r)||r?.resident_key||r?.id||'').trim();
  const residentByKey=k=>(window.residents||[]).find(r=>residentStable(r)===String(k)||String(r.id)===String(k));
  const mainEl=()=>document.getElementById('mainContent');
  const toast=m=>window.showToast?.(m)||console.info(m);
  const refreshBind=()=>window.bindActions?.();
  const safeRender=fn=>{const y=window.scrollY||0;requestAnimationFrame(()=>{try{fn();refreshBind();}catch(e){console.error(e)}requestAnimationFrame(()=>window.scrollTo(0,y));});};

  function setLocalNotes(rows){
    const map={};
    for(const row of rows||[]){
      const r=residentByKey(row.resident_key);const key=r?.id??row.resident_key;
      const item={...(row.data||{}),id:row.note_key,date:row.recorded_at,shift:row.shift_name||'',status:row.clinical_status||'',author:row.author_name||'',note:row.note_text||''};
      (map[key]??=[]).push(item);
    }
    window.nursingNotes=map;
    try{nursingNotes=map}catch(_){ }
    localStorage.setItem('seniorcare-nursing-notes',JSON.stringify(map));
  }

  async function pullNotes(render=true){
    if(notesBusy||!db()||!org())return;notesBusy=true;
    try{
      const {data,error}=await db().from(NOTES).select('*').eq('organization_id',org()).eq('active',true).order('recorded_at',{ascending:false});
      if(error)throw error;setLocalNotes(data||[]);
      if(render&&window.activeScreen==='nursing')safeRender(renderNursing362);
      if(render&&window.activeScreen==='home'&&isAdmin())safeRender(window.renderHome);
    }finally{notesBusy=false;}
  }

  function currentResident(){return window.selectedResident||(window.residents||[])[0]||null;}
  function currentNotes(){const r=currentResident();if(!r)return[];return (window.nursingNotes?.[r.id]||window.nursingNotes?.[residentStable(r)]||[]);}

  function noteCard(n,adminView=false){
    const archived=!!(n.archivedAt||n.archived_at);
    return `<article class="note-card nursing-note-v362 ${archived?'is-archived':''}"><div><b>${esc(localDate(n.date))} · ${esc(n.shift||'Sin turno')}</b><span>${esc(n.author||'Sin autor')} · ${esc(n.status||'Sin estado')}</span><p>${esc(n.note||'')}</p>${archived?`<small class="note-archive-meta-v4319">Archivada ${esc(localDate(n.archivedAt||n.archived_at))}${n.archivedByName?` por ${esc(n.archivedByName)}`:''}</small>`:''}</div>${adminView&&!archived?`<button class="mini-btn note-archive-btn-v4319" data-note362-archive="${esc(n.id)}">Archivar</button>`:archived?'<span class="status ok note-archived-status-v4319">Archivada</span>':''}</article>`;
  }

  function renderNursing362(){
    const r=currentResident();const root=mainEl();if(!root)return;
    if(!r){root.innerHTML=window.empty?.('No hay residentes disponibles.')||'<p>No hay residentes disponibles.</p>';return;}
    const notes=currentNotes();
    const activeNotes=notes.filter(n=>!(n.archivedAt||n.archived_at));
    const archivedNotes=notes.filter(n=>!!(n.archivedAt||n.archived_at));
    const adminArchive=isAdmin()?`<section class="history-card nursing-history-v362 nursing-archive-v4319"><div class="section-title-row"><div><span>ARCHIVO DEL EXPEDIENTE</span><h3>Notas archivadas</h3></div><b>${archivedNotes.length}</b></div>${archivedNotes.length?archivedNotes.map(n=>noteCard(n,true)).join(''):window.empty('No hay notas archivadas para este residente.')}</section>`:'';
    root.innerHTML=window.pageHeader('EVOLUCIÓN CLÍNICA','Notas de enfermería',`Historial sincronizado de ${esc(r.name||'residente')}`)+`
      <div class="filter-row nursing-filter-v362"><select id="nursingResidentSelect362">${(window.residents||[]).map(x=>`<option value="${esc(residentStable(x))}" ${residentStable(x)===residentStable(r)?'selected':''}>${esc(x.name)}</option>`).join('')}</select></div>
      ${isNurse()?`<form class="form-card nursing-form-v362" id="nursingForm362"><div class="form-grid"><label>Residente<input value="${esc(r.name)}" disabled></label><label>Turno<select name="shift"><option>Matutino</option><option>Vespertino</option><option>Nocturno</option></select></label><label>Estado general<select name="status"><option>Estable</option><option>En observación</option><option>Requiere valoración</option></select></label><label class="wide">Nota de evolución<textarea name="note" rows="6" required></textarea></label></div><div class="form-actions"><button class="primary-btn">Guardar y sincronizar nota</button></div></form>`:''}
      <section class="history-card nursing-history-v362"><div class="section-title-row"><div><span>RESPALDO CLÍNICO</span><h3>${isAdmin()?'Notas pendientes de archivar':'Notas registradas'}</h3></div><b>${isAdmin()?activeNotes.length:notes.length}</b></div>${(isAdmin()?activeNotes:notes).length?(isAdmin()?activeNotes:notes).map(n=>noteCard(n,isAdmin())).join(''):window.empty(isAdmin()?'No hay notas pendientes de archivar para este residente.':'No hay notas registradas para este residente.')}</section>${adminArchive}`;
  }

  async function saveNote(fd){
    if(!isNurse())throw new Error('Solo Enfermería puede registrar notas clínicas.');
    const r=currentResident();if(!r)throw new Error('Seleccione un residente.');
    const note=String(fd.get('note')||'').trim();if(!note)throw new Error('Escriba la nota de enfermería.');
    const id=uuid(),now=new Date().toISOString();
    const payload={organization_id:org(),resident_key:residentStable(r),resident_name:r.name||'',note_key:id,shift_name:String(fd.get('shift')||''),clinical_status:String(fd.get('status')||''),note_text:note,recorded_at:now,author_name:me()?.name||me()?.full_name||'Enfermería',data:{id,date:now,shift:String(fd.get('shift')||''),status:String(fd.get('status')||''),author:me()?.name||me()?.full_name||'Enfermería',note},active:true,updated_at:now,updated_by:me()?.id||null};
    const {error}=await db().from(NOTES).upsert(payload,{onConflict:'organization_id,resident_key,note_key'});if(error)throw error;
    await pullNotes(false);
  }

  function handoffRoleLabel(v){const x=String(v||'').toLowerCase();return x==='nurse'?'Enfermería':x==='assistant'?'Asistentes':x==='admin'?'Administración':v||'Personal';}
  function handoffStatusLabel(v){return v==='archived'?'Archivado':v==='closed'?'Cerrado':'Entregado';}
  function normalizeHandoff(row){return {...(row.data||{}),id:row.handoff_key,date:row.recorded_at,area:row.area_name||'',shift:row.outgoing_shift||'',incomingShift:row.incoming_shift||'',author:row.author_name||'',receiver:row.receiver_name||'',authorRole:row.author_role||row.data?.authorRole||'',recordStatus:row.record_status||row.data?.recordStatus||'submitted',archivedAt:row.archived_at||null,archivedBy:row.archived_by||null};}
  function setLocalHandoffs(rows){const list=(rows||[]).map(normalizeHandoff);window.handoffRecords=list;try{handoffRecords=list}catch(_){ }localStorage.setItem('seniorcare-handoffs',JSON.stringify(list));}
  async function pullHandoffs(render=true){
    if(handoffBusy||!db()||!org())return;handoffBusy=true;
    try{const {data,error}=await db().from(HANDOFFS).select('*').eq('organization_id',org()).eq('active',true).order('recorded_at',{ascending:false});if(error)throw error;setLocalHandoffs(data||[]);if(render&&window.activeScreen==='handoff')safeRender(renderHandoff362);}finally{handoffBusy=false;}
  }
  function handoffRows(){return [...(window.handoffRecords||[])];}
  function handoffCard(r,admin=false){
    const archived=!!r.archivedAt||r.recordStatus==='archived';
    return `<article class="handoff-admin-card-v362 ${archived?'is-archived':''}"><div class="handoff-record-top"><span class="handoff-shift">${esc(r.shift||'Turno')}</span><span class="status ${archived?'warn':r.recordStatus==='closed'?'ok':'warn'}">${esc(handoffStatusLabel(archived?'archived':r.recordStatus))}</span></div><div class="handoff-card-main-v362"><div><strong>${esc(r.author||'Sin autor')} <span>→</span> ${esc(r.receiver||'Sin relevo')}</strong><small>${esc(handoffRoleLabel(r.authorRole))} · ${esc(localDate(r.date))}</small><p>${esc(String(r.news||'Sin novedades').slice(0,180))}</p></div></div><div class="handoff-card-actions-v362"><button class="mini-btn" data-handoff362-view="${esc(r.id)}">Ver ficha</button>${admin&&!archived&&r.recordStatus!=='closed'?`<button class="mini-btn" data-handoff362-close="${esc(r.id)}">Cerrar</button>`:''}${admin&&!archived?`<button class="mini-btn" data-handoff362-archive="${esc(r.id)}">Archivar</button>`:''}${admin?`<button class="icon-delete" data-handoff362-delete="${esc(r.id)}" title="Eliminar">×</button>`:''}</div></article>`;
  }
  function renderHandoff362(){
    const root=mainEl();if(!root)return;const all=handoffRows();
    if(isAdmin()){
      const active=all.filter(x=>!x.archivedAt&&x.recordStatus!=='archived'),archived=all.filter(x=>x.archivedAt||x.recordStatus==='archived');
      root.innerHTML=window.pageHeader('CONTINUIDAD OPERATIVA','Cierres y entregas de turno','Respaldo de Enfermería y Asistentes')+`<section class="handoff-admin-summary-v362"><article><span>Entregas activas</span><strong>${active.length}</strong></article><article><span>Enfermería</span><strong>${all.filter(x=>x.authorRole==='nurse').length}</strong></article><article><span>Asistentes</span><strong>${all.filter(x=>x.authorRole==='assistant').length}</strong></article><article><span>Archivadas</span><strong>${archived.length}</strong></article></section><section class="history-card"><div class="section-title-row"><div><span>ENTREGAS VIGENTES</span><h3>Pendientes de respaldo o cierre</h3></div></div><div class="handoff-admin-list-v362">${active.length?active.map(x=>handoffCard(x,true)).join(''):window.empty('No hay entregas activas.')}</div></section><section class="history-card"><div class="section-title-row"><div><span>ARCHIVO</span><h3>Entregas archivadas</h3></div></div><div class="handoff-admin-list-v362">${archived.length?archived.map(x=>handoffCard(x,true)).join(''):window.empty('No hay entregas archivadas.')}</div></section><section id="handoffDetail362" class="handoff-detail-v362 hidden"></section>`;
      return;
    }
    if(canSubmitHandoff()){
      const mine=all.filter(x=>!x.archivedAt&&(!x.authorRole||x.authorRole===role()));
      root.innerHTML=window.pageHeader('CONTINUIDAD DEL CUIDADO','Entrega de turno',`Registro de ${handoffRoleLabel(role())} sincronizado con Administración`)+`<form class="form-card handoff-form-pro" id="handoffForm362"><div class="handoff-form-title"><div><span>NUEVA ENTREGA</span><h3>Registrar cambio de turno</h3></div><span class="handoff-lock">Respaldo permanente</span></div><div class="form-grid"><label>Turno que entrega<select name="shift" required><option value="">Seleccione</option><option>Matutino</option><option>Vespertino</option><option>Nocturno</option></select></label><label>Turno que recibe<select name="incomingShift" required><option value="">Seleccione</option><option>Matutino</option><option>Vespertino</option><option>Nocturno</option><option>Sin relevo</option></select></label><label>Entrega el turno<input value="${esc(me()?.name||'')}" readonly></label><label>Recibe el turno<input name="receiver" placeholder="Nombre o Sin relevo" required></label><label class="wide">Novedades del turno<textarea name="news" rows="5" required></textarea></label><label class="wide">Pendientes<textarea name="pending" rows="4"></textarea></label><label class="wide">Indicaciones especiales<textarea name="instructions" rows="3"></textarea></label></div><div class="handoff-warning">Al entregar, el registro será visible para Administración y quedará disponible para cierre o archivo.</div><div class="form-actions"><button class="primary-btn">Entregar turno</button></div></form><section class="history-card"><div class="section-title-row"><div><span>HISTORIAL</span><h3>Mis entregas registradas</h3></div><b>${mine.length}</b></div><div class="handoff-admin-list-v362">${mine.length?mine.map(x=>handoffCard(x,false)).join(''):window.empty('No hay entregas registradas.')}</div></section><section id="handoffDetail362" class="handoff-detail-v362 hidden"></section>`;
      return;
    }
    root.innerHTML=window.pageHeader('CONTINUIDAD OPERATIVA','Entregas de turno','Consulta de registros')+(all.length?all.map(x=>handoffCard(x,false)).join(''):window.empty('No hay registros.'));
  }
  async function saveHandoff(fd){
    const id=uuid(),now=new Date().toISOString();
    const data={id,date:now,shift:String(fd.get('shift')||''),incomingShift:String(fd.get('incomingShift')||''),author:me()?.name||me()?.full_name||'',receiver:String(fd.get('receiver')||'').trim(),news:String(fd.get('news')||'').trim(),pending:String(fd.get('pending')||'').trim(),instructions:String(fd.get('instructions')||'').trim(),authorRole:role(),recordStatus:'submitted',locked:true};
    const row={organization_id:org(),handoff_key:id,area_name:handoffRoleLabel(role()),outgoing_shift:data.shift,incoming_shift:data.incomingShift,author_name:data.author,receiver_name:data.receiver,author_role:role(),record_status:'submitted',recorded_at:now,data,active:true,updated_at:now,updated_by:me()?.id||null};
    const {error}=await db().from(HANDOFFS).upsert(row,{onConflict:'organization_id,handoff_key'});if(error)throw error;await pullHandoffs(false);
  }
  async function updateHandoff(id,patch){const {error}=await db().from(HANDOFFS).update({...patch,updated_at:new Date().toISOString(),updated_by:me()?.id||null}).eq('organization_id',org()).eq('handoff_key',id);if(error)throw error;await pullHandoffs(false);renderHandoff362();refreshBind();}
  function showHandoff(id){const r=handoffRows().find(x=>String(x.id)===String(id));const box=document.getElementById('handoffDetail362');if(!r||!box)return;box.classList.remove('hidden');box.innerHTML=`<div class="handoff-detail-head-v362"><div><span>FICHA DE ENTREGA</span><h3>${esc(handoffRoleLabel(r.authorRole))} · ${esc(r.shift||'Turno')}</h3></div><button class="icon-delete" data-handoff362-hide>×</button></div><div class="handoff-detail-grid-v362"><article><span>Entrega</span><strong>${esc(r.author||'')}</strong></article><article><span>Recibe</span><strong>${esc(r.receiver||'')}</strong></article><article><span>Fecha</span><strong>${esc(localDate(r.date))}</strong></article><article><span>Estado</span><strong>${esc(handoffStatusLabel(r.archivedAt?'archived':r.recordStatus))}</strong></article></div><h4>Novedades</h4><p>${esc(r.news||'Sin novedades')}</p><h4>Pendientes</h4><p>${esc(r.pending||'Sin pendientes')}</p><h4>Indicaciones especiales</h4><p>${esc(r.instructions||'Sin indicaciones')}</p>`;box.scrollIntoView({behavior:'smooth',block:'start'});}

  async function startRealtime(){
    if(!db()||!org())return;
    await Promise.all([pullNotes(false).catch(console.warn),pullHandoffs(false).catch(console.warn)]);
    if(notesChannel)try{await db().removeChannel(notesChannel)}catch(_){ }
    if(handoffChannel)try{await db().removeChannel(handoffChannel)}catch(_){ }
    notesChannel=db().channel(`bhsc-notes-362-${org()}`).on('postgres_changes',{event:'*',schema:'public',table:NOTES,filter:`organization_id=eq.${org()}`},()=>pullNotes(true).catch(console.error)).subscribe();
    handoffChannel=db().channel(`bhsc-handoff-362-${org()}`).on('postgres_changes',{event:'*',schema:'public',table:HANDOFFS,filter:`organization_id=eq.${org()}`},()=>pullHandoffs(true).catch(console.error)).subscribe();
  }

  const oldNursing=window.renderNursing;
  const oldHandoff=window.renderHandoff;
  window.renderNursing=renderNursing362;
  window.renderHandoff=renderHandoff362;
  try{renderNursing=renderNursing362;renderHandoff=renderHandoff362}catch(_){ }

  document.addEventListener('change',e=>{if(e.target?.id==='nursingResidentSelect362'){e.preventDefault();e.stopImmediatePropagation();window.selectedResident=residentByKey(e.target.value)||window.selectedResident;renderNursing362();refreshBind();}},true);
  document.addEventListener('submit',async e=>{
    if(e.target?.id==='nursingForm362'){e.preventDefault();e.stopImmediatePropagation();const btn=e.target.querySelector('button[type="submit"],button:not([type])');if(btn)btn.disabled=true;try{await saveNote(new FormData(e.target));toast('Nota guardada y sincronizada.');e.target.reset();renderNursing362();refreshBind();}catch(err){toast(err.message||String(err));}finally{if(btn)btn.disabled=false;}return;}
    if(e.target?.id==='handoffForm362'){e.preventDefault();e.stopImmediatePropagation();if(!confirm('¿Confirma la entrega del turno?'))return;const btn=e.target.querySelector('button[type="submit"],button:not([type])');if(btn)btn.disabled=true;try{await saveHandoff(new FormData(e.target));toast('Entrega guardada y sincronizada.');renderHandoff362();refreshBind();}catch(err){toast(err.message||String(err));}finally{if(btn)btn.disabled=false;}return;}
  },true);
  document.addEventListener('click',async e=>{
    const na=e.target.closest?.('[data-note362-archive]');if(na){e.preventDefault();e.stopImmediatePropagation();if(!isAdmin()){toast('Solo Administración puede archivar notas.');return;}if(!confirm('¿Archivar esta nota en el expediente del residente?'))return;const note=currentNotes().find(n=>String(n.id)===String(na.dataset.note362Archive));if(!note){toast('No se encontró la nota.');return;}const now=new Date().toISOString();const data={...note,archivedAt:now,archivedBy:me()?.id||null,archivedByName:me()?.name||me()?.full_name||'Administración'};const {error}=await db().from(NOTES).update({data,updated_at:now,updated_by:me()?.id||null}).eq('organization_id',org()).eq('note_key',na.dataset.note362Archive);if(error)toast(error.message);else{await pullNotes(false);renderNursing362();refreshBind();toast('Nota archivada en el expediente.');}return;}
    const view=e.target.closest?.('[data-handoff362-view]');if(view){e.preventDefault();e.stopImmediatePropagation();showHandoff(view.dataset.handoff362View);return;}
    if(e.target.closest?.('[data-handoff362-hide]')){document.getElementById('handoffDetail362')?.classList.add('hidden');return;}
    const close=e.target.closest?.('[data-handoff362-close]');if(close){e.preventDefault();e.stopImmediatePropagation();await updateHandoff(close.dataset.handoff362Close,{record_status:'closed'});toast('Entrega cerrada.');return;}
    const archive=e.target.closest?.('[data-handoff362-archive]');if(archive){e.preventDefault();e.stopImmediatePropagation();if(!confirm('¿Archivar esta entrega?'))return;await updateHandoff(archive.dataset.handoff362Archive,{record_status:'archived',archived_at:new Date().toISOString(),archived_by:me()?.id||null});toast('Entrega archivada.');return;}
    const del=e.target.closest?.('[data-handoff362-delete]');if(del){e.preventDefault();e.stopImmediatePropagation();if(!confirm('¿Eliminar esta entrega? El registro quedará fuera de la vista activa.'))return;await updateHandoff(del.dataset.handoff362Delete,{active:false});toast('Entrega eliminada.');return;}
  },true);

  window.addEventListener('seniorcare:user-ready',()=>setTimeout(startRealtime,400));
  window.addEventListener('load',()=>setTimeout(startRealtime,1500));
  document.addEventListener('visibilitychange',()=>{if(!document.hidden){pullNotes(true).catch(()=>{});pullHandoffs(true).catch(()=>{});}});
  window.BHSC_NURSING_HANDOFF_GLOBAL={version:VERSION,pullNotes,pullHandoffs};
  console.info(`Notas y entregas globales ${VERSION} listo`);
})();
