import { api, toast } from '/static/js/api.js';
import { lineChart, barChart } from '/static/js/charts.js';

const errorBox = document.getElementById('error');
const esc = (s) => String(s ?? '').replace(/[&<>"']/g, (c) => ({
  '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;',
}[c]));

let me = null;

function rangeQS() {
  const from = document.getElementById('m-from').value;
  const to = document.getElementById('m-to').value;
  const p = new URLSearchParams();
  if (from) p.set('from', from);
  if (to) p.set('to', to);
  return p;
}

function card(label, value, hint) {
  return `<div class="card stat"><p class="stat-label">${esc(label)}</p>
    <p class="stat-value">${esc(value)}</p>
    ${hint ? `<p class="hint">${esc(hint)}</p>` : ''}</div>`;
}

const weekLabel = (iso) => {
  const d = new Date(iso);
  return `${d.getMonth() + 1}/${d.getDate()}`;
};

async function loadDeveloper() {
  const res = await api('GET', '/api/v1/developer/metrics?' + rangeQS());
  document.getElementById('dev-metrics').hidden = false;
  document.getElementById('dev-cards').innerHTML =
    card('Total bounty earned', res.totalBounty) +
    card('Tasks completed', res.tasksCompleted) +
    card('Approval rate', `${Math.round(res.approvalRate * 100)}%`,
      `${res.approved} approved · ${res.changesRequested} change requests`) +
    card('Avg assigned → approved', `${res.avgAssignToApproveHours.toFixed(1)} h`) +
    card('Time logged', `${Math.floor(res.timeLoggedMinutes / 60)}h ${res.timeLoggedMinutes % 60}m`);
  lineChart(document.getElementById('dev-weekly'),
    res.weekly.map((p) => ({ label: weekLabel(p.week), value: p.amount })),
    { label: 'weekly earnings' });
  barChart(document.getElementById('dev-customers'),
    res.perCustomer.map((g) => ({ label: g.key, value: g.amount })),
    { label: 'earnings per customer' });
  document.getElementById('m-csv').href = '/api/v1/developer/metrics?format=csv&' + rangeQS();
}

async function loadConsultant() {
  const qs = rangeQS();
  const cust = document.getElementById('m-customer').value;
  if (cust) qs.set('customerId', cust);
  const res = await api('GET', '/api/v1/consultant/metrics?' + qs);
  document.getElementById('cons-metrics').hidden = false;
  const sel = document.getElementById('m-customer');
  if (sel.options.length === 1) {
    res.customers.forEach((c) => sel.add(new Option(c.name, c.id)));
  }
  document.getElementById('cons-cards').innerHTML =
    card('Bounty awarded', res.totalBounty) +
    card('Tasks completed', res.tasksCompleted) +
    card('Atomization lead time', `${res.atomizationLeadHours.toFixed(1)} h`, 'imported → published') +
    card('Open board depth', res.openBoardDepth, 'published, unclaimed tasks');
  lineChart(document.getElementById('cons-weekly'),
    res.weekly.map((p) => ({ label: weekLabel(p.week), value: p.amount })),
    { label: 'weekly awards' });
  barChart(document.getElementById('cons-devs'),
    res.perDeveloper.map((g) => ({ label: g.key, value: g.amount })),
    { label: 'per developer' });
  barChart(document.getElementById('cons-customers'),
    res.perCustomer.map((g) => ({ label: g.key, value: g.amount })),
    { label: 'per customer' });
  document.getElementById('m-csv').href = '/api/v1/consultant/metrics?format=csv&' + qs;
}

async function loadLeaderboard() {
  const res = await api('GET', '/api/v1/leaderboard?' + rangeQS());
  const tbody = document.querySelector('#leaderboard tbody');
  tbody.replaceChildren(...res.leaderboard.map((row, i) => {
    const tr = document.createElement('tr');
    tr.innerHTML = `<td>${i + 1}</td><td>${esc(row.name)}</td><td>${row.tasks}</td><td>◈ ${row.amount}</td>`;
    return tr;
  }));
  if (!res.leaderboard.length) {
    tbody.innerHTML = '<tr><td colspan="4" class="muted">No bounties awarded yet.</td></tr>';
  }
}

async function loadAll() {
  errorBox.textContent = '';
  try {
    if (me.user.roles.developer) await loadDeveloper();
    if (me.user.roles.consultant || me.user.roles.admin) await loadConsultant();
    await loadLeaderboard();
  } catch (e) { errorBox.textContent = e.message; }
}

document.getElementById('m-apply').addEventListener('click', loadAll);
document.getElementById('m-customer').addEventListener('change', loadConsultant);
document.getElementById('lb-optout').addEventListener('change', async (e) => {
  try {
    await api('PATCH', '/api/v1/profile', { settings: { leaderboardOptOut: e.target.checked } });
    toast(e.target.checked ? 'You are hidden from the leaderboard.' : 'You are visible on the leaderboard.', 'ok');
    loadLeaderboard();
  } catch (err) { toast(err.message, 'err'); }
});

(async () => {
  me = await api('GET', '/api/v1/auth/me');
  document.getElementById('lb-optout').checked = !!me.user.settings.leaderboardOptOut;
  loadAll();
})();
