/* Bernard Health SeniorCare Enterprise 3.3.5 — residentes activos e inactivos sincronizados */
(function(){
  'use strict';
  const TABLE='seniorcare_residents';
  const VERSION='4.3.68';
  let initialized=false, syncing=false, queued=false, channel=null, timer=null, bootstrapPromise=null;

  const db=()=>window.seniorcareSupabase||null;
  const user=()=>window.currentUser||null;
  const org=()=>user()?.organizationId||user()?.organization_id||null;
  const role=()=>String(user()?.role||'');
  const canWrite=()=>['admin','administrator','supervisor'].includes(role());
  const list=()=>{try{return Array.isArray(residents)?residents:[]}catch(_){return Array.isArray(window.residents)?window.residents:[]}};
  const inactiveList=()=>{try{return Array.isArray(inactiveResidents)?inactiveResidents:[]}catch(_){return Array.isArray(window.inactiveResidents)?window.inactiveResidents:[]}};
  const persist=()=>localStorage.setItem('seniorcare-residents',JSON.stringify(list()));
  const persistInactive=()=>localStorage.setItem('seniorcare-inactive-residents',JSON.stringify(inactiveList()));
  const keyOf=r=>String(r?.resident_key??r?.residentData?.resident_key??r?.residentData?.id??r?.id??r?.identification??r?.key??'').trim();
  const now=()=>new Date().toISOString();
  const uuid=()=>globalThis.crypto?.randomUUID?.()||`resident-${Date.now()}-${Math.random().toString(16).slice(2)}`;

  function ensureKeys(){
    let changed=false;
    for(const r of list()){
      if(!r)continue;
      const key=keyOf(r)||uuid();
      if(String(r.resident_key||'')!==key){r.resident_key=key;changed=true;}
      if(r.id===undefined||r.id===null||r.id===''){r.id=key;changed=true;}
    }
    for(const item of inactiveList()){
      if(!item)continue;
      const key=keyOf(item)||uuid();
      item.resident_key=key;
      item.id=key;
      item.residentData=item.residentData||{};
      item.residentData.resident_key=key;
      item.residentData.id=item.residentData.id||key;
    }
    if(changed)persist();
    persistInactive();
  }

  function activeFromRow(row){
    const d={...(row.data||{})};
    const key=String(row.resident_key||d.resident_key||d.id||row.id||'').trim();
    return {
      ...d,id:d.id??key,resident_key:key,
      name:row.full_name||row.resident_name||d.name||d.full_name||'Residente',
      identification:row.identification_number||d.identification||d.identification_number||'',identification_number:row.identification_number||d.identification_number||d.identification||'',
      age:row.age??d.age??0,room:row.room||d.room||'Sin asignar',
      status:row.status&&row.status!=='Inactivo'?row.status:(d.status&&d.status!=='Inactivo'?d.status:'Estable'),
      risk:row.risk_level||d.risk||'Riesgo bajo',diet:row.nutrition_notes||d.diet||'Corriente',
      contact:row.emergency_contact||d.contact||'',dx:row.diagnoses||d.dx||'',allergy:row.allergies||d.allergy||'Ninguna conocida'
    };
  }

  function inactiveFromRow(row){
    const d={...(row.data||{})};
    const base={...(d.residentData||d)};
    const key=String(row.resident_key||base.resident_key||base.id||row.id||'').trim();
    const classification=d.classification||d.inactiveClassification||base.inactiveClassification||'Baja';
    const reason=d.reason||d.inactiveReason||base.inactiveReason||classification;
    const residentData={...base,id:base.id??key,resident_key:key,name:row.full_name||row.resident_name||base.name||'Residente',identification:row.identification_number||base.identification||base.identification_number||'',identification_number:row.identification_number||base.identification_number||base.identification||'',age:row.age??base.age??0,room:row.room||base.room||'Sin asignar',status:'Inactivo',inactiveClassification:classification,inactiveReason:reason};
    return {id:key,resident_key:key,name:residentData.name,age:residentData.age,room:residentData.room,status:'Inactivo',classification,reason,inactiveDate:d.inactiveDate||row.updated_at||row.created_at||now(),residentData};
  }

  function rowOf(r){
    const key=keyOf(r)||uuid(); r.resident_key=key; if(!r.id)r.id=key;
    return {organization_id:org(),resident_key:key,identification_number:r.identification||r.identification_number||'',full_name:r.name||r.full_name||'',resident_name:r.name||r.full_name||'',age:Number(r.age)||null,room:r.room||'',status:r.status||'Estable',risk_level:r.risk||'',diagnoses:r.dx||'',allergies:r.allergy||'',nutrition_notes:r.diet||'',emergency_contact:r.contact||'',data:{...r,resident_key:key},active:true,updated_at:now(),updated_by:user()?.id||null};
  }

  function rowOfInactive(item){
    const r={...(item.residentData||{}),...item};
    const key=keyOf(item)||uuid();
    const classification=item.classification||r.inactiveClassification||'Baja';
    const reason=item.reason||r.inactiveReason||classification;
    return {organization_id:org(),resident_key:key,identification_number:item.identification||r.identification||r.identification_number||'',full_name:item.name||r.name||'',resident_name:item.name||r.name||'',age:Number(item.age??r.age)||null,room:item.room||r.room||'',status:'Inactivo',risk_level:r.risk||'',diagnoses:r.dx||'',allergies:r.allergy||'',nutrition_notes:r.diet||'',emergency_contact:r.contact||'',data:{...r,resident_key:key,status:'Inactivo',classification,reason,inactiveClassification:classification,inactiveReason:reason,inactiveDate:item.inactiveDate||now(),residentData:{...r,resident_key:key,status:'Inactivo'}},active:false,updated_at:now(),updated_by:user()?.id||null};
  }

  function assertReady(){if(!db())throw new Error('No hay conexión con Supabase.');if(!org())throw new Error('La cuenta no tiene organización asignada.');}

  async function pull({render=true}={}){
    assertReady();
    const {data,error}=await db().from(TABLE).select('*').eq('organization_id',org()).order('updated_at',{ascending:true});
    if(error)throw error;
    const rows=(data||[]).filter(row=>row?.data?.deleted!==true&&String(row?.status||'').toLowerCase()!=='eliminado');
    const active=rows.filter(row=>row.active!==false&&row.status!=='Inactivo').map(activeFromRow).filter(r=>r.resident_key&&r.name);
    const inactive=rows.filter(row=>row.active===false||row.status==='Inactivo').map(inactiveFromRow).filter(r=>r.resident_key&&r.name);
    const selectedKey=keyOf(window.selectedResident);
    list().splice(0,list().length,...active);
    inactiveList().splice(0,inactiveList().length,...inactive);
    persist();persistInactive();
    if(selectedKey){const next=active.find(r=>keyOf(r)===selectedKey)||inactive.find(r=>keyOf(r)===selectedKey)?.residentData;if(next){window.selectedResident=next;try{selectedResident=next}catch(_){}}}
    initialized=true;
    if(render&&['home','residents','inactive','resident'].includes(window.activeScreen||'')){if(typeof window.render==='function')window.render();else window.go?.(window.activeScreen,{scope:window.residentScoped?'resident':'global'},{replace:true});}
    return true;
  }

  async function saveOne(r,{pullAfter=true}={}){assertReady();if(!canWrite())throw new Error('Este usuario no tiene permiso para crear residentes.');const payload=rowOf(r);const {error}=await db().from(TABLE).upsert(payload,{onConflict:'organization_id,resident_key'});if(error)throw error;if(pullAfter)await pull({render:false});return payload;}

  async function deleteOne(r){
    assertReady();
    if(!canWrite())throw new Error('Este usuario no tiene permiso para eliminar residentes.');
    const key=keyOf(r);
    if(!key)throw new Error('No se pudo identificar al residente.');
    const stamp=now();
    let removedByRpc=false;
    if(typeof window.BHSC_CALL_RPC==='function'){
      const rpc=await window.BHSC_CALL_RPC(['bh_delete_resident_v4368'],{p_resident_key:key});
      if(!rpc?.error)removedByRpc=true;
      else if(!window.BHSC_RPC_FUNCTION_MISSING?.(rpc.error))throw rpc.error;
    }
    if(!removedByRpc){
      const payload={
        active:false,
        status:'Eliminado',
        data:{...(r||{}),resident_key:key,status:'Eliminado',deleted:true,deleted_at:stamp,deleted_by:user()?.id||null},
        updated_at:stamp,
        updated_by:user()?.id||null
      };
      const query=await db().from(TABLE).update(payload).eq('organization_id',org()).eq('resident_key',key).select('resident_key').maybeSingle();
      if(query.error)throw query.error;
      if(!query.data)throw new Error('No se pudo confirmar la eliminación del residente en la nube.');
    }
    const active=list();
    const inactive=inactiveList();
    active.splice(0,active.length,...active.filter(x=>keyOf(x)!==key));
    inactive.splice(0,inactive.length,...inactive.filter(x=>keyOf(x)!==key));
    persist();persistInactive();
    try{
      const map=window.residentAssignments||{};
      Object.keys(map).forEach(k=>{if(Array.isArray(map[k]))map[k]=map[k].filter(v=>String(v)!==key)});
      localStorage.setItem('seniorcare-resident-assignments',JSON.stringify(map));
    }catch(_){ }
    if(keyOf(window.selectedResident)===key){window.selectedResident=null;try{selectedResident=null}catch(_){}}
    return true;
  }

  async function pushNow(){
    if(syncing){queued=true;return false;} assertReady(); if(!canWrite())return false; syncing=true;
    try{
      ensureKeys();
      for(const r of list().filter(r=>r&&keyOf(r))){const {error}=await db().from(TABLE).upsert(rowOf(r),{onConflict:'organization_id,resident_key'});if(error)throw error;}
      for(const item of inactiveList().filter(r=>r&&keyOf(r))){const {error}=await db().from(TABLE).upsert(rowOfInactive(item),{onConflict:'organization_id,resident_key'});if(error)throw error;}
      await pull({render:false}); return true;
    }finally{syncing=false;if(queued){queued=false;setTimeout(()=>pushNow().catch(console.error),0);}}
  }

  async function bootstrap(){
    if(bootstrapPromise)return bootstrapPromise;
    bootstrapPromise=(async()=>{assertReady();ensureKeys();await pull({render:false});if(channel){try{await db().removeChannel(channel)}catch(_){}}channel=db().channel(`bhsc-residents-${org()}`).on('postgres_changes',{event:'*',schema:'public',table:TABLE,filter:`organization_id=eq.${org()}`},()=>pull({render:true}).catch(console.error)).subscribe();initialized=true;return true;})().finally(()=>{bootstrapPromise=null;});
    return bootstrapPromise;
  }

  function schedulePush(){clearTimeout(timer);timer=setTimeout(async()=>{try{if(!initialized)await bootstrap();await pushNow();}catch(err){console.error('[BHSC Residents]',err);window.showToast?.(err.message||'No se pudo sincronizar residentes.');}},220);}
  const previousSave=window.saveResidents;
  window.saveResidents=function(){ensureKeys();if(typeof previousSave==='function')previousSave.apply(this,arguments);else persist();schedulePush();};
  window.saveResidentToCloud=saveOne;window.deleteResidentFromCloud=deleteOne;window.pullResidentsFromCloud=pull;window.pushResidentsToCloud=pushNow;
  window.BHSC_RESIDENT_SYNC_STATUS=()=>({version:VERSION,initialized,syncing,organizationId:org(),active:list().length,inactive:inactiveList().length});
  window.addEventListener('seniorcare:user-ready',()=>setTimeout(()=>bootstrap().catch(err=>{console.error('[BHSC Residents bootstrap]',err);window.showToast?.(err.message||'No se pudo iniciar la sincronización.');}),150));
  document.addEventListener('visibilitychange',()=>{if(!document.hidden&&initialized)pull({render:true}).catch(console.error);});
  window.addEventListener('focus',()=>{if(initialized)pull({render:true}).catch(console.error);});
  window.addEventListener('pageshow',()=>{if(initialized)pull({render:true}).catch(console.error);});
  window.addEventListener('online',()=>{if(initialized)pull({render:true}).catch(console.error);});
  console.info('BHSC resident sync',VERSION);
})();
