// ── Notification center (real events, persisted, per-user scoped) ──
// Storage: localStorage 'finx_notifs_v1' = newest-first array of
//   { id, t:'info|success|warn', title, msg, view, audience, key, ts, readBy[], hiddenFor[] }
// audience:  '*'  → system-wide (every user sees it, e.g. Cash Balance alert)
//            name → personal activity (only that user sees it)
// Read/clear state is tracked PER USER (readBy / hiddenFor) so one user's
// actions never change what another user sees.
(function(){
const KEY='finx_notifs_v1', MAX=80;
const THRESH_KEY='finx_cash_alert_threshold', DEFAULT_THRESH=50000;

const me    = () => String(window.CURRENT_USER||'').trim() || 'unknown';
const read  = () => { try { const a=JSON.parse(localStorage.getItem(KEY)||'[]'); return Array.isArray(a)?a:[]; } catch(_){ return []; } };
const write = (list) => {
  try { localStorage.setItem(KEY, JSON.stringify(list.slice(0,MAX))); } catch(_){}
  try { window.dispatchEvent(new Event('finx:notifs')); } catch(_){}
};

// Add a notification. `key` makes it idempotent (system alerts fire once).
function notify({ t='info', title='', msg='', view=null, audience='*', key=null }){
  if (!title) return;
  const list = read();
  if (key && list.some(n => n.key===key)) return;
  list.unshift({ id:'n'+Date.now().toString(36)+Math.random().toString(36).slice(2,6),
                 t, title, msg, view, audience, key, ts:Date.now(), readBy:[], hiddenFor:[] });
  write(list);
}
// Personal notification for whoever is acting right now.
const notifyMe = (o) => notify({ ...o, audience: me() });

const visible = () => { const m=me();
  return read().filter(n => (n.audience==='*' || n.audience===m) && !(n.hiddenFor||[]).includes(m));
};
const unreadCount = () => { const m=me(); return visible().filter(n => !(n.readBy||[]).includes(m)).length; };

const mark = (id) => { const m=me();
  write(read().map(n => n.id===id && !(n.readBy||[]).includes(m) ? {...n, readBy:[...(n.readBy||[]), m]} : n));
};
const markAll = () => { const m=me();
  write(read().map(n => (n.audience==='*'||n.audience===m) && !(n.readBy||[]).includes(m) ? {...n, readBy:[...(n.readBy||[]), m]} : n));
};
// "Clear" only hides for the current user — system alerts stay for everyone else.
const clearMine = () => { const m=me();
  write(read().map(n => (n.audience==='*'||n.audience===m) && !(n.hiddenFor||[]).includes(m) ? {...n, hiddenFor:[...(n.hiddenFor||[]), m]} : n));
};

// ── Cash Balance threshold watcher (system-wide) ──
const getThresh = () => { const v=Number(localStorage.getItem(THRESH_KEY)); return isNaN(v)||!localStorage.getItem(THRESH_KEY) ? DEFAULT_THRESH : v; };
const fmt = (n) => Number(n||0).toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2});
function checkCashBalance(){
  let rows=[];
  try { rows = window.buildCashflow ? window.buildCashflow() : (window.CASHFLOW||[]); } catch(_){ rows = window.CASHFLOW||[]; }
  if (!rows.length) return;
  const last = rows[rows.length-1];
  const bal = Number(last.cashBalance)||0, th = getThresh();
  if (bal >= th) return;
  notify({ t:'warn', audience:'*', view:'cashflow',
    key:'cash-low|'+(last.iso||last.date||'')+'|'+th,
    title:'Cash Balance ต่ำกว่าเกณฑ์',
    msg:`ยอดคงเหลือ ${fmt(bal)} THB ณ ${last.date||last.iso} (เกณฑ์ ${fmt(th)})` });
}

// Thai relative label: "เมื่อ 13 นาทีที่แล้ว · 00:17"
function whenTh(ts){
  const d = new Date(ts), hh = String(d.getHours()).padStart(2,'0'), mm = String(d.getMinutes()).padStart(2,'0');
  const min = Math.max(0, Math.floor((Date.now()-ts)/60000));
  const rel = min < 1 ? 'เมื่อสักครู่'
            : min < 60 ? 'เมื่อ '+min+' นาทีที่แล้ว'
            : min < 1440 ? 'เมื่อ '+Math.floor(min/60)+' ชั่วโมงที่แล้ว'
            : 'เมื่อ '+Math.floor(min/1440)+' วันที่แล้ว';
  return rel+' · '+hh+':'+mm;
}

window.finxNotify   = notify;
window.finxNotifyMe = notifyMe;
window.finxNotifs   = { visible, unreadCount, mark, markAll, clear: clearMine, when: whenTh,
                        getThreshold: getThresh,
                        setThreshold: (v)=>{ try{ localStorage.setItem(THRESH_KEY, String(Number(v)||0)); }catch(_){} checkCashBalance(); } };

const rescan = () => checkCashBalance();
window.addEventListener('finx:status-changed', rescan);
window.addEventListener('finx-cashflow-dirty', rescan);
window.addEventListener('storage', rescan);
setTimeout(rescan, 800);
})();
