// daygig-compliance.js — Compliance: deadlines, mileage, checklist, packets, exports

// ── Compliance ────────────────────────────────────────────────────────────

  async function complianceLoadSummary() {
    try {
      const res = await fetch('/api/compliance/summary');
      const data = await res.json();
      complianceSummaryCache = data;
      const deadlineCount = Object.values(data.deadline_statuses || {}).reduce((a,b) => a + Number(b || 0), 0);
      const checklistCount = Object.values(data.checklist_statuses || {}).reduce((a,b) => a + Number(b || 0), 0);
      const set = (id, value) => { const el = document.getElementById(id); if (el) el.textContent = value; };
      set('comp-stat-deadlines', deadlineCount);
      set('comp-stat-miles', data.mileage_total_miles || 0);
      set('comp-stat-deduction', money(data.mileage_deductible || 0));
      set('comp-stat-checklist', checklistCount);

      const deadlineTypeSelect = document.getElementById('comp-deadline-type');
      if (deadlineTypeSelect && !deadlineTypeSelect.dataset.loaded) {
        deadlineTypeSelect.innerHTML = (data.deadline_types_available || [])
          .map(t => `<option value="${t.deadline_type}">${t.label}</option>`).join('');
        deadlineTypeSelect.dataset.loaded = '1';
      }
      const mileagePurposeSelect = document.getElementById('comp-mileage-purpose');
      if (mileagePurposeSelect && !mileagePurposeSelect.dataset.loaded) {
        mileagePurposeSelect.innerHTML = (data.mileage_purposes || [])
          .map(p => `<option value="${p}">${cap(p.replace(/_/g,' '))}</option>`).join('');
        mileagePurposeSelect.dataset.loaded = '1';
      }
      const checklistAreaSelect = document.getElementById('comp-checklist-area');
      if (checklistAreaSelect && !checklistAreaSelect.dataset.loaded) {
        checklistAreaSelect.innerHTML = (data.checklist_areas || [])
          .map(a => `<option value="${a}">${cap(a.replace(/_/g,' '))}</option>`).join('');
        checklistAreaSelect.dataset.loaded = '1';
      }
    } catch (e) {
      console.warn('Compliance summary failed:', e);
    }
  }

  function complianceTab(name) {
    ['deadlines','mileage','checklist','packets','exports'].forEach(t => {
      const el = document.getElementById('comp-' + t);
      if (el) el.style.display = t === name ? 'block' : 'none';
    });
    document.querySelectorAll('.comp-tab').forEach(btn => {
      const active = btn.dataset.comp === name;
      btn.style.color        = active ? 'var(--accent)'           : 'var(--text-soft)';
      btn.style.borderBottom = active ? '2px solid var(--accent)' : '2px solid transparent';
    });
    complianceLoadSummary();
    if (name === 'deadlines') complianceLoadDeadlines();
    if (name === 'mileage')   complianceLoadMileage();
    if (name === 'checklist') complianceLoadChecklist();
    if (name === 'packets')   complianceLoadPackets();
    if (name === 'exports')   { complianceLoadPackets().then(complianceRenderExports); }
  }

  async function complianceLoadDeadlines() {
    const body = document.getElementById('comp-deadlines-body');
    const sub = document.getElementById('comp-deadlines-sub');
    if (!body) return;
    body.innerHTML = '<tr><td colspan="5" style="padding:32px;text-align:center;color:var(--text-dim);">Loading…</td></tr>';
    try {
      const res = await fetch('/api/compliance/deadlines');
      const data = await res.json();
      const rows = data.deadlines || [];
      if (sub) sub.textContent = `${data.total || rows.length} tracked deadline${(data.total || rows.length) === 1 ? '' : 's'}`;
      if (!rows.length) {
        body.innerHTML = '<tr><td colspan="5" style="padding:32px;text-align:center;color:var(--text-dim);">No compliance deadlines yet.</td></tr>';
        return;
      }
      body.innerHTML = rows.map(r => `
        <tr style="border-bottom:1px solid var(--border);">
          <td style="padding:8px 10px;font-family:var(--mono);white-space:nowrap;">${r.due_date || '—'}</td>
          <td style="padding:8px 10px;"><strong>${r.title}</strong><br><span style="font-size:11px;color:var(--text-dim);">${r.jurisdiction || ''}</span></td>
          <td style="padding:8px 10px;">${r.deadline_type_label || r.deadline_type}</td>
          <td style="padding:8px 10px;font-family:var(--mono);font-size:11px;color:var(--accent);">${(r.status || '').replace(/_/g,' ')}</td>
          <td style="padding:8px 10px;text-align:right;font-family:var(--mono);">${money(r.balance_due || 0)}</td>
        </tr>`).join('');
    } catch(e) {
      body.innerHTML = `<tr><td colspan="5" style="padding:32px;text-align:center;color:var(--err);">Error: ${e.message}</td></tr>`;
    }
  }

  async function complianceCreateDeadline() {
    const msg = document.getElementById('comp-deadline-msg');
    const payload = {
      title: document.getElementById('comp-deadline-title').value.trim(),
      deadline_type: document.getElementById('comp-deadline-type').value || 'other',
      due_date: document.getElementById('comp-deadline-date').value,
      jurisdiction: document.getElementById('comp-deadline-jurisdiction').value.trim(),
      frequency: document.getElementById('comp-deadline-frequency').value || 'once',
      amount_due: document.getElementById('comp-deadline-amount').value || 0,
      notes: document.getElementById('comp-deadline-notes').value.trim(),
    };
    if (!payload.title || !payload.due_date) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent='Title and due date are required.'; }
      return;
    }
    try {
      const res = await fetch('/api/compliance/deadlines', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) });
      const data = await res.json();
      if (data.id) {
        if (msg) { msg.style.display='inline'; msg.style.color='var(--accent)'; msg.textContent='✓ Saved'; }
        ['comp-deadline-title','comp-deadline-date','comp-deadline-jurisdiction','comp-deadline-amount','comp-deadline-notes'].forEach(id => document.getElementById(id).value = '');
        complianceLoadDeadlines(); complianceLoadSummary();
      } else throw new Error(data.error || 'Save failed');
    } catch(e) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent=e.message; }
    }
  }

  async function complianceLoadMileage() {
    const body = document.getElementById('comp-mileage-body');
    const sub = document.getElementById('comp-mileage-sub');
    if (!body) return;
    body.innerHTML = '<tr><td colspan="5" style="padding:32px;text-align:center;color:var(--text-dim);">Loading…</td></tr>';
    try {
      const res = await fetch('/api/compliance/mileage');
      const data = await res.json();
      const rows = data.mileage_logs || [];
      if (sub) sub.textContent = `${data.total || rows.length} trips · ${data.visible_total_miles || 0} miles · ${money(data.visible_total_deductible || 0)}`;
      if (!rows.length) {
        body.innerHTML = '<tr><td colspan="5" style="padding:32px;text-align:center;color:var(--text-dim);">No mileage logged yet.</td></tr>';
        return;
      }
      body.innerHTML = rows.map(r => `
        <tr style="border-bottom:1px solid var(--border);">
          <td style="padding:8px 10px;font-family:var(--mono);white-space:nowrap;">${r.trip_date || '—'}</td>
          <td style="padding:8px 10px;">${(r.purpose || '').replace(/_/g,' ')}</td>
          <td style="padding:8px 10px;">${r.start_location || '—'} → ${r.end_location || '—'}<br><span style="font-size:11px;color:var(--text-dim);">${r.business_purpose || ''}</span></td>
          <td style="padding:8px 10px;text-align:right;font-family:var(--mono);">${r.miles || 0}</td>
          <td style="padding:8px 10px;text-align:right;font-family:var(--mono);">${money(r.total_deductible || 0)}</td>
        </tr>`).join('');
    } catch(e) {
      body.innerHTML = `<tr><td colspan="5" style="padding:32px;text-align:center;color:var(--err);">Error: ${e.message}</td></tr>`;
    }
  }

  async function complianceCreateMileage() {
    const msg = document.getElementById('comp-mileage-msg');
    const rate = parseFloat(document.getElementById('comp-mileage-rate').value || '0');
    const tolls = parseFloat(document.getElementById('comp-mileage-tolls').value || '0');
    const payload = {
      trip_date: document.getElementById('comp-mileage-date').value || todayIso(),
      purpose: document.getElementById('comp-mileage-purpose').value || 'business',
      start_location: document.getElementById('comp-mileage-start').value.trim(),
      end_location: document.getElementById('comp-mileage-end').value.trim(),
      business_purpose: document.getElementById('comp-mileage-business-purpose').value.trim(),
      miles: parseFloat(document.getElementById('comp-mileage-miles').value || '0'),
      rate_cents: Math.round(rate * 100),
      parking_tolls_cents: Math.round(tolls * 100),
    };
    if (!payload.trip_date || payload.miles <= 0) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent='Trip date and miles are required.'; }
      return;
    }
    try {
      const res = await fetch('/api/compliance/mileage', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) });
      const data = await res.json();
      if (data.id) {
        if (msg) { msg.style.display='inline'; msg.style.color='var(--accent)'; msg.textContent='✓ Saved'; }
        ['comp-mileage-miles','comp-mileage-start','comp-mileage-end','comp-mileage-business-purpose','comp-mileage-tolls'].forEach(id => document.getElementById(id).value = '');
        complianceLoadMileage(); complianceLoadSummary();
      } else throw new Error(data.error || 'Save failed');
    } catch(e) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent=e.message; }
    }
  }

  async function complianceLoadChecklist() {
    const body = document.getElementById('comp-checklist-body');
    const sub = document.getElementById('comp-checklist-sub');
    if (!body) return;
    body.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-dim);">Loading…</div>';
    try {
      const res = await fetch('/api/compliance/checklist');
      const data = await res.json();
      const rows = data.items || [];
      if (sub) sub.textContent = `${rows.length} checklist item${rows.length === 1 ? '' : 's'}`;
      if (!rows.length) {
        body.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-dim);">No tax checklist items yet.</div>';
        return;
      }
      body.innerHTML = rows.map(r => `
        <div style="border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;justify-content:space-between;gap:12px;">
          <div><strong>${r.title}</strong><div style="font-size:12px;color:var(--text-soft);">${r.tax_year} · ${(r.area || '').replace(/_/g,' ')}</div></div>
          <div style="font-family:var(--mono);font-size:11px;color:var(--accent);">${(r.status || '').replace(/_/g,' ')}</div>
        </div>`).join('');
    } catch(e) {
      body.innerHTML = `<div style="padding:24px;text-align:center;color:var(--err);">Error: ${e.message}</div>`;
    }
  }

  async function complianceCreateChecklistItem() {
    const msg = document.getElementById('comp-checklist-msg');
    const payload = {
      tax_year: parseInt(document.getElementById('comp-checklist-year').value || new Date().getFullYear(), 10),
      area: document.getElementById('comp-checklist-area').value || 'other',
      title: document.getElementById('comp-checklist-title').value.trim(),
      status: 'needed',
    };
    if (!payload.title) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent='Title is required.'; }
      return;
    }
    try {
      const res = await fetch('/api/compliance/checklist', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(payload) });
      const data = await res.json();
      if (data.id) {
        if (msg) { msg.style.display='inline'; msg.style.color='var(--accent)'; msg.textContent='✓ Saved'; }
        document.getElementById('comp-checklist-title').value = '';
        complianceLoadChecklist(); complianceLoadSummary();
      } else throw new Error(data.error || 'Save failed');
    } catch(e) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent=e.message; }
    }
  }

  async function complianceLoadPackets() {
    const body = document.getElementById('comp-packets-body');
    const sub = document.getElementById('comp-packets-sub');
    if (body) body.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-dim);">Loading…</div>';
    try {
      const res = await fetch('/api/compliance/packets');
      const data = await res.json();
      compliancePacketsCache = data.packets || [];
      if (sub) sub.textContent = `${compliancePacketsCache.length} packet${compliancePacketsCache.length === 1 ? '' : 's'}`;
      if (body) {
        if (!compliancePacketsCache.length) {
          body.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-dim);">No accountant packets yet.</div>';
        } else {
          body.innerHTML = compliancePacketsCache.map(p => `
            <div style="border:1px solid var(--border);border-radius:8px;padding:14px 16px;">
              <div style="display:flex;justify-content:space-between;gap:12px;">
                <div><strong>${p.name}</strong><div style="font-size:12px;color:var(--text-soft);">${p.tax_year} · ${(p.status || '').replace(/_/g,' ')}</div></div>
                <button class="btn btn-ghost btn-sm" onclick="complianceLoadPacketDetail(${p.id})">View Exports</button>
              </div>
              <div id="comp-packet-detail-${p.id}" style="display:none;margin-top:12px;"></div>
            </div>`).join('');
        }
      }
      return compliancePacketsCache;
    } catch(e) {
      if (body) body.innerHTML = `<div style="padding:24px;text-align:center;color:var(--err);">Error: ${e.message}</div>`;
      return [];
    }
  }

  const _exportMeta = {
    business_profile:  { icon: dgIcon('building', 20), label: 'Business Profile',      desc: 'Entity name, EIN, address, business type, tax basis, fiscal year.' },
    profit_loss:       { icon: dgIcon('report', 20), label: 'Profit & Loss',          desc: 'Revenue, COGS, gross margin, operating expenses, and net income for the tax year.' },
    balance_sheet:     { icon: dgIcon('scales', 20), label: 'Balance Sheet',          desc: 'Assets, liabilities, and owner equity as of year-end.' },
    general_ledger:    { icon: dgIcon('ledger', 20), label: 'General Ledger',         desc: 'Full double-entry transaction history with account codes and posting dates.' },
    expense_detail:    { icon: dgIcon('expense', 20), label: 'Expense Detail',         desc: 'All expenses itemized by category with dates, vendors, and amounts.' },
    mileage_log:       { icon: dgIcon('car', 20), label: 'Mileage Log',            desc: 'IRS-compliant mileage log with dates, destinations, business purpose, and deduction totals.' },
    sales_tax_summary: { icon: dgIcon('receipt', 20), label: 'Sales Tax Summary',      desc: 'Taxable sales, tax collected, and amounts remitted by jurisdiction.' },
    owner_equity:      { icon: dgIcon('briefcase', 20), label: 'Owner Equity',           desc: 'Owner contributions and draws for the period.' },
    inventory_value:   { icon: dgIcon('box', 20), label: 'Inventory Value',        desc: 'On-hand inventory valued at cost — raw materials and finished goods.' },
    cogs_detail:       { icon: dgIcon('tag', 20), label: 'COGS Detail',            desc: 'Cost of goods sold broken down by product and packaging components.' },
    receipts_archive:  { icon: dgIcon('archive', 20), label: 'Receipts Archive',       desc: 'All scanned and parsed receipts linked to expense transactions.' },
    '1099_vendor_list':{ icon: dgIcon('clipboard', 20), label: '1099 Vendor List',       desc: 'Vendors paid $600+ via non-card methods who may require a 1099-NEC.' },
    funding_summary:   { icon: dgIcon('projects', 20), label: 'Funding & Campaigns',    desc: 'Crowdfunding and campaign income summary for the tax year.' },
  };

  function _exportStatusStyle(status) {
    if (status === 'complete') return 'color:var(--accent);';
    if (status === 'in_progress') return 'color:var(--warn);';
    if (status === 'not_started') return 'color:var(--text-dim);';
    return 'color:var(--text-soft);';
  }

  async function complianceMarkExport(exportId, status, packetId) {
    try {
      const res = await fetch(`/api/compliance/exports/${exportId}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ status }),
      });
      const data = await res.json();
      if (data.id) {
        complianceLoadPacketDetail(packetId, true);
        complianceLoadPackets();
      } else {
        flashMsg('comp-packet-msg', data.error || 'Update failed', true);
      }
    } catch(e) {
      flashMsg('comp-packet-msg', e.message, true);
    }
  }

  async function complianceLoadPacketDetail(id, forceOpen = false) {
    const target = document.getElementById('comp-packet-detail-' + id);
    if (!target) return;
    if (!forceOpen && target.style.display !== 'none') { target.style.display = 'none'; return; }
    target.style.display = 'block';
    target.innerHTML = '<div style="color:var(--text-dim);font-size:12px;padding:8px 0;">Loading…</div>';
    try {
      const res = await fetch('/api/compliance/packets/' + id);
      const p = await res.json();
      const exports = p.exports || [];
      const total = exports.length;
      const done = exports.filter(e => e.status === 'complete').length;
      const pct = total ? Math.round((done / total) * 100) : 0;

      const progressBar = `
        <div style="margin:10px 0 14px;">
          <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;">
            <span style="font-family:var(--mono);font-size:11px;color:var(--text-soft);">${done} of ${total} complete</span>
            <span style="font-family:var(--mono);font-size:11px;color:var(--accent);">${pct}%</span>
          </div>
          <div style="height:4px;background:var(--surface2);border-radius:2px;">
            <div style="height:4px;width:${pct}%;background:var(--accent);border-radius:2px;transition:width .3s;"></div>
          </div>
        </div>`;

      const rows = exports.map(e => {
        const meta = _exportMeta[e.export_type] || { icon: dgIcon('file', 20), label: e.title, desc: '' };
        const isDone = e.status === 'complete';
        const nextStatus = isDone ? 'not_started' : 'complete';
        const nextLabel = isDone ? 'Mark Pending' : 'Mark Complete';
        const nextStyle = isDone ? 'color:var(--text-soft);border-color:var(--border);' : 'color:var(--accent);border-color:var(--accent-ring);';
        return `
          <div style="display:grid;grid-template-columns:1fr auto;gap:12px;align-items:start;border-top:1px solid var(--border);padding:10px 0;">
            <div>
              <div style="font-size:13px;font-weight:600;color:var(--text);">${meta.icon} ${meta.label}</div>
              <div style="font-size:11px;color:var(--text-soft);margin-top:2px;line-height:1.5;">${meta.desc}</div>
              <div style="font-family:var(--mono);font-size:10px;margin-top:4px;${_exportStatusStyle(e.status)}">${(e.status||'not_started').replace(/_/g,' ')}</div>
            </div>
            <div style="display:flex;flex-direction:column;gap:6px;align-items:flex-end;flex-shrink:0;">
              <button class="btn btn-ghost btn-sm" style="font-size:11px;${nextStyle}"
                onclick="complianceMarkExport(${e.id}, '${nextStatus}', ${id})">${nextLabel}</button>
            </div>
          </div>`;
      }).join('');

      target.innerHTML = progressBar + rows;
    } catch(e) {
      target.innerHTML = `<div style="color:var(--err);font-size:12px;">Error: ${e.message}</div>`;
    }
  }

  async function complianceCreatePacket() {
    const msg = document.getElementById('comp-packet-msg');
    const year = parseInt(document.getElementById('comp-packet-year').value || new Date().getFullYear(), 10);
    const name = document.getElementById('comp-packet-name').value.trim() || `${year} Accountant Packet`;
    try {
      const res = await fetch('/api/compliance/packets', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({tax_year:year, name}) });
      const data = await res.json();
      if (data.id) {
        if (msg) { msg.style.display='inline'; msg.style.color='var(--accent)'; msg.textContent='✓ Created'; }
        complianceLoadPackets();
      } else throw new Error(data.error || 'Save failed');
    } catch(e) {
      if (msg) { msg.style.display='inline'; msg.style.color='var(--err)'; msg.textContent=e.message; }
    }
  }

  function complianceRenderExports() {
    const body = document.getElementById('comp-exports-body');
    if (!body) return;
    const packets = compliancePacketsCache || [];
    if (!packets.length) {
      body.innerHTML = '<div style="padding:24px;text-align:center;color:var(--text-dim);">No packets yet. Create one in the Accountant Packet tab.</div>';
      return;
    }
    body.innerHTML = packets.map(p => {
      const exports = p.exports || [];
      const done = exports.filter(e => e.status === 'complete').length;
      const total = exports.length;
      const pct = total ? Math.round((done / total) * 100) : 0;
      return `
        <div style="border:1px solid var(--border);border-radius:8px;padding:14px 16px;margin-bottom:10px;">
          <div style="display:flex;justify-content:space-between;align-items:center;gap:12px;">
            <div>
              <div style="font-weight:600;">${p.name}</div>
              <div style="font-size:12px;color:var(--text-soft);">${p.tax_year} · ${done}/${total} items complete · ${pct}%</div>
            </div>
            <button class="btn btn-ghost btn-sm" onclick="showTab('compliance',{complianceTarget:'packets'})">Open Packet →</button>
          </div>
          <div style="height:4px;background:var(--surface2);border-radius:2px;margin-top:10px;">
            <div style="height:4px;width:${pct}%;background:var(--accent);border-radius:2px;"></div>
          </div>
        </div>`;
    }).join('');
  }