// Finanças: Contas a pagar/receber com filtros por período e categoria
// initFinance(state, { fmtBRL })

export function initFinance(state, { fmtBRL }) {
  const p = {
    start: document.getElementById('fpStart'),
    end: document.getElementById('fpEnd'),
    cat: document.getElementById('fpCat'),
    apply: document.getElementById('fpApply'),
    rows: document.getElementById('fpRows'),
    summary: document.getElementById('fpSummary'),
    wrap: document.getElementById('fpTableWrap'),
  };
  const r = {
    start: document.getElementById('frStart'),
    end: document.getElementById('frEnd'),
    cat: document.getElementById('frCat'),
    apply: document.getElementById('frApply'),
    rows: document.getElementById('frRows'),
    summary: document.getElementById('frSummary'),
    wrap: document.getElementById('frTableWrap'),
  };

  const fmtDate = (s) => {
    try {
      const d = new Date(s);
      const dd = String(d.getDate()).padStart(2,'0');
      const mm = String(d.getMonth()+1).padStart(2,'0');
      const yyyy = d.getFullYear();
      return `${dd}-${mm}-${yyyy}`;
    } catch(e) { return s || ''; }
  };

  let abortPay = null, abortRec = null;
  const recState = { items: [], page: 1, perPage: 7 };
  const payState = { items: [], page: 1, perPage: 7 };

  function 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())}`;
  }

  function buildQuery(start, end, cat){
    const q = new URLSearchParams();
    if (start) q.set('start', toISO(start));
    if (end) q.set('end', toISO(end));
    if (cat) q.set('category', cat);
    q.set('per_page', '50');
    return q.toString();
  }

  async function fetchJson(url, { signal }){
    try {
      const res = await apiRequest(url, { headers: { 'Accept': 'application/json' }, signal });
      if (!res.ok) throw new Error(`${res.status}`);
      return await res.json();
    } catch (e) {
      return { data: [] };
    }
  }

  function renderRows(tbody, items, isReceivable){
    if (!Array.isArray(items) || items.length === 0){
      tbody.innerHTML = `<tr><td colspan="5" class="muted">Sem dados</td></tr>`;
      return;
    }
    const rows = items.map(it => {
      const date = fmtDate(isReceivable ? it.receive_at || it.due_at : it.due_at);
      const desc = (isReceivable ? (it.customer_name || it.origin || it.description) : (it.description || it.supplier_name)) || '-';
      const cat = it.category || (isReceivable ? 'vendas' : 'fornecedores');
      const status = it.status || (isReceivable ? 'pendente' : 'aberto');
      const value = fmtBRL(it.amount_cents ? it.amount_cents/100 : (it.amount || 0));
      return `<tr>
        <td>${date}</td>
        <td>${escapeHtml(desc)}</td>
        <td>${escapeHtml(cat)}</td>
        <td>${escapeHtml(status)}</td>
        <td style="text-align:right;">${value}</td>
      </tr>`;
    }).join('');
    tbody.innerHTML = rows;
  }

  function renderPayablesPaged(){
    const total = payState.items.length;
    const maxPage = Math.max(1, Math.ceil(total / payState.perPage));
    if (payState.page > maxPage) payState.page = maxPage;
    const start = (payState.page - 1) * payState.perPage;
    const slice = payState.items.slice(start, start + payState.perPage);
    renderRows(p.rows, slice, false);
    // Condicional: rolagem quando passar do limite
    if (p.wrap) {
      if (total > payState.perPage) {
        p.wrap.style.maxHeight = '300px';
        p.wrap.style.overflowY = 'auto';
      } else {
        p.wrap.style.maxHeight = '';
        p.wrap.style.overflowY = '';
      }
    }
    // Controles de paginação dinâmicos
    let pager = document.getElementById('fpPagination');
    if (!pager) {
      pager = document.createElement('div');
      pager.id = 'fpPagination';
      pager.style.display = 'flex';
      pager.style.alignItems = 'center';
      pager.style.justifyContent = 'flex-end';
      pager.style.gap = '0.5rem';
      pager.style.marginTop = '0.5rem';
      p.wrap?.parentNode?.appendChild(pager);
    }
    if (total > payState.perPage) {
      pager.innerHTML = `
        <button class="btn btn-secondary" id="fpPrev">Anterior</button>
        <span class="muted">Página ${payState.page} de ${maxPage}</span>
        <button class="btn btn-secondary" id="fpNext">Próximo</button>
      `;
      pager.style.display = 'flex';
      pager.querySelector('#fpPrev')?.addEventListener('click', ()=>{ if (payState.page > 1) { payState.page--; renderPayablesPaged(); } });
      pager.querySelector('#fpNext')?.addEventListener('click', ()=>{ if (payState.page < maxPage) { payState.page++; renderPayablesPaged(); } });
    } else {
      pager.style.display = 'none';
    }
  }

  function summarize(items, isReceivable){
    let total = 0, nextDates = [];
    for (const it of (items || [])){
      const v = it.amount_cents ? it.amount_cents/100 : (it.amount || 0);
      total += v;
      const d = new Date(isReceivable ? (it.receive_at || it.due_at) : it.due_at);
      if (!isNaN(d)) nextDates.push(d);
    }
    nextDates.sort((a,b)=>a-b);
    const first3 = nextDates.slice(0,3).map(d => `${String(d.getDate()).padStart(2,'0')}-${String(d.getMonth()+1).padStart(2,'0')}-${d.getFullYear()}`).join(', ');
    return { total, next: first3 };
  }

  function renderReceivablesPaged(){
    const total = recState.items.length;
    const maxPage = Math.max(1, Math.ceil(total / recState.perPage));
    if (recState.page > maxPage) recState.page = maxPage;
    const start = (recState.page - 1) * recState.perPage;
    const slice = recState.items.slice(start, start + recState.perPage);
    renderRows(r.rows, slice, true);
    if (r.wrap) {
      if (total > recState.perPage) {
        r.wrap.style.maxHeight = '300px';
        r.wrap.style.overflowY = 'auto';
      } else {
        r.wrap.style.maxHeight = '';
        r.wrap.style.overflowY = '';
      }
    }
    let pager = document.getElementById('frPagination');
    if (!pager) {
      pager = document.createElement('div');
      pager.id = 'frPagination';
      pager.style.display = 'flex';
      pager.style.alignItems = 'center';
      pager.style.justifyContent = 'flex-end';
      pager.style.gap = '0.5rem';
      pager.style.marginTop = '0.5rem';
      r.wrap?.parentNode?.appendChild(pager);
    }
    if (total > recState.perPage) {
      pager.innerHTML = `
        <button class="btn btn-secondary" id="frPrev">Anterior</button>
        <span class="muted">Página ${recState.page} de ${maxPage}</span>
        <button class="btn btn-secondary" id="frNext">Próximo</button>
      `;
      pager.style.display = 'flex';
      pager.querySelector('#frPrev')?.addEventListener('click', ()=>{ if (recState.page > 1) { recState.page--; renderReceivablesPaged(); } });
      pager.querySelector('#frNext')?.addEventListener('click', ()=>{ if (recState.page < maxPage) { recState.page++; renderReceivablesPaged(); } });
    } else {
      pager.style.display = 'none';
    }
  }

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

  async function loadPayables(){
    if (abortPay) abortPay.abort();
    abortPay = new AbortController();
    p.summary.textContent = 'Carregando…';
    const q = buildQuery(p.start?.value, p.end?.value, p.cat?.value);
    const json = await fetchJson(`/api/finance/payables?${q}`, { signal: abortPay.signal });
    const items = json.data || json.items || [];
    payState.items = items;
    payState.page = 1;
    renderPayablesPaged();
    const { total, next } = summarize(items, false);
    p.summary.textContent = `Pendentes: ${fmtBRL(total)}${next ? ` • Próx. vencimentos: ${next}` : ''}`;
  }

  async function loadReceivables(){
    if (abortRec) abortRec.abort();
    abortRec = new AbortController();
    r.summary.textContent = 'Carregando…';
    const q = buildQuery(r.start?.value, r.end?.value, r.cat?.value);
    const json = await fetchJson(`/api/finance/receivables?${q}`, { signal: abortRec.signal });
    const items = json.data || json.items || [];
    recState.items = items;
    recState.page = 1;
    renderReceivablesPaged();
    const { total, next } = summarize(items, true);
    r.summary.textContent = `Esperados: ${fmtBRL(total)}${next ? ` • Próx. recebimentos: ${next}` : ''}`;
  }

  // Eventos de filtro
  p.apply?.addEventListener('click', loadPayables);
  r.apply?.addEventListener('click', loadReceivables);

  // Atualização em tempo real ao registrar transação rápida na agenda
  document.addEventListener('calendar:quick-transaction', () => {
    loadPayables();
    loadReceivables();
  });

  // Carregamento inicial sincronizado com filtros globais quando existirem
  const s = state?.filters || {};
  if (s.start && p.start) p.start.value = s.start;
  if (s.end && p.end) p.end.value = s.end;
  if (s.start && r.start) r.start.value = s.start;
  if (s.end && r.end) r.end.value = s.end;

  loadPayables();
  loadReceivables();
}