const $ = (id) => document.getElementById(id);
const money = (v) => new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN', maximumFractionDigits: 0 }).format(v || 0);
const num = (id) => Number($(id).value || 0);

let lineChart, pieChart, barChart;
let socket;
let debounceTimer;
let lastRequest = null;
window.lastSimulationData = null;

function setTheme(theme) {
  document.body.dataset.theme = theme;
  localStorage.setItem('mortgage-theme', theme);
  const btn = $('themeToggle');
  if (btn) btn.textContent = theme === 'dark' ? '☀️ Jasny' : '🌙 Ciemny';
}

function initTheme() {
  const saved = localStorage.getItem('mortgage-theme') || 'dark';
  setTheme(saved);
  $('themeToggle').onclick = () => setTheme(document.body.dataset.theme === 'dark' ? 'light' : 'dark');
}

function connectWs() {
  const proto = location.protocol === 'https:' ? 'wss' : 'ws';
  socket = new WebSocket(`${proto}://${location.host}/ws/simulate`);
  socket.onopen = () => recalc();
  socket.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.error) return console.error(data.error);
    render(data);
  };
  socket.onclose = () => setTimeout(connectWs, 1200);
}

function buildRequest() {
  const rateChanges = [...document.querySelectorAll('#rateChanges .dynamic-row')].map(row => ({
    month: Number(row.querySelector('[data-field="month"]').value || 1),
    annual_rate: Number(row.querySelector('[data-field="rate"]').value || 0)
  })).filter(x => x.month > 0 && x.annual_rate >= 0);

  const overpayments = [...document.querySelectorAll('#overpayments .dynamic-row')].map(row => ({
    month: Number(row.querySelector('[data-field="month"]').value || 1),
    amount: Number(row.querySelector('[data-field="amount"]').value || 0),
    repeat: row.querySelector('[data-field="repeat"]').value,
    until_month: Number(row.querySelector('[data-field="until"]').value || 0) || null
  })).filter(x => x.month > 0 && x.amount > 0);

  return {
    principal: num('principal'),
    years: num('years'),
    margin: num('margin'),
    base_rate: num('baseRate'),
    installment_type: $('installmentType').value,
    overpayment_effect: $('overpaymentEffect').value,
    rate_changes: rateChanges,
    overpayments: overpayments
  };
}

function recalc() {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    lastRequest = buildRequest();
    if (socket?.readyState === WebSocket.OPEN) socket.send(JSON.stringify(lastRequest));
  }, 120);
}

function addRateRow(month = 13, rate = 7.0) {
  const div = document.createElement('div');
  div.className = 'dynamic-row';
  div.innerHTML = `
    <div><label class="form-label">Od miesiąca</label><input data-field="month" type="number" min="1" class="form-control form-control-sm" value="${month}"></div>
    <div><label class="form-label">Oproc. roczne %</label><input data-field="rate" type="number" step="0.01" class="form-control form-control-sm" value="${rate}"></div>
    <button class="btn btn-sm btn-outline-danger" type="button">Usuń</button>`;
  div.querySelector('button').onclick = () => { div.remove(); recalc(); };
  div.querySelectorAll('input').forEach(x => x.addEventListener('input', recalc));
  $('rateChanges').appendChild(div);
  recalc();
}

function addOverpaymentRow(month = 12, amount = 10000, repeat = 'once', until = '') {
  const div = document.createElement('div');
  div.className = 'dynamic-row overpay';
  div.innerHTML = `
    <div><label class="form-label">Miesiąc</label><input data-field="month" type="number" min="1" class="form-control form-control-sm" value="${month}"></div>
    <div><label class="form-label">Kwota</label><input data-field="amount" type="number" min="1" class="form-control form-control-sm" value="${amount}"></div>
    <div><label class="form-label">Powtarzaj</label><select data-field="repeat" class="form-select form-select-sm"><option value="once">raz</option><option value="monthly">co miesiąc</option><option value="yearly">co rok</option></select></div>
    <div><label class="form-label">Do mies.</label><input data-field="until" type="number" min="1" class="form-control form-control-sm" value="${until}"></div>
    <button class="btn btn-sm btn-outline-danger" type="button">Usuń</button>`;
  div.querySelector('[data-field="repeat"]').value = repeat;
  div.querySelector('button').onclick = () => { div.remove(); recalc(); };
  div.querySelectorAll('input,select').forEach(x => x.addEventListener('input', recalc));
  $('overpayments').appendChild(div);
  recalc();
}

