// Agenda/Calendário: visualização mensal/semanal/diária com marcadores coloridos e criação de eventos
// initCalendar(state, { fmtBRL })

export function initCalendar(state, { fmtBRL }){
  const grid = document.getElementById('calendarGrid');
  const form = document.getElementById('calendarForm');
  const viewBtns = document.querySelectorAll('#calendar [data-view]');
  if (!grid) return;

  let current = new Date();
  let mode = 'month';
  let abort = null;

  viewBtns.forEach(b => b.addEventListener('click', (e) => {
    mode = b.getAttribute('data-view');
    viewBtns.forEach(x => x.setAttribute('aria-selected', x===b ? 'true':'false'));
    render();
  }));

  form?.addEventListener('submit', async (e) => {
    e.preventDefault();
    const rawDate = document.getElementById('calDate').value;
    const toISO = (s)=>{
      if (!s) return '';
      const d = (typeof window !== 'undefined' && typeof window.parseDateBR === 'function') ? window.parseDateBR(s) : new Date(s);
      if (!d || isNaN(d)) return String(s);
      const pad=(n)=>String(n).padStart(2,'0');
      return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}`;
    };
    const date = toISO(rawDate);
    const type = document.getElementById('calType').value;
    const desc = document.getElementById('calDesc').value;
    const value = parseFloat(document.getElementById('calValue').value || '0');
    if (!isFinite(value) || value <= 0) {
      alert('Informe um valor positivo.');
      return;
    }
    try {
      const res = await apiRequest('/api/calendar/quick-transactions', {
        method: 'POST', headers: { 'Content-Type':'application/json', 'Accept':'application/json' },
        body: JSON.stringify({ date, type, description: desc, value }),
      });
      let payload = {};
      try { payload = await res.json(); } catch(_) {}
      // emitir evento para atualização em tempo real de finanças
      document.dispatchEvent(new CustomEvent('calendar:quick-transaction', { detail: { type, date, value, financeId: payload.finance_id, financeType: payload.finance_type } }));
    } catch(_) {}
    render();
    form.reset();
  });

  function range(){
    if (mode === 'day'){
      const start = new Date(current.getFullYear(), current.getMonth(), current.getDate());
      const end = new Date(start); end.setDate(end.getDate()+1);
      return { start, end };
    }
    if (mode === 'week'){
      const d = new Date(current);
      const day = (d.getDay()+6)%7; // segunda=0
      const start = new Date(d); start.setDate(d.getDate() - day);
      const end = new Date(start); end.setDate(start.getDate()+7);
      return { start, end };
    }
    // month
    const start = new Date(current.getFullYear(), current.getMonth(), 1);
    const end = new Date(current.getFullYear(), current.getMonth()+1, 1);
    return { start, end };
  }

  async function fetchEvents(start, end){
    const q = new URLSearchParams({ start: start.toISOString().slice(0,10), end: end.toISOString().slice(0,10) });
    try {
      if (abort) abort.abort();
      abort = new AbortController();
      const res = await apiRequest(`/api/calendar/events?${q.toString()}`, { headers: { 'Accept':'application/json' }, signal: abort.signal });
      if (!res.ok) throw new Error(String(res.status));
      const json = await res.json();
      return json.data || json.items || [];
    } catch(_){
      return [];
    }
  }

  function dot(type, tooltip){
    const color = (type === 'despesa') ? '#ef4444' : '#3b82f6';
    return `<span title="${tooltip}" aria-label="${tooltip}" style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${color};margin-right:4px;"></span>`;
  }

  function fmtBRL2(v){ try { return new Intl.NumberFormat('pt-BR',{style:'currency',currency:'BRL'}).format(v||0); } catch(e){ return 'R$ ' + Number(v||0).toFixed(2).replace('.', ','); } }

  function escapeHtml(s){ return (s||'').toString().replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&#39;'}[m])); }

  function cellTpl(date, items){
    const d = date.getDate();
    const insideMonth = date.getMonth() === current.getMonth();
    const dayItems = (items||[]).filter(ev => sameDate(ev.date, date));
    const chips = dayItems.slice(0,4).map(ev => {
      const categoria = ev.type==='despesa' ? 'fornecedores' : 'vendas';
      const tip = `${ev.type==='despesa'?'Despesa':'Receita'}: ${fmtBRL2(ev.value||0)} — ${ev.description||''}${categoria ? ' — Categoria: '+categoria : ''}`;
      return `${dot(ev.type, tip)}`;
    }).join('');
    const muted = insideMonth ? '' : 'opacity:0.5;';
    return `<div style="border:1px solid var(--border-muted);min-height:80px;padding:4px;${muted}">
      <div style="font-size:12px;color:#6b7280;">${d}</div>
      <div>${chips}</div>
    </div>`;
  }

  function sameDate(a, b){
    const da = new Date(a);
    return da.getFullYear()===b.getFullYear() && da.getMonth()===b.getMonth() && da.getDate()===b.getDate();
  }

  async function render(){
    const { start, end } = range();
    const events = await fetchEvents(start, end);
    if (mode === 'day'){
      const list = events.filter(ev => sameDate(ev.date, current)).map(ev => `<li>${dot(ev.type, '')} ${escapeHtml(ev.description||'')} — ${fmtBRL2(ev.value||0)}</li>`).join('');
      grid.innerHTML = `<ul>${list || '<li class=\"muted\">Sem eventos</li>'}</ul>`;
      return;
    }
    if (mode === 'week'){
      let html = '';
      for (let i=0;i<7;i++){
        const d = new Date(start); d.setDate(start.getDate()+i);
        html += cellTpl(d, events);
      }
      grid.style.display = 'grid';
      grid.style.gridTemplateColumns = 'repeat(7,1fr)';
      grid.innerHTML = html;
      return;
    }
    // month grid
    const first = new Date(current.getFullYear(), current.getMonth(), 1);
    const firstWeekDay = (first.getDay()+6)%7; // 0=Mon
    const daysInMonth = new Date(current.getFullYear(), current.getMonth()+1, 0).getDate();
    const cells = [];
    for (let i=0;i<firstWeekDay;i++){
      const d = new Date(first); d.setDate(first.getDate() - (firstWeekDay - i));
      cells.push(cellTpl(d, events));
    }
    for (let i=1;i<=daysInMonth;i++){
      const d = new Date(current.getFullYear(), current.getMonth(), i);
      cells.push(cellTpl(d, events));
    }
    while (cells.length % 7 !== 0) {
      const d = new Date(current.getFullYear(), current.getMonth()+1, (cells.length % 7));
      cells.push(cellTpl(d, events));
    }
    grid.style.display = 'grid';
    grid.style.gridTemplateColumns = 'repeat(7,1fr)';
    grid.innerHTML = cells.join('');
  }

  render();
}