/* Bernard Health SeniorCare V4.3.21 — reporte mensual administrativo de asistencia */
(function(){
  'use strict';
  if(window.__bhscAttendanceMonthlyV4320)return;
  window.__bhscAttendanceMonthlyV4320=true;

  const TABLE='attendance_records';
  const SECTION_ID='attendanceMonthlyReportV4320';
  const STYLE_ID='attendanceMonthlyReportStylesV4320';
  const MONTH_KEY='bhsc-attendance-report-month';
  let currentRows=[];
  let currentMonth='';
  let loadSequence=0;

  const esc=value=>String(value??'').replace(/[&<>"']/g,char=>({
    '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'
  }[char]));

  const normalizedRole=()=>String(window.currentUser?.role||'')
    .normalize('NFD').replace(/[\u0300-\u036f]/g,'').trim().toLowerCase();
  const isAdmin=()=>['admin','administrator','administrador'].includes(normalizedRole());
  const organizationId=()=>window.currentUser?.organizationId||window.currentUser?.organization_id||null;
  const db=()=>window.seniorcareSupabase||null;
  const toast=message=>window.showToast?.(message);

  function costaRicaMonth(){
    const parts=new Intl.DateTimeFormat('en-CA',{
      timeZone:'America/Costa_Rica',year:'numeric',month:'2-digit'
    }).formatToParts(new Date());
    const year=parts.find(part=>part.type==='year')?.value;
    const month=parts.find(part=>part.type==='month')?.value;
    return `${year}-${month}`;
  }

  function validMonth(value){
    return /^\d{4}-(0[1-9]|1[0-2])$/.test(String(value||''));
  }

  function monthBounds(month){
    if(!validMonth(month))throw new Error('Seleccione un mes válido.');
    const [year,number]=month.split('-').map(Number);
    const lastDay=new Date(Date.UTC(year,number,0)).getUTCDate();
    return {from:`${month}-01`,to:`${month}-${String(lastDay).padStart(2,'0')}`};
  }

  function monthTitle(month){
    if(!validMonth(month))return month;
    const [year,number]=month.split('-').map(Number);
    const label=new Intl.DateTimeFormat('es-CR',{month:'long',year:'numeric',timeZone:'UTC'})
      .format(new Date(Date.UTC(year,number-1,1)));
    return label.charAt(0).toUpperCase()+label.slice(1);
  }

  function normalizeRow(row){
    return {
      id:row.id||row.remoteId||row.client_id||null,
      staffKey:String(row.staff_key||row.staffId||''),
      userId:String(row.user_id||row.userId||''),
      name:String(row.staff_name||row.name||'Sin nombre'),
      role:String(row.role_name||row.role||'Personal'),
      date:String(row.work_date||row.date||''),
      clockIn:row.clock_in||row.clockIn||null,
      clockOut:row.clock_out||row.clockOut||null,
      updatedAt:row.updated_at||row.updatedAt||null
    };
  }

  function dedupeRows(rows){
    const map=new Map();
    for(const raw of rows||[]){
      const row=normalizeRow(raw);
      if(!row.date)continue;
      const key=row.id?`id:${row.id}`:`row:${row.staffKey}|${row.userId}|${row.date}|${row.clockIn||''}`;
      const previous=map.get(key);
      if(!previous||String(row.updatedAt||'')>=String(previous.updatedAt||''))map.set(key,row);
    }
    return [...map.values()].sort((a,b)=>
      String(b.date).localeCompare(String(a.date))||
      String(b.clockIn||'').localeCompare(String(a.clockIn||''))||
      String(a.name).localeCompare(String(b.name),'es')
    );
  }

  function localRows(month){
    const {from,to}=monthBounds(month);
    const logs=Array.isArray(window.attendanceLog)?window.attendanceLog:[];
    return dedupeRows(logs.filter(row=>{
      const date=String(row.work_date||row.date||'');
      return date>=from&&date<=to;
    }));
  }

  async function fetchRows(month){
    const client=db();
    const orgId=organizationId();
    if(!client||!orgId)return {rows:localRows(month),source:'local'};
    const {from,to}=monthBounds(month);
    const pageSize=1000;
    const cloudRows=[];
    // Supabase limita normalmente cada consulta a 1000 filas. Se pagina para que
    // un reporte mensual grande no quede incompleto sin avisar.
    for(let offset=0;offset<50000;offset+=pageSize){
      const response=await client.from(TABLE).select('*')
        .eq('organization_id',orgId)
        .gte('work_date',from)
        .lte('work_date',to)
        .order('work_date',{ascending:false})
        .order('clock_in',{ascending:false})
        .range(offset,offset+pageSize-1);
      if(response.error)throw response.error;
      const page=Array.isArray(response.data)?response.data:[];
      cloudRows.push(...page);
      if(page.length<pageSize)break;
    }
    return {rows:dedupeRows(cloudRows),source:'cloud'};
  }

  function hoursNumber(row){
    if(!row.clockIn||!row.clockOut)return 0;
    const start=new Date(row.clockIn).getTime();
    const end=new Date(row.clockOut).getTime();
    if(!Number.isFinite(start)||!Number.isFinite(end)||end<start)return 0;
    return (end-start)/3600000;
  }

  function formatHours(value){
    return Number(value||0).toLocaleString('es-CR',{minimumFractionDigits:2,maximumFractionDigits:2});
  }

  function formatDate(value){
    if(!value)return '—';
    const date=new Date(`${value}T12:00:00`);
    return Number.isNaN(date.getTime())?String(value):date.toLocaleDateString('es-CR');
  }

  function formatTime(value){
    if(!value)return '—';
    const date=new Date(value);
    return Number.isNaN(date.getTime())?'—':date.toLocaleTimeString('es-CR',{
      timeZone:'America/Costa_Rica',hour:'2-digit',minute:'2-digit'
    });
  }

  function rowHtml(row){
    const completed=Boolean(row.clockIn&&row.clockOut);
    return `<tr>
      <td>${esc(formatDate(row.date))}</td>
      <td><strong>${esc(row.name)}</strong></td>
      <td>${esc(row.role)}</td>
      <td>${esc(formatTime(row.clockIn))}</td>
      <td>${esc(formatTime(row.clockOut))}</td>
      <td>${completed?esc(formatHours(hoursNumber(row))):'—'}</td>
    </tr>`;
  }

  function reportStats(rows){
    const people=new Set(rows.map(row=>row.userId||row.staffKey||row.name.toLowerCase()).filter(Boolean));
    const completed=rows.filter(row=>row.clockIn&&row.clockOut).length;
    const hours=rows.reduce((total,row)=>total+hoursNumber(row),0);
    return {marks:rows.length,people:people.size,completed,hours};
  }

  function injectStyles(){
    if(document.getElementById(STYLE_ID))return;
    const style=document.createElement('style');
    style.id=STYLE_ID;
    style.textContent=`
      #${SECTION_ID}{margin-top:24px;border:1px solid #e6dcf4;border-radius:24px;background:#fff;box-shadow:0 12px 32px rgba(78,42,125,.08);overflow:hidden}
      #${SECTION_ID} .monthly-attendance-head{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;padding:22px 24px;background:linear-gradient(135deg,#6f35c9,#8c55db);color:#fff}
      #${SECTION_ID} .monthly-attendance-head span{display:block;font-size:.72rem;letter-spacing:.11em;font-weight:850;opacity:.85}
      #${SECTION_ID} .monthly-attendance-head h3{margin:5px 0 4px;font-size:1.22rem}
      #${SECTION_ID} .monthly-attendance-head p{margin:0;max-width:650px;opacity:.9;font-size:.9rem}
      #${SECTION_ID} .monthly-attendance-head strong{white-space:nowrap;background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.24);border-radius:14px;padding:9px 12px;font-size:.82rem}
      #${SECTION_ID} .monthly-attendance-toolbar{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;padding:18px 20px;border-bottom:1px solid #eee7f6;background:#fcfaff}
      #${SECTION_ID} .monthly-attendance-toolbar label{display:grid;gap:6px;color:#574b65;font-size:.78rem;font-weight:800;min-width:180px}
      #${SECTION_ID} .monthly-attendance-toolbar input{min-height:43px;border:1px solid #dcd0ec;border-radius:12px;background:#fff;padding:8px 11px;font:inherit;color:#2d2338}
      #${SECTION_ID} .monthly-attendance-toolbar button{min-height:43px}
      #${SECTION_ID} .monthly-attendance-status{padding:10px 20px 0;color:#6d607a;font-size:.8rem}
      #${SECTION_ID} .monthly-attendance-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;padding:18px 20px}
      #${SECTION_ID} .monthly-attendance-summary article{border:1px solid #ece4f5;border-radius:16px;padding:14px;background:#fff}
      #${SECTION_ID} .monthly-attendance-summary span{display:block;color:#786b84;font-size:.75rem;font-weight:750}
      #${SECTION_ID} .monthly-attendance-summary strong{display:block;margin-top:4px;color:#4c267f;font-size:1.2rem}
      #${SECTION_ID} .monthly-attendance-table-wrap{overflow:auto;padding:0 20px 20px}
      #${SECTION_ID} table{width:100%;min-width:760px;border-collapse:separate;border-spacing:0;border:1px solid #e7dff0;border-radius:15px;overflow:hidden}
      #${SECTION_ID} th{background:#f4effa;color:#584969;font-size:.76rem;text-align:left;padding:11px 12px;border-bottom:1px solid #e5dcef}
      #${SECTION_ID} td{padding:11px 12px;border-bottom:1px solid #eee8f4;color:#403648;font-size:.84rem;vertical-align:middle}
      #${SECTION_ID} tbody tr:last-child td{border-bottom:0}
      #${SECTION_ID} .monthly-attendance-empty{text-align:center;padding:28px;color:#776a82}
      @media(max-width:760px){
        #${SECTION_ID} .monthly-attendance-head{padding:19px;display:block}
        #${SECTION_ID} .monthly-attendance-head strong{display:inline-block;margin-top:13px}
        #${SECTION_ID} .monthly-attendance-toolbar{align-items:stretch;padding:16px}
        #${SECTION_ID} .monthly-attendance-toolbar label{width:100%;min-width:0}
        #${SECTION_ID} .monthly-attendance-toolbar button{flex:1 1 145px}
        #${SECTION_ID} .monthly-attendance-summary{grid-template-columns:repeat(2,minmax(0,1fr));padding:16px}
        #${SECTION_ID} .monthly-attendance-table-wrap{padding:0 16px 16px}
      }
    `;
    document.head.appendChild(style);
  }

  function sectionHtml(month){
    return `<section id="${SECTION_ID}" aria-live="polite">
      <div class="monthly-attendance-head">
        <div><span>REGISTRO ADMINISTRATIVO</span><h3>Historial mensual de asistencia</h3><p>Consulta las entradas y salidas de todo el personal y genera el archivo mensual para control administrativo.</p></div>
        <strong id="attendanceMonthLabelV4320">${esc(monthTitle(month))}</strong>
      </div>
      <div class="monthly-attendance-toolbar">
        <label>Mes del reporte<input type="month" id="attendanceMonthV4320" value="${esc(month)}"></label>
        <button type="button" class="secondary-btn" id="loadAttendanceMonthV4320">Cargar mes</button>
        <button type="button" class="primary-btn" id="exportAttendanceExcelV4320" disabled>Descargar Excel (CSV)</button>
        <button type="button" class="secondary-btn" id="exportAttendancePdfV4320" disabled>PDF / imprimir</button>
      </div>
      <div class="monthly-attendance-status" id="attendanceMonthStatusV4320">Cargando las marcas del mes…</div>
      <div class="monthly-attendance-summary" id="attendanceMonthSummaryV4320">
        <article><span>Marcas del mes</span><strong>—</strong></article>
        <article><span>Colaboradores</span><strong>—</strong></article>
        <article><span>Jornadas completas</span><strong>—</strong></article>
        <article><span>Horas registradas</span><strong>—</strong></article>
      </div>
      <div class="monthly-attendance-table-wrap"><table>
        <thead><tr><th>Fecha</th><th>Colaborador</th><th>Puesto</th><th>Entrada</th><th>Salida</th><th>Horas</th></tr></thead>
        <tbody id="attendanceMonthBodyV4320"><tr><td colspan="6" class="monthly-attendance-empty">Cargando…</td></tr></tbody>
      </table></div>
    </section>`;
  }

  function updateReport(rows,month,source,errorMessage=''){
    currentRows=rows;
    currentMonth=month;
    const stats=reportStats(rows);
    const body=document.getElementById('attendanceMonthBodyV4320');
    const summary=document.getElementById('attendanceMonthSummaryV4320');
    const status=document.getElementById('attendanceMonthStatusV4320');
    const label=document.getElementById('attendanceMonthLabelV4320');
    const excel=document.getElementById('exportAttendanceExcelV4320');
    const pdf=document.getElementById('exportAttendancePdfV4320');
    if(body)body.innerHTML=rows.length?rows.map(rowHtml).join(''):'<tr><td colspan="6" class="monthly-attendance-empty">No hay marcas registradas en este mes.</td></tr>';
    if(summary)summary.innerHTML=`
      <article><span>Marcas del mes</span><strong>${stats.marks}</strong></article>
      <article><span>Colaboradores</span><strong>${stats.people}</strong></article>
      <article><span>Jornadas completas</span><strong>${stats.completed}</strong></article>
      <article><span>Horas registradas</span><strong>${esc(formatHours(stats.hours))}</strong></article>`;
    if(label)label.textContent=monthTitle(month);
    if(status){
      if(errorMessage)status.textContent=`No se pudo consultar la nube. Se muestra el registro disponible en este dispositivo. ${errorMessage}`;
      else status.textContent=source==='cloud'?'Datos sincronizados desde Supabase.':'Datos disponibles en este dispositivo.';
    }
    if(excel)excel.disabled=!rows.length;
    if(pdf)pdf.disabled=!rows.length;
  }

  async function loadMonth(month){
    const sequence=++loadSequence;
    const status=document.getElementById('attendanceMonthStatusV4320');
    const body=document.getElementById('attendanceMonthBodyV4320');
    const loadButton=document.getElementById('loadAttendanceMonthV4320');
    if(!validMonth(month)){toast('Seleccione un mes válido.');return;}
    try{sessionStorage.setItem(MONTH_KEY,month);}catch(_){ }
    if(status)status.textContent='Cargando las marcas del mes…';
    if(body)body.innerHTML='<tr><td colspan="6" class="monthly-attendance-empty">Cargando…</td></tr>';
    if(loadButton)loadButton.disabled=true;
    try{
      const result=await fetchRows(month);
      if(sequence!==loadSequence)return;
      updateReport(result.rows,month,result.source);
    }catch(error){
      if(sequence!==loadSequence)return;
      console.error('Reporte mensual de asistencia V4.3.21:',error);
      updateReport(localRows(month),month,'local',error?.message||String(error));
    }finally{
      if(sequence===loadSequence&&loadButton)loadButton.disabled=false;
    }
  }

  function exportTableRows(rows){
    return rows.map(row=>`<tr><td>${esc(formatDate(row.date))}</td><td>${esc(row.name)}</td><td>${esc(row.role)}</td><td>${esc(formatTime(row.clockIn))}</td><td>${esc(formatTime(row.clockOut))}</td><td>${row.clockIn&&row.clockOut?esc(formatHours(hoursNumber(row))):'—'}</td></tr>`).join('');
  }

  function downloadFile(filename,content,type){
    const blob=new Blob(['\ufeff',content],{type});
    const url=URL.createObjectURL(blob);
    const link=document.createElement('a');
    link.href=url;
    link.download=filename;
    document.body.appendChild(link);
    link.click();
    link.remove();
    setTimeout(()=>URL.revokeObjectURL(url),1500);
  }

  function csvCell(value){
    const text=String(value??'').replace(/\r?\n/g,' ');
    return `\"${text.replace(/\"/g,'\"\"')}\"`;
  }

  function exportExcel(){
    if(!currentRows.length)return toast('No hay marcas para exportar.');
    const header=['Fecha','Colaborador','Puesto','Entrada','Salida','Horas'];
    const lines=[header.map(csvCell).join(';')];
    currentRows.forEach(row=>{
      const normalized=normalizeRow(row);
      lines.push([normalized.date,normalized.name,normalized.role,normalized.entry,normalized.exit,normalized.hours].map(csvCell).join(';'));
    });
    lines.push([]);
    lines.push(['Resumen',`Marcas: ${stats.marks}`,`Colaboradores: ${stats.people}`,`Jornadas completas: ${stats.completed}`,`Horas: ${formatHours(stats.hours)}`].map(csvCell).join(';'));
    downloadFile(`asistencia-${currentMonth}.csv`,`\ufeff${lines.join('\r\n')}`,'text/csv;charset=utf-8');
  }

  function exportPdf(){
    if(!currentRows.length)return toast('No hay marcas para exportar.');
    const stats=reportStats(currentRows);
    const popup=window.open('','_blank');
    if(popup)try{popup.opener=null;}catch(_){ }
    if(!popup){toast('El navegador bloqueó la ventana del PDF. Permita ventanas emergentes para esta aplicación.');return;}
    popup.document.open();
    popup.document.write(`<!doctype html><html lang="es"><head><meta charset="UTF-8"><title>Asistencia ${esc(currentMonth)}</title><style>@page{size:A4 landscape;margin:12mm}body{font-family:Arial,sans-serif;color:#2f2736;margin:0}h1{color:#5b28b8;margin:0 0 4px}p{margin:0 0 16px}.summary{display:flex;gap:10px;margin-bottom:16px}.summary span{border:1px solid #ddd;border-radius:8px;padding:8px 10px;font-size:12px}table{border-collapse:collapse;width:100%;font-size:11px}th,td{border:1px solid #cfc8d6;padding:7px;text-align:left}th{background:#eee6f8}@media print{button{display:none}}</style></head><body><h1>Historial mensual de asistencia</h1><p>${esc(monthTitle(currentMonth))}</p><div class="summary"><span>Marcas: <b>${stats.marks}</b></span><span>Colaboradores: <b>${stats.people}</b></span><span>Jornadas completas: <b>${stats.completed}</b></span><span>Horas: <b>${esc(formatHours(stats.hours))}</b></span></div><table><thead><tr><th>Fecha</th><th>Colaborador</th><th>Puesto</th><th>Entrada</th><th>Salida</th><th>Horas</th></tr></thead><tbody>${exportTableRows(currentRows)}</tbody></table><script>window.onload=function(){setTimeout(function(){window.print();},250)}<\/script></body></html>`);
    popup.document.close();
  }

  function bindSection(){
    const section=document.getElementById(SECTION_ID);
    if(!section||section.dataset.bound==='1')return;
    section.dataset.bound='1';
    document.getElementById('loadAttendanceMonthV4320')?.addEventListener('click',()=>{
      const month=document.getElementById('attendanceMonthV4320')?.value||'';
      loadMonth(month);
    });
    document.getElementById('attendanceMonthV4320')?.addEventListener('change',event=>loadMonth(event.target.value));
    document.getElementById('exportAttendanceExcelV4320')?.addEventListener('click',exportExcel);
    document.getElementById('exportAttendancePdfV4320')?.addEventListener('click',exportPdf);
  }

  function decorate(){
    if(!isAdmin()||String(window.activeScreen||'')!=='staff')return;
    const main=window.main||document.getElementById('mainContent');
    if(!main||document.getElementById(SECTION_ID))return;
    injectStyles();
    let month='';
    try{month=sessionStorage.getItem(MONTH_KEY)||'';}catch(_){ }
    if(!validMonth(month))month=costaRicaMonth();
    main.insertAdjacentHTML('beforeend',sectionHtml(month));
    bindSection();
    loadMonth(month);
  }

  function wrapRenderer(name){
    const original=window[name];
    if(typeof original!=='function'||original.__monthlyAttendanceWrappedV4320)return;
    const wrapped=function(){
      const result=original.apply(this,arguments);
      if(result&&typeof result.then==='function')return result.finally(()=>queueMicrotask(decorate));
      queueMicrotask(decorate);
      return result;
    };
    wrapped.__monthlyAttendanceWrappedV4320=true;
    wrapped.__monthlyAttendanceOriginalV4320=original;
    window[name]=wrapped;
  }

  wrapRenderer('renderStaffGlobal');
  wrapRenderer('renderStaff');
  window.addEventListener('seniorcare:user-ready',()=>setTimeout(decorate,150));
  window.addEventListener('focus',()=>{
    if(document.getElementById(SECTION_ID)&&validMonth(currentMonth))loadMonth(currentMonth);
  });
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>setTimeout(decorate,250),{once:true});
  else setTimeout(decorate,250);

  window.SENIORCARE_ATTENDANCE_MONTHLY_REPORT_VERSION='4.3.21';
})();