function render(data) {
  window.lastSimulationData = data;
  const s = data.summary;
  $('summaryCards').innerHTML = [
    ['Odsetki', money(s.total_interest)],
    ['Oszczędność', money(s.interest_saved)],
    ['Nadpłaty', money(s.total_overpayment)],
    ['Okres', `${s.months} mies. / ${Math.ceil(s.months / 12)} lat`],
    ['Skrócenie', `${s.months_saved} mies.`],
    ['Średnia rata', money(s.average_payment)]
  ].map(([label, value]) => `<div class="col-6 col-md-4 col-xxl-2"><div class="card border-0 shadow-sm stat-card"><div class="card-body py-3"><div class="stat-label">${label}</div><div class="stat-value">${value}</div></div></div></div>`).join('');

  $('resultText').textContent = `Dzięki nadpłatom w wysokości ${money(s.total_overpayment)} oszczędzasz około ${money(s.interest_saved)} na odsetkach. Kredyt kończy się po ${s.months} miesiącach zamiast ${s.baseline_months}. Łącznie płacisz ${money(s.total_paid)}, z czego odsetki to ${money(s.total_interest)}.`;

  $('scheduleTable').innerHTML = data.schedule.slice(0, 180).map(r => `<tr><td>${r.month}</td><td>${r.rate.toFixed(2)}%</td><td>${money(r.payment)}</td><td>${money(r.principal_part)}</td><td>${money(r.interest_part)}</td><td>${money(r.overpayment)}</td><td>${money(r.remaining)}</td></tr>`).join('');

  renderCharts(data);
}

function renderCharts(data) {
  if (!data) return;
  const labels = data.schedule.map(r => r.month);
  const balance = data.schedule.map(r => r.remaining);
  const payment = data.schedule.map(r => r.payment);
  const yearly = new Map();
  data.schedule.forEach(r => {
    const year = Math.ceil(r.month / 12);
    yearly.set(year, (yearly.get(year) || 0) + r.interest_part);
  });

  lineChart?.destroy();
  lineChart = new Chart($('lineChart'), {
    type: 'line',
    data: { labels, datasets: [{ label: 'Saldo', data: balance, yAxisID: 'y' }, { label: 'Rata', data: payment, yAxisID: 'y1' }] },
    options: { responsive: true, maintainAspectRatio: false, interaction: { mode: 'index', intersect: false }, scales: { y: { beginAtZero: true }, y1: { position: 'right', beginAtZero: true, grid: { drawOnChartArea: false } } } }
  });

  pieChart?.destroy();
  pieChart = new Chart($('pieChart'), {
    type: 'pie',
    data: { labels: ['Kapitał', 'Odsetki', 'Nadpłaty'], datasets: [{ data: [lastRequest.principal, data.summary.total_interest, data.summary.total_overpayment] }] },
    options: { responsive: true, maintainAspectRatio: false }
  });

  barChart?.destroy();
  barChart = new Chart($('barChart'), {
    type: 'bar',
    data: { labels: [...yearly.keys()].map(x => `Rok ${x}`), datasets: [{ label: 'Odsetki', data: [...yearly.values()] }] },
    options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true } } }
  });
}

async function download(endpoint, filename) {
  const res = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(buildRequest()) });
  const blob = await res.blob();
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

async function loadNbp() {
  const btn = $('loadNbp');
  const old = btn.textContent;
  btn.textContent = 'Pobieram...';
  try {
    const res = await fetch('/api/rate/nbp');
    const data = await res.json();
    if (!res.ok || data.error) throw new Error(data.error || 'Błąd pobierania');
    $('baseRate').value = data.rate;
    recalc();
    btn.textContent = `NBP: ${data.rate}%`;
    setTimeout(() => btn.textContent = old, 2500);
  } catch (e) {
    alert(`Nie udało się pobrać stopy NBP: ${e.message}`);
    btn.textContent = old;
  }
}

['principal','years','baseRate','margin','installmentType','overpaymentEffect'].forEach(id => $(id).addEventListener('input', recalc));
$('addRate').onclick = () => addRateRow();
$('addOverpayment').onclick = () => addOverpaymentRow();
$('exportCsv').onclick = () => download('/api/export/csv', 'symulacja-kredytu.csv');
$('exportPdf').onclick = () => download('/api/export/pdf', 'symulacja-kredytu.pdf');
$('loadNbp').onclick = loadNbp;
initTheme();

addOverpaymentRow(24, 20000, 'once', '');
addOverpaymentRow(36, 500, 'monthly', 120);
connectWs();
