/* Bernard Health SeniorCare Enterprise 3.3.0
   Núcleo clínico global: contrato único de sincronización para módulos clínicos.
   Conserva adaptadores ya estabilizados y añade Curaciones, Notas de enfermería
   y Entrega de turno bajo el mismo patrón Supabase + Realtime. */
(function(){
  'use strict';
  const VERSION='3.3.2';
  const db=()=>window.seniorcareSupabase||null;
  const user=()=>window.currentUser||null;
  const org=()=>user()?.organizationId||user()?.organization_id||null;
  const now=()=>new Date().toISOString();
  const clean=v=>String(v??'').trim();
  const uuid=()=>crypto.randomUUID?.()||`${Date.now()}-${Math.random().toString(16).slice(2)}`;
  const channels=new Map();
  const timers=new Map();
  let startedOrg=null;

  function residentsList(){ try{return Array.isArray(residents)?residents:[]}catch(_){return Array.isArray(window.residents)?window.residents:[]} }
  function residentKey(r){return clean(r?.resident_key||r?.residentKey||r?.id)}
  function residentByAny(v){const x=clean(v);return residentsList().find(r=>residentKey(r)===x||clean(r.id)===x||clean(r.name)===x||clean(r.full_name)===x)}
  function residentLocalKey(stable){const r=residentByAny(stable);return r?.id??stable}
  function safeDate(v){const d=new Date(v);return Number.isNaN(d.getTime())?now():d.toISOString()}
  function currentScreen(){try{return activeScreen}catch(_){return window.activeScreen||''}}
  function renderRelevant(screens){
    if(!screens.includes(currentScreen()))return;
    const y=window.scrollY||0;
    requestAnimationFrame(()=>{
      try{
        if(typeof window.render==='function')window.render();
        else if(currentScreen()==='wounds'&&typeof renderWounds==='function')renderWounds();
        else if(currentScreen()==='nursing'&&typeof renderNursing==='function')renderNursing();
        else if(currentScreen()==='handoff'&&typeof renderHandoff==='function')renderHandoff();
        window.bindActions?.();
      }catch(e){console.warn('[BHSC Global render]',e)}
      requestAnimationFrame(()=>window.scrollTo(0,y));
    });
  }
  function debounce(name,fn,ms=180){clearTimeout(timers.get(name));timers.set(name,setTimeout(fn,ms))}
  async function deactivateMissing(table,keyColumn,keys){
    const client=db(),organization=org();if(!client||!organization)return;
    const {data,error}=await client.from(table).select(keyColumn).eq('organization_id',organization).eq('active',true);
    if(error)throw error;
    const keep=new Set(keys.map(String));
    const missing=(data||[]).map(r=>String(r[keyColumn])).filter(k=>!keep.has(k));
    if(missing.length){const {error:e}=await client.from(table).update({active:false,updated_at:now(),updated_by:user()?.id||null}).eq('organization_id',organization).in(keyColumn,missing);if(e)throw e;}
  }

  const adapters={
    wounds:{
      table:'seniorcare_wound_records',key:'record_key',screens:['wounds','resident','home','alerts'],
      local(){const rows=[];try{Object.entries(woundRecords||{}).forEach(([rid,list])=>{const r=residentByAny(rid);(list||[]).forEach(item=>rows.push({rid,r,item}))})}catch(_){}return rows},
      row(x){const id=clean(x.item.id)||uuid();x.item.id=id;return {organization_id:org(),resident_key:residentKey(x.r)||clean(x.rid),resident_name:x.r?.name||x.r?.full_name||'',record_key:id,area:x.item.area||'',status:x.item.status||'Pendiente',scheduled_date:x.item.next||null,recorded_at:safeDate(x.item.date),data:x.item,active:x.item.archived!==true,updated_at:now(),updated_by:user()?.id||null}},
      apply(rows){const map={};for(const row of rows){const k=residentLocalKey(row.resident_key);const d={...(row.data||{}),id:row.record_key,date:row.recorded_at,area:row.area||row.data?.area||'',status:row.status||row.data?.status||'',next:row.scheduled_date||row.data?.next||'',archived:false};(map[k]||(map[k]=[])).push(d)};try{woundRecords=map;localStorage.setItem('seniorcare-wounds',JSON.stringify(map))}catch(_){window.woundRecords=map}},
    },
    nursing:{
      table:'seniorcare_nursing_notes',key:'note_key',screens:['nursing','resident','home','alerts'],
      local(){const rows=[];try{Object.entries(nursingNotes||{}).forEach(([rid,list])=>{const r=residentByAny(rid);(list||[]).forEach(item=>rows.push({rid,r,item}))})}catch(_){}return rows},
      row(x){const id=clean(x.item.id)||uuid();x.item.id=id;return {organization_id:org(),resident_key:residentKey(x.r)||clean(x.rid),resident_name:x.r?.name||x.r?.full_name||'',note_key:id,shift_name:x.item.shift||'',clinical_status:x.item.status||'',note_text:x.item.note||'',recorded_at:safeDate(x.item.date),author_name:x.item.author||user()?.name||'',data:x.item,active:true,updated_at:now(),updated_by:user()?.id||null}},
      apply(rows){const map={};for(const row of rows){const k=residentLocalKey(row.resident_key);const d={...(row.data||{}),id:row.note_key,date:row.recorded_at,shift:row.shift_name||row.data?.shift||'',status:row.clinical_status||row.data?.status||'',author:row.author_name||row.data?.author||'',note:row.note_text||row.data?.note||''};(map[k]||(map[k]=[])).push(d)};try{nursingNotes=map;localStorage.setItem('seniorcare-nursing-notes',JSON.stringify(map))}catch(_){window.nursingNotes=map}},
    },
    handoffs:{
      table:'seniorcare_handoff_records',key:'handoff_key',screens:['handoff','home','alerts'],
      local(){let list=[];try{list=Array.isArray(handoffRecords)?handoffRecords:[]}catch(_){}return list.map(item=>({item}))},
      row(x){const id=clean(x.item.id)||uuid();x.item.id=id;return {organization_id:org(),handoff_key:id,area_name:x.item.area||'',outgoing_shift:x.item.shift||'',incoming_shift:x.item.incomingShift||'',author_name:x.item.author||'',receiver_name:x.item.receiver||'',recorded_at:safeDate(x.item.date),data:x.item,active:true,updated_at:now(),updated_by:user()?.id||null}},
      apply(rows){const list=rows.map(row=>({...row.data,id:row.handoff_key,date:row.recorded_at,area:row.area_name||row.data?.area||'',shift:row.outgoing_shift||row.data?.shift||'',incomingShift:row.incoming_shift||row.data?.incomingShift||'',author:row.author_name||row.data?.author||'',receiver:row.receiver_name||row.data?.receiver||''}));try{handoffRecords=list;localStorage.setItem('seniorcare-handoffs',JSON.stringify(list))}catch(_){window.handoffRecords=list}},
    }
  };

  async function push(name){
    const a=adapters[name],client=db(),organization=org();if(!a||!client||!organization)return;
    const local=a.local(),rows=local.map(x=>a.row(x));
    if(rows.length){const {error}=await client.from(a.table).upsert(rows,{onConflict:name==='wounds'?'organization_id,resident_key,record_key':`organization_id,${a.key}`});if(error)throw error;}
    await deactivateMissing(a.table,a.key,rows.map(r=>r[a.key]));
  }
  async function pull(name,{render=true}={}){
    const a=adapters[name],client=db(),organization=org();if(!a||!client||!organization)return;
    const {data,error}=await client.from(a.table).select('*').eq('organization_id',organization).eq('active',true).order('updated_at',{ascending:false});
    if(error)throw error;a.apply(data||[]);if(render)renderRelevant(a.screens);
  }
  async function subscribe(name){
    const a=adapters[name],client=db(),organization=org();if(!a||!client||!organization)return;
    const old=channels.get(name);if(old)try{await client.removeChannel(old)}catch(_){}
    const ch=client.channel(`bhsc-global-${name}-${organization}`).on('postgres_changes',{event:'*',schema:'public',table:a.table,filter:`organization_id=eq.${organization}`},()=>pull(name,{render:true}).catch(e=>console.error(`[BHSC ${name} realtime]`,e))).subscribe(status=>console.info(`[BHSC ${name} realtime]`,status));
    channels.set(name,ch);
  }
  function wrapSave(globalName,adapterName){
    let original;try{original=eval(globalName)}catch(_){original=window[globalName]}
    if(typeof original!=='function'||original.__bhscGlobalWrapped)return;
    const wrapped=function(...args){const result=original.apply(this,args);debounce(adapterName,()=>push(adapterName).catch(e=>{console.error(`[BHSC ${adapterName} push]`,e);window.showToast?.(`No se pudo sincronizar ${adapterName}: ${e?.message||'error desconocido'}`)}));return result};
    wrapped.__bhscGlobalWrapped=true;
    try{eval(`${globalName}=wrapped`)}catch(_){window[globalName]=wrapped}
  }
  async function bootstrapAdapter(name){
    const a=adapters[name];
    await pull(name,{render:false});
    await subscribe(name);
  }
  async function start(){
    const organization=org();if(!db()||!organization)return;if(startedOrg===organization&&channels.size)return;startedOrg=organization;
    wrapSave('saveWoundRecords','wounds');wrapSave('saveNursingNotes','nursing');wrapSave('saveHandoffs','handoffs');
    for(const name of Object.keys(adapters)){try{await bootstrapAdapter(name)}catch(e){console.error(`[BHSC Global ${name}]`,e)}}
    renderRelevant(['wounds','nursing','handoff','resident','home','alerts']);
  }
  async function refreshAll(){for(const name of Object.keys(adapters)){try{await pull(name,{render:false})}catch(e){console.warn(`[BHSC refresh ${name}]`,e)}}renderRelevant(['wounds','nursing','handoff','resident','home','alerts'])}

  window.BHSC_CLINICAL_GLOBAL={version:VERSION,start,refreshAll,pull,push,status:()=>({version:VERSION,organizationId:org(),channels:[...channels.keys()],existingAdapters:{residents:!!window.seniorcarePullResidents,vitals:!!window.seniorcarePullClinical,alerts:!!window.BHSC_ALERTS_PULL,medications:!!window.seniorcarePullMedications,care:!!window.BHSC_CARE_PULL,nutritionPlans:!!window.BHSC_NUTRITION_PLAN_PULL}})};
  window.addEventListener('seniorcare:user-ready',()=>setTimeout(start,500));
  window.addEventListener('load',()=>setTimeout(start,1800));
  window.addEventListener('online',()=>refreshAll());
  document.addEventListener('visibilitychange',()=>{if(!document.hidden)refreshAll()});
})();
