<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="#1D9E75">
<title>Diário de Saúde</title>
<link rel="manifest" href="/manifest.json">
<script src="https://accounts.google.com/gsi/client" async defer></script>
<style>
:root {
  --green:#1D9E75; --green-light:#E1F5EE; --green-dark:#0F6E56;
  --purple:#7B5EA7; --red:#D85A30; --orange:#EF9F27;
  --bg:#fff; --bg2:#f7f8fa; --bg3:#eef0f3;
  --text:#1a1a1a; --text2:#6b7280; --text3:#9ca3af;
  --border:#e5e7eb; --border2:#d1d5db;
  --radius:10px; --radius-sm:6px;
  --shadow:0 1px 4px rgba(0,0,0,.09);
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent;}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:var(--bg);color:var(--text);font-size:15px;}
button{cursor:pointer;font-family:inherit;}
input,textarea,select{font-family:inherit;}

/* LOGIN */
#login-screen{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;padding:2rem;background:var(--bg2);}
.login-card{width:100%;max-width:360px;background:var(--bg);border:1px solid var(--border);border-radius:16px;padding:2rem;box-shadow:var(--shadow);text-align:center;}
.login-icon{font-size:48px;margin-bottom:1rem;}
.login-card h1{font-size:22px;font-weight:700;margin-bottom:.4rem;}
.login-card p{font-size:14px;color:var(--text2);margin-bottom:2rem;line-height:1.5;}
.recover-msg{font-size:13px;color:#92600A;background:#FFF8EC;border:1px solid #F5D98A;border-radius:var(--radius-sm);padding:10px 12px;margin-bottom:1.2rem;line-height:1.5;text-align:left;}
.g-btn-wrap{display:flex;justify-content:center;}
.login-error{color:var(--red);font-size:13px;margin-top:12px;min-height:18px;}

/* SESSION EXPIRED MODAL */
#session-modal{display:none;position:fixed;inset:0;z-index:1000;background:rgba(0,0,0,.55);align-items:center;justify-content:center;padding:1.5rem;}
#session-modal.visible{display:flex;}
.session-card{background:var(--bg);border-radius:16px;padding:2rem;max-width:340px;width:100%;text-align:center;box-shadow:0 8px 30px rgba(0,0,0,.18);}
.session-card h2{font-size:18px;font-weight:700;margin-bottom:.5rem;}
.session-card p{font-size:14px;color:var(--text2);margin-bottom:1.2rem;line-height:1.5;}
.session-card .warn{font-size:13px;color:#92600A;background:#FFF8EC;border:1px solid #F5D98A;border-radius:var(--radius-sm);padding:8px 10px;margin-bottom:1.2rem;}

/* APP */
#app{display:none;flex-direction:column;min-height:100vh;}
.app-header{position:sticky;top:0;z-index:100;background:var(--bg);border-bottom:1px solid var(--border);padding:10px 16px;display:flex;align-items:center;justify-content:space-between;gap:8px;}
.app-header h1{font-size:16px;font-weight:700;white-space:nowrap;}
.header-right{display:flex;align-items:center;gap:8px;}
.user-avatar{width:30px;height:30px;border-radius:50%;border:1.5px solid var(--border);object-fit:cover;}
.logout-btn{font-size:12px;padding:4px 10px;border:1px solid var(--border);border-radius:99px;background:none;color:var(--text2);}
.month-nav{display:flex;align-items:center;gap:6px;}
.month-nav button{background:none;border:1px solid var(--border);border-radius:var(--radius-sm);padding:4px 10px;font-size:14px;color:var(--text2);}
.month-label{font-size:13px;font-weight:600;min-width:105px;text-align:center;}

/* STATUS BAR */
#status-bar{display:none;align-items:center;justify-content:center;gap:8px;padding:7px 16px;font-size:13px;font-weight:500;}
#status-bar.saving{background:#EEF9F5;color:var(--green);display:flex;}
#status-bar.saved{background:#EEF9F5;color:var(--green-dark);display:flex;}
#status-bar.pending{background:#FFF8EC;color:#92600A;display:flex;}
#status-bar.error{background:#FEF0EC;color:var(--red);display:flex;}
.status-dot{width:7px;height:7px;border-radius:50%;background:currentColor;flex-shrink:0;}
.spinner-sm{width:14px;height:14px;border:2px solid rgba(29,158,117,.3);border-top-color:var(--green);border-radius:50%;animation:spin .7s linear infinite;flex-shrink:0;}

.tabs-bar{display:flex;border-bottom:1px solid var(--border);background:var(--bg);}
.tab-btn{flex:1;padding:10px;font-size:14px;font-weight:500;color:var(--text2);background:none;border:none;border-bottom:2px solid transparent;}
.tab-btn.active{color:var(--green);border-bottom-color:var(--green);}

/* PERSON BAR */
.person-bar{display:flex;gap:8px;padding:10px 16px;background:var(--bg);border-bottom:1px solid var(--border);overflow-x:auto;}
.person-btn{display:flex;align-items:center;gap:7px;padding:7px 14px;border-radius:99px;border:1.5px solid var(--border);background:var(--bg);white-space:nowrap;font-size:14px;font-weight:500;color:var(--text2);}
.person-btn.active{color:#fff;border-color:transparent;}
.avatar{width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;color:#fff;flex-shrink:0;}
.edit-name-wrap{display:flex;align-items:center;gap:5px;}
.edit-name-wrap input{font-size:13px;padding:4px 8px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);width:95px;}
.edit-name-wrap button{font-size:12px;padding:4px 9px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);}

/* CALENDAR */
#view-cal{padding:10px 12px 100px;}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:6px;}
.day-hdr{text-align:center;font-size:11px;color:var(--text2);padding:4px 0;font-weight:600;}
.day-cell{border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px;min-height:54px;cursor:pointer;background:var(--bg);position:relative;transition:background .1s;}
.day-cell:active{background:var(--bg3);}
.day-cell.empty{border:none;background:transparent;cursor:default;}
.day-cell.today{border-width:2px;}
.day-cell.has-data{background:var(--bg2);}
.day-cell.selected{border-width:2px;}
.day-cell.pending-save{box-shadow:inset 0 0 0 2px var(--orange);}
.day-num{font-size:13px;font-weight:600;}
.dot-row{display:flex;gap:3px;margin-top:4px;flex-wrap:wrap;}
.dot{width:6px;height:6px;border-radius:50%;}
.saved-mark{position:absolute;top:3px;right:5px;font-size:9px;font-weight:700;}
.legend{display:flex;gap:12px;padding:4px 0 10px;flex-wrap:wrap;}
.legend-item{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--text2);}

/* DAY PANEL */
.day-panel{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);padding:16px;margin-top:10px;box-shadow:var(--shadow);}
.panel-head{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:14px;}
.panel-title{font-size:16px;font-weight:700;}
.panel-sub{font-size:12px;color:var(--text2);text-transform:capitalize;margin-top:1px;}
.panel-person-badge{font-size:11px;padding:3px 10px;border-radius:99px;color:#fff;font-weight:500;}
.close-btn{background:none;border:none;font-size:22px;color:var(--text2);padding:0 4px;line-height:1;}
.sec-label{font-size:11px;font-weight:600;color:var(--text2);text-transform:uppercase;letter-spacing:.06em;margin:14px 0 8px;}
.sec-label:first-of-type{margin-top:0;}
.item-list{list-style:none;margin-bottom:6px;}
.item-row{display:flex;align-items:center;gap:7px;padding:7px 0;border-bottom:1px solid var(--border);font-size:14px;}
.item-row:last-child{border:none;}
.item-name{flex:1;color:var(--text);}
.item-qty{color:var(--text2);font-size:13px;min-width:55px;text-align:right;}
.action-btn{background:none;border:none;color:var(--text3);font-size:15px;padding:0 3px;line-height:1;}
.action-btn:active{color:var(--green);}
.action-btn.del:active{color:var(--red);}
.empty-msg{font-size:13px;color:var(--text3);padding:4px 0 8px;}
.edit-food-row{display:flex;gap:5px;padding:6px 0;border-bottom:1px solid var(--border);flex-wrap:wrap;}
.edit-food-row input{font-size:13px;padding:6px 8px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);}
.edit-food-row input.efn{flex:2;min-width:80px;}
.edit-food-row input.efq{flex:1;min-width:60px;}
.edit-food-row button{font-size:13px;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);}
.edit-food-row .confirm-btn{border-color:var(--green);color:var(--green);}
.add-row{display:flex;gap:6px;margin-top:6px;flex-wrap:wrap;}
.add-row input{font-size:14px;padding:9px 10px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);}
.add-row input.fn{flex:2;min-width:100px;}
.add-row input.fq{flex:1;min-width:65px;}
.add-row .add-btn{font-size:14px;padding:9px 14px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);white-space:nowrap;}
.symp-add{display:flex;gap:6px;margin-top:6px;flex-wrap:wrap;}
.symp-add input{flex:3;min-width:110px;font-size:14px;padding:9px 10px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);}
.symp-add select{flex:1;min-width:88px;font-size:13px;padding:9px 8px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);}
.symp-add .add-btn{font-size:14px;padding:9px 14px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);white-space:nowrap;}
.symp-badge{font-size:11px;padding:2px 8px;border-radius:99px;font-weight:500;white-space:nowrap;}
.bs{background:#FAECE7;color:#993C1D;}.bi{background:#FAEEDA;color:#854F0B;}.bo{background:#E6F1FB;color:#185FA5;}
.sev-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.s1{background:#9FE1CB;}.s2{background:#EF9F27;}.s3{background:#E24B4A;}
.symp-text{flex:1;color:var(--text);}
.notes-area{width:100%;font-size:14px;padding:10px;border:1px solid var(--border2);border-radius:var(--radius-sm);background:var(--bg2);color:var(--text);resize:vertical;min-height:70px;}
.notes-area:focus{outline:none;border-color:var(--green);}
.save-btn{margin-top:12px;width:100%;font-size:15px;padding:12px;border-radius:var(--radius-sm);font-weight:600;border:none;color:#fff;transition:opacity .15s;}
.save-btn:active{opacity:.85;}
.toast{font-size:13px;text-align:center;margin-top:6px;height:18px;transition:opacity .3s;opacity:0;}

/* ANALYSIS */
#view-ana{padding:12px 16px 100px;display:none;}
.person-ana-tabs{display:flex;gap:6px;margin-bottom:14px;}
.pa-tab{font-size:13px;padding:7px 16px;border-radius:99px;border:1.5px solid var(--border);background:var(--bg);color:var(--text2);font-weight:500;}
.pa-tab.active{color:#fff;border-color:transparent;}
.stats-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin-bottom:14px;}
.stat-card{background:var(--bg2);border-radius:var(--radius);padding:14px;}
.stat-num{font-size:26px;font-weight:700;}
.stat-lbl{font-size:12px;color:var(--text2);margin-top:2px;}
.ana-section{margin-bottom:18px;}
.ana-title{font-size:15px;font-weight:600;margin-bottom:10px;}
.symp-freq{display:flex;flex-direction:column;gap:8px;}
.sf-row{display:flex;align-items:center;gap:8px;font-size:13px;}
.sf-name{flex:1;color:var(--text);}
.sf-bar-wrap{width:80px;height:8px;background:var(--bg3);border-radius:99px;overflow:hidden;}
.sf-bar{height:100%;border-radius:99px;}
.sf-count{font-size:12px;color:var(--text2);min-width:24px;text-align:right;}
.corr-list{display:flex;flex-direction:column;gap:8px;}
.corr-row{background:var(--bg2);border-radius:var(--radius-sm);padding:10px 12px;}
.corr-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:5px;}
.corr-food{font-size:14px;font-weight:500;}
.corr-meta{font-size:12px;color:var(--text2);}
.corr-bar-wrap{height:6px;background:var(--bg3);border-radius:99px;overflow:hidden;}
.corr-bar{height:100%;border-radius:99px;}
.c-high{background:var(--red);}.c-med{background:var(--orange);}.c-low{background:var(--green);}
.ai-btn{width:100%;margin-top:6px;margin-bottom:14px;padding:13px;background:var(--green);color:#fff;border:none;border-radius:var(--radius-sm);font-size:15px;font-weight:600;display:flex;align-items:center;justify-content:center;gap:8px;}
.ai-btn:active{background:var(--green-dark);}
.ai-btn:disabled{background:var(--bg3);color:var(--text2);cursor:default;}
.ai-result{background:var(--bg2);border:1px solid var(--border);border-radius:var(--radius);padding:16px;font-size:14px;line-height:1.75;margin-top:4px;}
.ai-result h1,.ai-result h2,.ai-result h3{font-size:15px;font-weight:600;margin:12px 0 5px;}
.ai-result ul{padding-left:16px;}
.ai-result li{margin-bottom:4px;}
.no-data-msg{text-align:center;padding:3rem 0;color:var(--text2);font-size:14px;}
.disclaimer{font-size:12px;color:var(--text2);margin-top:10px;padding:8px 10px;background:var(--bg2);border-radius:var(--radius-sm);border-left:3px solid var(--orange);}
.spinner{display:inline-block;width:18px;height:18px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:spin .7s linear infinite;}
@keyframes spin{to{transform:rotate(360deg);}}
</style>
</head>
<body>

<!-- LOGIN -->
<div id="login-screen">
  <div class="login-card">
    <div class="login-icon">🌿</div>
    <h1>Diário de Saúde</h1>
    <p>Registo de alimentação e sintomas digestivos.<br>Entra com a tua conta Google para começar.</p>
    <div id="recover-msg" style="display:none" class="recover-msg">
      ⚠️ A tua sessão expirou enquanto tinhas dados por guardar.<br>
      Entra novamente — os dados serão recuperados automaticamente.
    </div>
    <div class="g-btn-wrap">
      <div id="g_id_onload"
           data-client_id="523650929533-kv2r143vdg9paifmoshf043q5csk13eq.apps.googleusercontent.com"
           data-callback="onGoogleLogin"
           data-auto_prompt="false"></div>
      <div class="g_id_signin"
           data-type="standard" data-size="large" data-theme="outline"
           data-text="signin_with" data-locale="pt-PT" data-shape="rectangular"></div>
    </div>
    <div class="login-error" id="login-error"></div>
  </div>
</div>

<!-- SESSION EXPIRED MODAL -->
<div id="session-modal">
  <div class="session-card">
    <div style="font-size:36px;margin-bottom:.75rem">⏱</div>
    <h2>Sessão expirada</h2>
    <p>A tua sessão terminou, mas <strong>os dados não se perderam</strong> — estão guardados neste dispositivo.</p>
    <div class="warn">Entra novamente para sincronizar com o servidor.</div>
    <div class="g-btn-wrap">
      <div class="g_id_signin"
           data-type="standard" data-size="large" data-theme="outline"
           data-text="signin_with" data-locale="pt-PT" data-shape="rectangular"></div>
    </div>
  </div>
</div>

<!-- APP -->
<div id="app">
  <div class="app-header">
    <h1>🌿 Diário de Saúde</h1>
    <div class="header-right">
      <div class="month-nav">
        <button onclick="changeMonth(-1)">‹</button>
        <span class="month-label" id="month-label"></span>
        <button onclick="changeMonth(1)">›</button>
      </div>
      <img class="user-avatar" id="user-avatar" src="" alt="" style="display:none">
      <button class="logout-btn" onclick="doLogout()">Sair</button>
    </div>
  </div>

  <div id="status-bar"></div>

  <div class="tabs-bar">
    <button class="tab-btn active" id="tab-cal" onclick="showTab('cal')">Calendário</button>
    <button class="tab-btn" id="tab-ana" onclick="showTab('ana')">Análise</button>
  </div>

  <div class="person-bar" id="person-bar"></div>

  <div id="view-cal">
    <div class="cal-grid" id="cal-grid">
      <div class="day-hdr">Seg</div><div class="day-hdr">Ter</div><div class="day-hdr">Qua</div>
      <div class="day-hdr">Qui</div><div class="day-hdr">Sex</div><div class="day-hdr">Sáb</div><div class="day-hdr">Dom</div>
    </div>
    <div class="legend">
      <div class="legend-item"><span class="dot" style="background:var(--green)"></span> Refeições</div>
      <div class="legend-item"><span class="dot" style="background:var(--red)"></span> Sintomas</div>
      <div class="legend-item"><span style="font-size:11px;color:var(--orange);font-weight:700">◻</span> Por guardar</div>
    </div>
    <div id="day-panel" style="display:none"></div>
  </div>
  <div id="view-ana"></div>
</div>

<script>
// ================================================================
// CONSTANTS
// ================================================================
const PERSONS=[{id:'p1',defaultColor:'#1D9E75'},{id:'p2',defaultColor:'#7B5EA7'}];
const MONTH_NAMES=['','Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'];
const WK=['segunda','terça','quarta','quinta','sexta','sábado','domingo'];
const BL={stomach:'bs',intestinal:'bi',outro:'bo'};
const BN={stomach:'Estômago',intestinal:'Intestinal',outro:'Outro'};
const SC={'1':'s1','2':'s2','3':'s3'};
const LS_KEY='diario-saude-local';
const AUTOSAVE_MS=30000;

// ================================================================
// STATE
// ================================================================
let S={
  year:new Date().getFullYear(), month:new Date().getMonth()+1,
  activePerson:'p1',
  data:{p1:{},p2:{}},
  names:{p1:{name:'Pessoa 1',color:'#1D9E75'},p2:{name:'Pessoa 2',color:'#7B5EA7'}},
  selectedDay:null, editingName:null, editingFood:null,
  pendingDays:new Set(),
  autosaveTimer:null, statusTimer:null,
  sessionExpired:false,
};

// ================================================================
// LOCAL STORAGE
// ================================================================
function lsSave(){
  try{
    localStorage.setItem(LS_KEY,JSON.stringify({
      data:S.data, names:S.names,
      pending:[...S.pendingDays],
      year:S.year, month:S.month, ts:Date.now()
    }));
  }catch(e){}
}
function lsLoad(){
  try{const r=localStorage.getItem(LS_KEY);return r?JSON.parse(r):null;}catch(e){return null;}
}
function lsClear(){try{localStorage.removeItem(LS_KEY);}catch(e){}}

// ================================================================
// HELPERS
// ================================================================
function firstDow(y,m){let d=new Date(y,m-1,1).getDay();return d===0?6:d-1;}
function daysInMonth(y,m){return new Date(y,m,0).getDate();}
function pColor(pid){return S.names[pid||S.activePerson]?.color||'#1D9E75';}
function pName(pid){return S.names[pid||S.activePerson]?.name||'Pessoa';}
function isToday(d){const t=new Date();return t.getFullYear()===S.year&&t.getMonth()+1===S.month&&t.getDate()===d;}
function getDay(pid,d){
  if(!S.data[pid])S.data[pid]={};
  if(!S.data[pid][d])S.data[pid][d]={foods:[],symptoms:[],notes:''};
  return S.data[pid][d];
}

// ================================================================
// STATUS BAR
// ================================================================
function setStatus(type,text,autohide=0){
  const bar=document.getElementById('status-bar');
  if(!bar)return;
  if(!type){bar.style.display='none';bar.className='';return;}
  bar.className=type;
  bar.style.display='flex';
  bar.style.cssText='display:flex;align-items:center;justify-content:center;gap:8px;padding:7px 16px;font-size:13px;font-weight:500;';
  if(type==='saving'){
    bar.style.background='#EEF9F5';bar.style.color='var(--green)';
    bar.innerHTML=`<span style="width:14px;height:14px;border:2px solid rgba(29,158,117,.3);border-top-color:var(--green);border-radius:50%;animation:spin .7s linear infinite;display:inline-block;flex-shrink:0"></span><span>${text}</span>`;
  }else if(type==='saved'){
    bar.style.background='#EEF9F5';bar.style.color='#0F6E56';
    bar.innerHTML=`<span style="width:7px;height:7px;border-radius:50%;background:currentColor;flex-shrink:0"></span><span>${text}</span>`;
  }else if(type==='pending'){
    bar.style.background='#FFF8EC';bar.style.color='#92600A';
    bar.innerHTML=`<span style="width:7px;height:7px;border-radius:50%;background:currentColor;flex-shrink:0"></span><span>${text}</span>`;
  }else if(type==='error'){
    bar.style.background='#FEF0EC';bar.style.color='var(--red)';
    bar.innerHTML=`<span style="width:7px;height:7px;border-radius:50%;background:currentColor;flex-shrink:0"></span><span>${text}</span>`;
  }
  if(S.statusTimer)clearTimeout(S.statusTimer);
  if(autohide>0)S.statusTimer=setTimeout(()=>setStatus('',''),autohide);
}
function updatePendingStatus(){
  if(S.pendingDays.size>0) setStatus('pending',`${S.pendingDays.size} dia(s) por guardar no servidor`);
  else setStatus('','');
}

// ================================================================
// API — deteta sessão expirada
// ================================================================
async function api(url,method='GET',body=null){
  const opts={method,headers:{'Content-Type':'application/json'},credentials:'include'};
  if(body)opts.body=JSON.stringify(body);
  const r=await fetch(url,opts);
  if(r.status===401){handleSessionExpired();return{error:'session_expired'};}
  return r.json();
}

function handleSessionExpired(){
  if(S.sessionExpired)return;
  S.sessionExpired=true;
  lsSave(); // guarda tudo localmente
  stopAutosave();
  document.getElementById('session-modal').classList.add('visible');
}

// ================================================================
// GOOGLE AUTH
// ================================================================
async function onGoogleLogin(response){
  const err=document.getElementById('login-error');
  if(err)err.textContent='';
  const res=await fetch('/api/google_auth.php',{
    method:'POST',headers:{'Content-Type':'application/json'},
    credentials:'include',body:JSON.stringify({credential:response.credential})
  }).then(r=>r.json()).catch(()=>({error:'Erro de ligação'}));

  if(res.ok){
    S.sessionExpired=false;
    document.getElementById('session-modal').classList.remove('visible');
    const hadPending=S.pendingDays.size>0;
    if(document.getElementById('app').style.display==='none'){
      showApp(res); await loadData();
    }else{
      // Re-login após sessão expirada
      if(hadPending) await syncPendingDays();
      startAutosave();
    }
  }else{
    const errEl=document.getElementById('login-error');
    if(errEl)errEl.textContent=res.error||'Erro ao autenticar';
  }
}

function showApp(user){
  document.getElementById('login-screen').style.display='none';
  document.getElementById('app').style.display='flex';
  if(user?.picture){const av=document.getElementById('user-avatar');av.src=user.picture;av.style.display='block';}
}

async function doLogout(){
  stopAutosave(); lsClear();
  await api('/api/logout.php','POST').catch(()=>{});
  location.reload();
}

// ================================================================
// LOAD DATA
// ================================================================
async function loadData(){
  const local=lsLoad();
  const hasPending=local?.pending?.length>0;

  if(hasPending){
    // Restaura dados locais pendentes primeiro
    S.data=local.data||S.data;
    if(local.names){if(local.names.p1)S.names.p1=local.names.p1;if(local.names.p2)S.names.p2=local.names.p2;}
    S.pendingDays=new Set(local.pending);
    updateMonthLabel();renderPersonBar();renderCal();updatePendingStatus();
    setStatus('saving','A sincronizar dados guardados localmente...');
    await syncPendingDays();
  }

  // Carrega dados frescos do servidor
  const res=await api(`/api/load.php?year=${S.year}&month=${S.month}`).catch(()=>null);
  if(res?.ok){
    // Merge: dados do servidor substituem tudo excepto dias ainda pendentes
    PERSONS.forEach(p=>{
      Object.keys(res.data[p.id]||{}).forEach(d=>{
        if(!S.pendingDays.has(`${p.id}_${d}`)){
          if(!S.data[p.id])S.data[p.id]={};
          S.data[p.id][d]=res.data[p.id][d];
        }
      });
    });
    if(res.names){if(res.names.p1)S.names.p1=res.names.p1;if(res.names.p2)S.names.p2=res.names.p2;}
    if(res.user?.picture){const av=document.getElementById('user-avatar');av.src=res.user.picture;av.style.display='block';}
  }

  lsSave();
  updateMonthLabel();renderPersonBar();renderCal();updatePendingStatus();
  startAutosave();
}

// ================================================================
// MARK DIRTY + SAVE DAY
// ================================================================
function markDirty(pid,d){
  S.pendingDays.add(`${pid}_${d}`);
  lsSave(); updatePendingStatus(); renderCal();
}

async function saveDay(d){
  const pid=S.activePerson;
  const entry=getDay(pid,d);
  entry.notes=document.getElementById(`nt${d}`)?.value||'';
  markDirty(pid,d);
  setStatus('saving','A guardar...');
  const res=await api('/api/save.php','POST',{
    person_id:pid,day:d,month:S.month,year:S.year,
    foods:entry.foods,symptoms:entry.symptoms,notes:entry.notes
  }).catch(()=>({error:'Erro de ligação'}));

  if(res.ok){
    S.pendingDays.delete(`${pid}_${d}`);
    lsSave(); setStatus('saved','Guardado ✓',2500); updatePendingStatus(); renderCal();
    const tk=document.getElementById(`tk${d}`);
    if(tk){tk.textContent='✓ Guardado';tk.style.color=pColor();tk.style.opacity='1';setTimeout(()=>tk.style.opacity='0',2500);}
  }else if(res.error!=='session_expired'){
    setStatus('error','Erro ao guardar — dados mantidos localmente',4000);
    const tk=document.getElementById(`tk${d}`);
    if(tk){tk.textContent='⚠ Guardado localmente';tk.style.color='var(--orange)';tk.style.opacity='1';setTimeout(()=>tk.style.opacity='0',3000);}
  }
}

// ================================================================
// SYNC PENDING
// ================================================================
async function syncPendingDays(){
  if(!S.pendingDays.size)return;
  setStatus('saving',`A sincronizar ${S.pendingDays.size} dia(s)...`);
  const toSync=[...S.pendingDays];
  let synced=0;
  for(const key of toSync){
    const[pid,d]=key.split('_');
    const entry=S.data[pid]?.[d];
    if(!entry){S.pendingDays.delete(key);continue;}
    const res=await api('/api/save.php','POST',{
      person_id:pid,day:parseInt(d),month:S.month,year:S.year,
      foods:entry.foods,symptoms:entry.symptoms,notes:entry.notes
    }).catch(()=>({error:'network'}));
    if(res.ok){S.pendingDays.delete(key);synced++;}
  }
  lsSave(); renderCal();
  if(!S.pendingDays.size) setStatus('saved',`${synced} dia(s) sincronizado(s) ✓`,3000);
  else updatePendingStatus();
}

// ================================================================
// AUTO-SAVE (a cada 30s)
// ================================================================
function startAutosave(){
  stopAutosave();
  S.autosaveTimer=setInterval(async()=>{
    if(S.pendingDays.size>0&&!S.sessionExpired) await syncPendingDays();
  },AUTOSAVE_MS);
}
function stopAutosave(){if(S.autosaveTimer){clearInterval(S.autosaveTimer);S.autosaveTimer=null;}}

// ================================================================
// SAVE NAME
// ================================================================
async function saveName(pid){
  const el=document.getElementById(`ninp-${pid}`);
  const name=el?.value?.trim();
  if(!name)return;
  S.names[pid].name=name; lsSave();
  await api('/api/save_name.php','POST',{person_id:pid,name}).catch(()=>{});
  S.editingName=null; renderPersonBar(); renderCal();
}

// ================================================================
// UI CONTROLS
// ================================================================
function changeMonth(dir){
  S.month+=dir;
  if(S.month>12){S.month=1;S.year++;}
  if(S.month<1){S.month=12;S.year--;}
  S.selectedDay=null;S.editingFood=null;
  document.getElementById('day-panel').style.display='none';
  loadData();
}
function updateMonthLabel(){
  document.getElementById('month-label').textContent=`${MONTH_NAMES[S.month]} ${S.year}`;
}
function showTab(t){
  document.getElementById('view-cal').style.display=t==='cal'?'':'none';
  document.getElementById('view-ana').style.display=t==='ana'?'':'none';
  document.getElementById('tab-cal').className='tab-btn'+(t==='cal'?' active':'');
  document.getElementById('tab-ana').className='tab-btn'+(t==='ana'?' active':'');
  if(t==='ana')renderAnalysis(S.activePerson);
}

// ================================================================
// PERSON BAR
// ================================================================
function renderPersonBar(){
  const bar=document.getElementById('person-bar');
  bar.innerHTML=PERSONS.map(p=>{
    const col=pColor(p.id),nm=pName(p.id),isActive=S.activePerson===p.id,isEditing=S.editingName===p.id;
    const initials=nm.split(' ').map(x=>x[0]).join('').slice(0,2).toUpperCase();
    if(isEditing){
      return `<div class="person-btn${isActive?' active':''}" style="${isActive?`background:${col}`:''}">
        <div class="avatar" style="background:${col}">${initials}</div>
        <div class="edit-name-wrap">
          <input id="ninp-${p.id}" value="${nm}" onkeydown="if(event.key==='Enter')saveName('${p.id}')"/>
          <button onclick="saveName('${p.id}')">OK</button>
        </div></div>`;
    }
    return `<div class="person-btn${isActive?' active':''}" style="${isActive?`background:${col}`:''}" onclick="selectPerson('${p.id}')">
      <div class="avatar" style="background:${col}">${initials}</div>
      <span>${nm}</span>
      <span style="font-size:13px;opacity:.55;margin-left:2px" onclick="event.stopPropagation();S.editingName='${p.id}';renderPersonBar()">✏</span>
    </div>`;
  }).join('');
  if(S.editingName)setTimeout(()=>{const el=document.getElementById(`ninp-${S.editingName}`);if(el){el.focus();el.select();}},50);
}
function selectPerson(pid){
  S.activePerson=pid;S.selectedDay=null;S.editingFood=null;
  document.getElementById('day-panel').style.display='none';
  renderPersonBar();renderCal();
}

// ================================================================
// CALENDAR
// ================================================================
function renderCal(){
  const grid=document.getElementById('cal-grid');
  grid.querySelectorAll('.day-cell').forEach(e=>e.remove());
  const col=pColor(),fd=firstDow(S.year,S.month),dim=daysInMonth(S.year,S.month);
  for(let i=0;i<fd;i++){const b=document.createElement('div');b.className='day-cell empty';grid.appendChild(b);}
  for(let d=1;d<=dim;d++){
    const cell=document.createElement('div');cell.className='day-cell';
    const dd=S.data[S.activePerson]&&S.data[S.activePerson][d];
    const isPending=S.pendingDays.has(`${S.activePerson}_${d}`);
    if(isToday(d)){cell.classList.add('today');cell.style.borderColor=col;}
    if(d===S.selectedDay){cell.classList.add('selected');cell.style.borderColor=col;}
    if(dd&&(dd.foods.length||dd.symptoms.length||dd.notes))cell.classList.add('has-data');
    if(isPending)cell.classList.add('pending-save');
    cell.innerHTML=`<div class="day-num" style="${isToday(d)?`color:${col}`:''}">${d}</div>`;
    if(dd&&(dd.foods.length||dd.symptoms.length||dd.notes)){
      const dots=document.createElement('div');dots.className='dot-row';
      if(dd.foods&&dd.foods.length)dots.innerHTML+=`<span class="dot" style="background:${col}"></span>`;
      if(dd.symptoms&&dd.symptoms.length)dots.innerHTML+=`<span class="dot" style="background:var(--red)"></span>`;
      cell.appendChild(dots);
      const mark=document.createElement('span');mark.className='saved-mark';
      mark.style.color=isPending?'var(--orange)':col;
      mark.textContent=isPending?'…':'✓';
      cell.appendChild(mark);
    }
    cell.onclick=()=>openDay(d);
    grid.appendChild(cell);
  }
}

// ================================================================
// DAY PANEL
// ================================================================
function openDay(d){
  S.selectedDay=d;S.editingFood=null;renderCal();
  const pid=S.activePerson,col=pColor(),entry=getDay(pid,d);
  const panel=document.getElementById('day-panel');
  panel.style.display='block';
  const dow=(firstDow(S.year,S.month)+d-1)%7;
  const hasSaved=S.data[pid]?.[d]&&(S.data[pid][d].foods.length||S.data[pid][d].symptoms.length||S.data[pid][d].notes);
  const isPending=S.pendingDays.has(`${pid}_${d}`);
  panel.innerHTML=`
    <div class="day-panel">
      <div class="panel-head">
        <div>
          <div class="panel-title">${d} de ${MONTH_NAMES[S.month]}</div>
          <div class="panel-sub">${WK[dow]}</div>
        </div>
        <div style="display:flex;align-items:center;gap:8px">
          <span class="panel-person-badge" style="background:${col}">${pName()}</span>
          ${isPending?`<span style="font-size:12px;color:var(--orange)">Por guardar</span>`:hasSaved?`<span style="font-size:12px;color:${col}">A editar</span>`:''}
          <button class="close-btn" onclick="closePanel()">×</button>
        </div>
      </div>
      <div class="sec-label">O que comi</div>
      <ul class="item-list" id="fl${d}"></ul>
      <div class="add-row">
        <input class="fn" id="fn${d}" type="text" placeholder="Alimento..."/>
        <input class="fq" id="fq${d}" type="text" placeholder="Qtd."/>
        <button class="add-btn" onclick="addFood(${d})" style="border-color:${col};color:${col}">+</button>
      </div>
      <div class="sec-label">Sintomas</div>
      <ul class="item-list" id="sl${d}"></ul>
      <div class="symp-add">
        <input id="st${d}" type="text" placeholder="Descrever sintoma..."/>
        <select id="sty${d}"><option value="stomach">Estômago</option><option value="intestinal">Intestinal</option><option value="outro">Outro</option></select>
        <select id="ssv${d}"><option value="1">Leve</option><option value="2">Moderado</option><option value="3">Forte</option></select>
        <button class="add-btn" onclick="addSymp(${d})">+</button>
      </div>
      <div class="sec-label">Notas</div>
      <textarea class="notes-area" id="nt${d}" placeholder="Medicação, observações, humor..." oninput="onNotesChange(${d})">${entry.notes||''}</textarea>
      <button class="save-btn" style="background:${col}" onclick="saveDay(${d})">Guardar dia</button>
      <div class="toast" id="tk${d}"></div>
    </div>`;
  renderFoods(d);renderSymps(d);
  document.getElementById(`fn${d}`).addEventListener('keydown',e=>{if(e.key==='Enter')addFood(d);});
  document.getElementById(`st${d}`).addEventListener('keydown',e=>{if(e.key==='Enter')addSymp(d);});
  panel.scrollIntoView({behavior:'smooth',block:'nearest'});
}

function onNotesChange(d){
  getDay(S.activePerson,d).notes=document.getElementById(`nt${d}`)?.value||'';
  markDirty(S.activePerson,d);
}

function renderFoods(d){
  const l=document.getElementById(`fl${d}`);if(!l)return;
  const foods=getDay(S.activePerson,d).foods;
  if(!foods.length){l.innerHTML='<li class="empty-msg">Nenhum alimento.</li>';return;}
  l.innerHTML=foods.map((x,i)=>{
    if(S.editingFood?.day===d&&S.editingFood?.index===i){
      return `<li class="edit-food-row">
        <input class="efn" id="efn${d}_${i}" value="${x.name.replace(/"/g,'&quot;')}"/>
        <input class="efq" id="efq${d}_${i}" value="${(x.qty||'').replace(/"/g,'&quot;')}"/>
        <button class="confirm-btn" onclick="confirmEditFood(${d},${i})">✓</button>
        <button onclick="cancelEditFood(${d})">✕</button>
      </li>`;
    }
    return `<li class="item-row">
      <span class="item-name">${x.name}</span>
      <span class="item-qty">${x.qty||'—'}</span>
      <button class="action-btn" onclick="startEditFood(${d},${i})" title="Editar">✏</button>
      <button class="action-btn del" onclick="delFood(${d},${i})" title="Remover">×</button>
    </li>`;
  }).join('');
  if(S.editingFood?.day===d)setTimeout(()=>{const el=document.getElementById(`efn${d}_${S.editingFood.index}`);if(el){el.focus();el.select();}},30);
}
function renderSymps(d){
  const l=document.getElementById(`sl${d}`);if(!l)return;
  const s=getDay(S.activePerson,d).symptoms;
  l.innerHTML=s.length?s.map((x,i)=>`<li class="item-row">
    <span class="sev-dot ${SC[x.severity||'1']}"></span>
    <span class="symp-badge ${BL[x.type]||'bo'}">${BN[x.type]||x.type}</span>
    <span class="symp-text">${x.text}</span>
    <button class="action-btn del" onclick="delSymp(${d},${i})">×</button>
  </li>`).join(''):'<li class="empty-msg">Nenhum sintoma.</li>';
}
function addFood(d){
  const n=document.getElementById(`fn${d}`),q=document.getElementById(`fq${d}`);
  if(!n?.value.trim())return;
  getDay(S.activePerson,d).foods.push({name:n.value.trim(),qty:q.value.trim()});
  n.value='';q.value='';markDirty(S.activePerson,d);renderFoods(d);
}
function startEditFood(d,i){S.editingFood={day:d,index:i};renderFoods(d);}
function cancelEditFood(d){S.editingFood=null;renderFoods(d);}
function confirmEditFood(d,i){
  const n=document.getElementById(`efn${d}_${i}`),q=document.getElementById(`efq${d}_${i}`);
  if(!n?.value.trim())return;
  getDay(S.activePerson,d).foods[i]={name:n.value.trim(),qty:q.value.trim()};
  S.editingFood=null;markDirty(S.activePerson,d);renderFoods(d);
}
function delFood(d,i){getDay(S.activePerson,d).foods.splice(i,1);S.editingFood=null;markDirty(S.activePerson,d);renderFoods(d);}
function addSymp(d){
  const t=document.getElementById(`st${d}`),ty=document.getElementById(`sty${d}`),sv=document.getElementById(`ssv${d}`);
  if(!t?.value.trim())return;
  getDay(S.activePerson,d).symptoms.push({text:t.value.trim(),type:ty.value,severity:sv.value});
  t.value='';markDirty(S.activePerson,d);renderSymps(d);
}
function delSymp(d,i){getDay(S.activePerson,d).symptoms.splice(i,1);markDirty(S.activePerson,d);renderSymps(d);}
function closePanel(){S.selectedDay=null;S.editingFood=null;document.getElementById('day-panel').style.display='none';renderCal();}

// ================================================================
// ANALYSIS
// ================================================================
function renderAnalysis(pid){
  const el=document.getElementById('view-ana'),col=pColor(pid);
  const pdata=S.data[pid]||{};
  const dWF=Object.keys(pdata).map(Number).filter(d=>pdata[d]&&pdata[d].foods.length>0);
  const dWS=Object.keys(pdata).map(Number).filter(d=>pdata[d]&&pdata[d].symptoms.length>0);
  const totS=dWS.reduce((a,d)=>a+pdata[d].symptoms.length,0);
  const both=dWF.filter(d=>pdata[d]&&pdata[d].symptoms.length>0);
  const pct=dWF.length?Math.round(both.length/dWF.length*100):0;
  const ptabs=PERSONS.map(p=>`<button class="pa-tab${p.id===pid?' active':''}" style="${p.id===pid?`background:${pColor(p.id)};border-color:${pColor(p.id)}`:''}" onclick="renderAnalysis('${p.id}')">${pName(p.id)}</button>`).join('');
  const sympMap={};
  dWS.forEach(d=>pdata[d].symptoms.forEach(s=>{
    const k=s.text.toLowerCase().trim();
    if(!sympMap[k])sympMap[k]={text:s.text,count:0,type:s.type};
    sympMap[k].count++;
  }));
  const sympRows=Object.values(sympMap).sort((a,b)=>b.count-a.count).slice(0,6);
  const maxSC=sympRows[0]?.count||1;
  const foodMap={};
  dWF.forEach(d=>{const hs=pdata[d].symptoms.length>0;
    pdata[d].foods.forEach(f=>{
      const k=f.name.toLowerCase().trim();
      if(!foodMap[k])foodMap[k]={name:f.name,days:0,sympDays:0};
      foodMap[k].days++;if(hs)foodMap[k].sympDays++;
    });
  });
  const foodRows=Object.values(foodMap).sort((a,b)=>b.sympDays/b.days-a.sympDays/a.days);
  el.innerHTML=`
    <div class="person-ana-tabs">${ptabs}</div>
    ${(!dWF.length&&!dWS.length)?`<div class="no-data-msg">Sem dados para ${pName(pid)} em ${MONTH_NAMES[S.month]}.</div>`:`
    <div class="stats-grid">
      <div class="stat-card"><div class="stat-num" style="color:${col}">${dWF.length}</div><div class="stat-lbl">Dias com refeições</div></div>
      <div class="stat-card"><div class="stat-num" style="color:var(--red)">${dWS.length}</div><div class="stat-lbl">Dias com sintomas</div></div>
      <div class="stat-card"><div class="stat-num">${totS}</div><div class="stat-lbl">Total de sintomas</div></div>
      <div class="stat-card"><div class="stat-num">${pct}%</div><div class="stat-lbl">Refeições com sintomas</div></div>
    </div>
    ${sympRows.length?`<div class="ana-section"><div class="ana-title">Sintomas mais frequentes</div>
      <div class="symp-freq">${sympRows.map(s=>`<div class="sf-row">
        <span class="symp-badge ${BL[s.type]||'bo'}" style="flex-shrink:0">${BN[s.type]||s.type}</span>
        <span class="sf-name">${s.text}</span>
        <div class="sf-bar-wrap"><div class="sf-bar" style="width:${Math.round(s.count/maxSC*100)}%;background:${col}"></div></div>
        <span class="sf-count">${s.count}×</span>
      </div>`).join('')}</div></div>`:''}
    ${foodRows.length?`<div class="ana-section"><div class="ana-title">Alimentos vs. sintomas</div>
      <div class="corr-list">${foodRows.map(f=>{
        const p2=f.days>0?Math.round(f.sympDays/f.days*100):0;
        const cls=p2>=67?'c-high':p2>=34?'c-med':'c-low';
        const lbl=p2>=67?'Alta':p2>=34?'Média':'Baixa';
        return `<div class="corr-row">
          <div class="corr-top"><span class="corr-food">${f.name}</span><span class="corr-meta">${p2}% (${lbl}) · ${f.days} dias</span></div>
          <div class="corr-bar-wrap"><div class="corr-bar ${cls}" style="width:${p2}%"></div></div>
        </div>`;
      }).join('')}</div></div>`:''}
    <button class="ai-btn" id="ai-btn" onclick="runAI('${pid}')"><span>✦</span> Análise detalhada com IA</button>
    <div id="ai-output"></div>
    <div class="disclaimer">⚠ Estes dados são informativos. Partilha com o teu médico ou nutricionista antes de fazer alterações alimentares.</div>`}`;
}

async function runAI(pid){
  const btn=document.getElementById('ai-btn'),out=document.getElementById('ai-output');
  if(!btn||!out)return;
  btn.disabled=true;btn.innerHTML='<span class="spinner"></span> A analisar...';out.innerHTML='';
  const res=await api('/api/analyze.php','POST',{person_id:pid,month:S.month,year:S.year}).catch(()=>({error:'Erro de ligação.'}));
  btn.disabled=false;btn.innerHTML='<span>✦</span> Análise detalhada com IA';
  if(res.ok){
    let html=res.analysis
      .replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>')
      .replace(/^### (.+)$/gm,'<h3>$1</h3>').replace(/^## (.+)$/gm,'<h2>$1</h2>').replace(/^# (.+)$/gm,'<h1>$1</h1>')
      .replace(/^- (.+)$/gm,'<li>$1</li>').replace(/(<li>[\s\S]*?<\/li>)/g,'<ul>$1</ul>')
      .replace(/\n\n+/g,'<br><br>');
    out.innerHTML=`<div class="ai-result">${html}</div>`;
  }else{
    out.innerHTML=`<div style="color:var(--red);font-size:14px;padding:8px 0">${res.error||'Erro desconhecido.'}</div>`;
  }
}

// ================================================================
// PWA + INIT
// ================================================================
if('serviceWorker' in navigator)navigator.serviceWorker.register('/sw.js').catch(()=>{});

window.addEventListener('beforeunload',()=>{if(S.pendingDays.size>0)lsSave();});

(async function init(){
  const local=lsLoad();
  if(local?.pending?.length>0){
    document.getElementById('recover-msg').style.display='block';
  }
  const res=await api('/api/load.php').catch(()=>null);
  if(res?.ok){
    showApp(res.user);
    if(local?.pending?.length>0){
      // Restaura local e sincroniza
      S.data=local.data||{p1:{},p2:{}};
      S.names=local.names||S.names;
      S.pendingDays=new Set(local.pending);
      updateMonthLabel();renderPersonBar();renderCal();
      await syncPendingDays();
    }
    // Carrega dados frescos
    S.data=res.data;
    if(res.names){if(res.names.p1)S.names.p1=res.names.p1;if(res.names.p2)S.names.p2=res.names.p2;}
    if(res.user?.picture){const av=document.getElementById('user-avatar');av.src=res.user.picture;av.style.display='block';}
    lsSave();updateMonthLabel();renderPersonBar();renderCal();updatePendingStatus();
    startAutosave();
  }
})();
</script>
</body>
</html>
