/* Bernard Health SeniorCare Enterprise 3.2.8 — plan por turno y Realtime dedicado */
(function(){
  'use strict';
  const VERSION='3.6.2';
  const TABLE='seniorcare_care_tasks';
  const SHIFTS=['Matutino','Vespertino','Nocturno'];
  let selectedShift=normalizeShift(localStorage.getItem('seniorcare-care-shift')||'Matutino');
  let editing=false;
  let customDraft=[];
  let channel=null;
  let pulling=false;
  let saving=false;
  let lastSignature='';
  let dayTimer=null;

  const esc=v=>String(v??'').replace(/[&<>"']/g,m=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]));
  const db=()=>window.seniorcareSupabase||null;
  const user=()=>window.currentUser||null;
  const org=()=>user()?.organizationId||user()?.organization_id||null;
  const isAdmin=()=>user()?.role==='admin';
  function normalizeShift(v){const s=String(v||'Matutino').replace(/^Turno\s+/i,'').trim();return SHIFTS.includes(s)?s:'Matutino';}
  function residentKeyStable(r){return String(window.residentKey?.(r)||r?.resident_key||r?.id||'').trim();}
  function planKey(r,s=selectedShift){return `${residentKeyStable(r)}:${normalizeShift(s)}`;}
  function taskList(r,s=selectedShift){const a=window.carePlans?.[planKey(r,s)];return Array.isArray(a)?a:[];}
  function persist(){window.saveCarePlans?.(); if(!window.saveCarePlans)localStorage.setItem('seniorcare-care-plans',JSON.stringify(window.carePlans||{}));}
  function currentResident(){return window.selectedResident||window.residents?.[0]||null;}
  function taskSlug(v){const x=String(v||'tarea').normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');return x||`tarea-${Date.now()}`;}
  function localDay(v=new Date()){const d=v instanceof Date?v:new Date(v);if(Number.isNaN(d.getTime()))return '';const y=d.getFullYear(),m=String(d.getMonth()+1).padStart(2,'0'),day=String(d.getDate()).padStart(2,'0');return `${y}-${m}-${day}`;}
  function completedToday(value){return !!value&&localDay(value)===localDay();}
  function signature(rows){return `${localDay()}|${JSON.stringify((rows||[]).map(r=>[r.resident_key,r.shift_name,r.task_key,r.completed,r.completed_at,r.active,r.updated_at]).sort())}`;}
  function scheduleDayBoundary(){clearTimeout(dayTimer);const n=new Date(),next=new Date(n.getFullYear(),n.getMonth(),n.getDate()+1,0,0,2);dayTimer=setTimeout(()=>{lastSignature='';pullCare328({render:true}).catch(console.warn);scheduleDayBoundary();},Math.max(1000,next-n));}

  function catalog(r,s){return [...new Set([...(window.defaultCareTasks||[]),...taskList(r,s).map(x=>x.name).filter(Boolean),...customDraft])];}

  function renderCare328(){
    const role=user()?.role||'admin';
    if(role==='admin'&&!window.residentScoped){
      const pending=[], completed=[];
      (window.residents||[]).forEach(r=>SHIFTS.forEach(s=>taskList(r,s).forEach(t=>(t.done?completed:pending).push({...t,resident:r,shift:s}))));
      window.main.innerHTML=window.pageHeader('SEGUIMIENTO OPERATIVO','Cuidados por residente','Planes definidos por Administración y ejecución del personal')+`
      <section class="care-review-summary"><article><span>Pendientes</span><strong>${pending.length}</strong></article><article><span>Completados</span><strong>${completed.length}</strong></article><article><span>Residentes con pendientes</span><strong>${new Set(pending.map(x=>residentKeyStable(x.resident))).size}</strong></article></section>
      <div class="care-review-list">${pending.length?pending.map(t=>`<article><div><strong>${esc(t.resident.name)}</strong><span>${esc(t.shift)} · ${esc(t.name)}</span></div><span class="status warn">Pendiente</span><button class="mini-btn" data-care328-open="${esc(residentKeyStable(t.resident))}" data-care328-shift="${esc(t.shift)}">Revisar</button></article>`).join(''):window.empty('No hay cuidados pendientes.')}</div>
      <section class="history-card"><h3>Últimos cuidados completados</h3>${completed.slice(0,20).map(t=>`<div class="history-line"><b>${esc(t.resident.name)} · ${esc(t.name)}</b><span>${esc(t.shift)} · ${t.completedAt?window.fmtDate(t.completedAt):'Completado'} · ${esc(t.completedBy||'Sin responsable')}</span></div>`).join('')||window.empty('No hay cuidados completados.')}</section>`;
      return;
    }
    const r=currentResident();
    if(!r){window.main.innerHTML=window.empty('No hay residentes disponibles.');return;}
    const list=taskList(r,selectedShift), done=list.filter(t=>t.done).length;
    const assigned=new Set(list.map(t=>String(t.name||'').trim()));
    const editor=isAdmin()&&editing?`<section class="form-card care-plan-config"><div class="toolbar-copy"><strong>Editar plan del ${esc(selectedShift)}</strong><span>Marque únicamente las tareas que debe realizar el personal en este turno.</span></div><div class="checklist care-plan-selector">${catalog(r,selectedShift).map(name=>`<label class="check-item"><input type="checkbox" data-care328-option value="${esc(name)}" ${assigned.has(name)?'checked':''}><span class="checkmark">${window.svg.check}</span><div><strong>${esc(name)}</strong><small>${assigned.has(name)?'Asignada':'Disponible'}</small></div></label>`).join('')}</div><div class="form-actions"><button class="secondary-btn" type="button" data-care328-add>Añadir tarea personalizada</button><button class="secondary-btn" type="button" data-care328-cancel>Cancelar</button><button class="primary-btn" type="button" data-care328-save>Guardar plan</button></div></section>`:'';
    window.main.innerHTML=window.pageHeader('CUIDADOS DIARIOS','Plan de cuidados',`${isAdmin()?'Configuración':'Tareas asignadas'} de ${esc(r.name)}`)+`
      <section class="care-resident-strip"><div><strong>${esc(r.name)}</strong><span>${esc(r.room||'')} · ${esc(selectedShift)}</span></div><span class="status ok">${done}/${list.length} completadas</span></section>
      <div class="care-controls">${isAdmin()?`<select data-care328-resident>${(window.residents||[]).map(x=>`<option value="${esc(residentKeyStable(x))}" ${residentKeyStable(x)===residentKeyStable(r)?'selected':''}>${esc(x.name)}</option>`).join('')}</select>`:''}<select data-care328-shift>${SHIFTS.map(s=>`<option value="${s}" ${s===selectedShift?'selected':''}>${s}</option>`).join('')}</select>${isAdmin()&&!editing?'<button class="primary-btn" type="button" data-care328-edit>Editar plan</button>':''}</div>
      ${editor}
      <section class="checklist care-checklist">${list.length?list.map(t=>`<article class="check-item editable-task ${t.done?'done':''}"><label><input type="checkbox" data-care328-check="${esc(t.id)}" ${t.done?'checked':''} ${isAdmin()?'disabled':''}><span class="checkmark">${window.svg.check}</span><div><strong>${esc(t.name)}</strong><small>${t.done?`Completada${t.completedBy?` por ${esc(t.completedBy)}`:''}`:'Pendiente de realizar'}</small></div></label></article>`).join(''):window.empty(isAdmin()?'No hay tareas asignadas en este turno. Pulse “Editar plan”.':'No hay tareas asignadas para este residente y turno.')}</section>`;
  }

  window.renderCare=renderCare328;

  async function pullCare328({render=true}={}){
    if(pulling||!db()||!org())return;
    pulling=true;
    try{
      const {data,error}=await db().from(TABLE).select('*').eq('organization_id',org()).eq('active',true).order('updated_at',{ascending:false});
      if(error)throw error;
      const sig=signature(data||[]);
      const grouped={};
      for(const row of data||[]){
        const s=normalizeShift(row.shift_name||row.data?.shift);
        const key=`${String(row.resident_key)}:${s}`;
        (grouped[key]??=[]).push({...(row.data||{}),id:row.data?.id||row.task_key,name:row.task_name||row.data?.name||'Tarea',shift:s,done:row.completed===true&&completedToday(row.completed_at),completedAt:row.completed_at||null,completedBy:row.completed_by||null});
      }
      const store=window.carePlans||{};
      Object.keys(store).forEach(k=>delete store[k]);
      Object.entries(grouped).forEach(([k,v])=>store[k]=v);
      persist();
      const changed=sig!==lastSignature; lastSignature=sig;
      if(render&&changed&&window.activeScreen==='care'&&!editing){renderCare328();window.bindActions?.();}
    }finally{pulling=false;}
  }

  async function saveExplicit(r,s,tasks){
    if(saving)throw new Error('Ya se está guardando el plan.');
    if(!db()||!org())throw new Error('No hay conexión con Supabase.');
    const rid=residentKeyStable(r), shift=normalizeShift(s), now=new Date().toISOString();
    if(!rid)throw new Error('No se pudo identificar al residente.');
    saving=true;
    try{
      const {error:offError}=await db().from(TABLE).update({active:false,updated_at:now,updated_by:user()?.id||null}).eq('organization_id',org()).eq('resident_key',rid).eq('shift_name',shift);
      if(offError)throw offError;
      if(tasks.length){
        const rows=tasks.map(t=>({organization_id:org(),resident_key:rid,resident_name:r?.name||'',shift_name:shift,task_key:taskSlug(t.name),task_name:t.name||'Tarea',completed:t.done===true,completed_at:t.done?(t.completedAt||now):null,completed_by:t.done?(t.completedBy||user()?.name||'Usuario'):null,data:{...t,shift},active:true,updated_at:now,updated_by:user()?.id||null}));
        const {error}=await db().from(TABLE).upsert(rows,{onConflict:'organization_id,resident_key,shift_name,task_key'});if(error)throw error;
      }
      await pullCare328({render:false});
    }finally{saving=false;}
  }

  async function startRealtime(){
    if(!db()||!org())return;
    await pullCare328({render:false}).catch(console.warn);
    try{
      if(channel)await db().removeChannel(channel);
      scheduleDayBoundary();
      channel=db().channel(`bhsc-care-362-${org()}`)
        .on('postgres_changes',{event:'*',schema:'public',table:TABLE,filter:`organization_id=eq.${org()}`},()=>pullCare328({render:true}).catch(console.warn))
        .subscribe(status=>console.info('[BHSC care realtime]',status));
    }catch(e){console.warn('[BHSC care realtime]',e);}
  }

  document.addEventListener('change',async e=>{
    const shiftSel=e.target.closest?.('[data-care328-shift],#careShiftSelect');
    if(shiftSel){e.preventDefault();e.stopPropagation();e.stopImmediatePropagation();selectedShift=normalizeShift(shiftSel.value);localStorage.setItem('seniorcare-care-shift',selectedShift);editing=false;customDraft=[];renderCare328();window.bindActions?.();return;}
    const residentSel=e.target.closest?.('[data-care328-resident],#careResidentSelect');
    if(residentSel){e.preventDefault();e.stopPropagation();e.stopImmediatePropagation();window.selectedResident=(window.residents||[]).find(r=>residentKeyStable(r)===String(residentSel.value))||window.selectedResident;editing=false;customDraft=[];renderCare328();window.bindActions?.();return;}
    const box=e.target.closest?.('[data-care328-check]');
    if(box){e.preventDefault();e.stopPropagation();e.stopImmediatePropagation();const r=currentResident();const list=taskList(r,selectedShift);const t=list.find(x=>String(x.id)===String(box.dataset.care328Check));if(!t)return;t.done=box.checked;t.completedAt=t.done?new Date().toISOString():null;t.completedBy=t.done?(user()?.name||'Usuario'):null;persist();renderCare328();window.bindActions?.();try{await saveExplicit(r,selectedShift,list);window.showToast?.(t.done?'Cuidado completado y sincronizado.':'Cuidado reabierto y sincronizado.');}catch(err){window.showToast?.(err.message||String(err));await pullCare328({render:true}).catch(()=>{});}return;}
  },true);

  document.addEventListener('click',async e=>{
    const open=e.target.closest?.('[data-care328-open]');if(open){e.preventDefault();e.stopImmediatePropagation();window.selectedResident=(window.residents||[]).find(r=>residentKeyStable(r)===String(open.dataset.care328Open))||window.selectedResident;selectedShift=normalizeShift(open.dataset.care328Shift);localStorage.setItem('seniorcare-care-shift',selectedShift);window.residentScoped=true;editing=false;renderCare328();window.bindActions?.();return;}
    if(e.target.closest?.('[data-care328-edit],#editCarePlan')){e.preventDefault();e.stopImmediatePropagation();editing=true;customDraft=[];renderCare328();window.bindActions?.();return;}
    if(e.target.closest?.('[data-care328-cancel],#cancelCarePlanEdit')){e.preventDefault();e.stopImmediatePropagation();editing=false;customDraft=[];renderCare328();window.bindActions?.();return;}
    if(e.target.closest?.('[data-care328-add],#addCarePlanOption')){e.preventDefault();e.stopImmediatePropagation();const name=prompt(`Nueva tarea para el turno ${selectedShift}:`);if(name?.trim()&&!catalog(currentResident(),selectedShift).some(x=>x.toLowerCase()===name.trim().toLowerCase())){customDraft.push(name.trim());renderCare328();window.bindActions?.();const b=[...document.querySelectorAll('[data-care328-option]')].find(x=>x.value===name.trim());if(b)b.checked=true;}return;}
    const save=e.target.closest?.('[data-care328-save],#saveCarePlan');if(save){e.preventDefault();e.stopPropagation();e.stopImmediatePropagation();const r=currentResident();const names=[...document.querySelectorAll('[data-care328-option]:checked,[data-care-plan-option]:checked')].map(x=>String(x.value||'').trim()).filter(Boolean);const existing=new Map(taskList(r,selectedShift).map(t=>[String(t.name||'').trim(),t]));const next=names.map(name=>({...existing.get(name),id:existing.get(name)?.id||crypto.randomUUID?.()||String(Date.now()+Math.random()),name,shift:selectedShift,done:existing.get(name)?.done===true,completedAt:existing.get(name)?.completedAt||null,completedBy:existing.get(name)?.completedBy||null}));window.carePlans[planKey(r,selectedShift)]=next;persist();save.disabled=true;const old=save.textContent;save.textContent='Guardando...';try{await saveExplicit(r,selectedShift,next);editing=false;customDraft=[];window.showToast?.(`Plan ${selectedShift} guardado y sincronizado.`);renderCare328();window.bindActions?.();}catch(err){window.showToast?.(err.message||String(err));alert(err.message||String(err));}finally{if(save.isConnected){save.disabled=false;save.textContent=old;}}return;}
  },true);

  window.addEventListener('seniorcare:user-ready',startRealtime);
  window.addEventListener('load',()=>setTimeout(startRealtime,1200));
  document.addEventListener('visibilitychange',()=>{if(!document.hidden)pullCare328({render:true}).catch(()=>{});});
  window.BHSC_PULL_CARE_328=pullCare328;
  window.BHSC_SAVE_CARE_EXPLICIT=saveExplicit;
})();
