
function paymentOpenModal(id) {
  const modal = typeof id === 'string' ? document.getElementById(id) : id;
  if (!modal) return;
  if (window.Pyrk && typeof Pyrk.openModal === 'function') {
    try {
      Pyrk.openModal(modal);
      modal.hidden = false;
      modal.removeAttribute('hidden');
      modal.setAttribute('aria-hidden', 'false');
      return;
    } catch (e) {
      console.warn('Pyrk.openModal failed, using fallback.', e);
    }
  }
  modal.hidden = false;
  modal.removeAttribute('hidden');
  modal.style.display = 'grid';
  modal.setAttribute('aria-hidden', 'false');
  modal.classList.add('is-open');
  document.body.classList.add('modal-open');
}

function paymentCloseModal(id) {
  const modal = typeof id === 'string' ? document.getElementById(id) : id;
  if (!modal) return;
  if (window.Pyrk && typeof Pyrk.closeModal === 'function') {
    try {
      Pyrk.closeModal(modal);
    } catch (e) {
      console.warn('Pyrk.closeModal failed, using fallback.', e);
    }
  }
  modal.hidden = true;
  modal.setAttribute('hidden', 'hidden');
  modal.style.display = 'none';
  modal.setAttribute('aria-hidden', 'true');
  modal.classList.remove('is-open');
  if (!document.querySelector('.modal-backdrop:not([hidden]), .modal:not([hidden])')) {
    document.body.classList.remove('modal-open');
  }
}

function paymentRowKey(row) {
  return `${Number(row.user_id || 0)}:${Number(row.registration_id || 0)}`;
}


let paymentState = {
  walks: [],
  rows: [],
  selectedWalk: null,
  selectedWalkId: 0,
  paymentTypes: {},
  currentRow: null
};

const esc = value => Pyrk.esc(value ?? '');

function money(amount, currency) {
  const value = Number(amount || 0);
  const cur = String(currency || '').toUpperCase();
  return `${value.toLocaleString(undefined, {minimumFractionDigits: value % 1 ? 2 : 0, maximumFractionDigits: 2})}${cur ? ' ' + cur : ''}`;
}

function statusPill(status) {
  const s = String(status || 'unpaid').toLowerCase();
  const cls = s === 'paid' ? 'pill-green' : (s === 'partial' ? 'pill-orange' : (['refunded','cancelled'].includes(s) ? 'pill-red' : 'pill-muted'));
  return `<span class="pill ${cls}">${esc(s.replace(/_/g, ' '))}</span>`;
}

function typeLabel(type) {
  const t = String(type || '').toLowerCase();
  return paymentState.paymentTypes[t] || t.replace(/_/g, ' ') || '—';
}

function renderPaymentTypeOptions(selected = '') {
  const select = document.getElementById('payType');
  if (!select) return;

  const types = paymentState.paymentTypes || {};
  const keys = Object.keys(types);
  const fallback = keys.length ? keys[0] : 'cash';
  const selectedKey = selected && (types[selected] || selected === 'other') ? selected : fallback;

  select.innerHTML = (keys.length ? keys : ['cash']).map(key => {
    const label = types[key] || typeLabel(key);
    return `<option value="${esc(key)}">${esc(label)}</option>`;
  }).join('');

  select.value = selectedKey;
}

function syncPaymentStatusFromAmounts() {
  const statusEl = document.getElementById('payStatus');
  const due = Number(document.getElementById('payAmountDue')?.value || 0);
  const paid = Number(document.getElementById('payAmountPaid')?.value || 0);

  if (!statusEl) return;
  if (['refunded', 'cancelled'].includes(String(statusEl.value || '').toLowerCase())) return;

  if (paid <= 0) {
    statusEl.value = 'unpaid';
    return;
  }

  if (due > 0 && paid + 0.00001 < due) {
    statusEl.value = 'partial';
    if (!document.getElementById('payPaidDate')?.value) document.getElementById('payPaidDate').value = todayDmy();
    return;
  }

  statusEl.value = 'paid';
  if (!document.getElementById('payPaidDate')?.value) document.getElementById('payPaidDate').value = todayDmy();
}

function pad2(value) {
  return String(value).padStart(2, '0');
}

function todayDmy() {
  const d = new Date();
  return `${pad2(d.getDate())}/${pad2(d.getMonth() + 1)}/${d.getFullYear()}`;
}

function parsePaymentDateTime(value) {
  const raw = String(value || '').trim();
  if (!raw) return null;

  let m = raw.match(/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::\d{2})?)?/);
  if (m) {
    return {
      date: `${m[3]}/${m[2]}/${m[1]}`,
      time: m[4] && m[5] ? `${m[4]}:${m[5]}` : ''
    };
  }

  m = raw.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/);
  if (m) {
    return {
      date: `${pad2(m[1])}/${pad2(m[2])}/${m[3]}`,
      time: m[4] && m[5] ? `${pad2(m[4])}:${m[5]}` : ''
    };
  }

  return null;
}

function dateText(value) {
  const parsed = parsePaymentDateTime(value);
  if (!parsed) return '—';
  return parsed.time && parsed.time !== '00:00' ? `${parsed.date} ${parsed.time}` : parsed.date;
}

function normaliseDmyDate(value) {
  const raw = String(value || '').trim();
  if (!raw) return '';
  const m = raw.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
  if (!m) return null;

  const day = Number(m[1]);
  const month = Number(m[2]);
  const year = Number(m[3]);
  const test = new Date(year, month - 1, day);
  if (test.getFullYear() !== year || test.getMonth() !== month - 1 || test.getDate() !== day) return null;

  return `${pad2(day)}/${pad2(month)}/${year}`;
}

function dmyToIso(value) {
  const clean = normaliseDmyDate(value);
  if (clean === '') return '';
  if (clean === null) return null;
  const [day, month, year] = clean.split('/');
  return `${year}-${month}-${day}`;
}

function isoToDmy(value) {
  const m = String(value || '').match(/^(\d{4})-(\d{2})-(\d{2})$/);
  return m ? `${m[3]}/${m[2]}/${m[1]}` : '';
}

function syncNativePaymentDate() {
  const dmy = document.getElementById('payPaidDate')?.value || '';
  const picker = document.getElementById('payPaidDatePicker');
  const iso = dmyToIso(dmy);
  if (picker && iso) picker.value = iso;
}

function paymentPaidAtPayload() {
  const dateInput = document.getElementById('payPaidDate');
  const timeInput = document.getElementById('payPaidTime');
  const hidden = document.getElementById('payPaidAt');

  const dmy = String(dateInput?.value || '').trim();
  const time = String(timeInput?.value || '').trim();

  if (!dmy && !time) {
    if (hidden) hidden.value = '';
    return {ok: true, value: ''};
  }

  const isoDate = dmyToIso(dmy);
  if (!isoDate) {
    return {ok: false, message: 'Payment date must be dd/mm/yyyy.'};
  }

  if (time && !/^\d{2}:\d{2}$/.test(time)) {
    return {ok: false, message: 'Payment time must be HH:MM or left empty.'};
  }

  const value = `${isoDate} ${time || '00:00'}`;
  if (hidden) hidden.value = value;
  return {ok: true, value};
}

function setPaidDateFields(value) {
  const parsed = parsePaymentDateTime(value);
  document.getElementById('payPaidDate').value = parsed?.date || '';
  document.getElementById('payPaidTime').value = parsed?.time === '00:00' ? '' : (parsed?.time || '');
  document.getElementById('payPaidAt').value = value ? String(value).replace('T', ' ').slice(0, 16) : '';
  syncNativePaymentDate();
}

function setPaymentMessage(res) {
  Pyrk.toast('paymentMsg', res);
}

function filteredWalks() {
  const q = (document.getElementById('paymentWalkSearch')?.value || '').toLowerCase().trim();
  return (paymentState.walks || []).filter(w => {
    const hay = `${w.title || ''} ${w.route_name || ''} ${w.walk_date || ''}`.toLowerCase();
    return !q || hay.includes(q);
  });
}

function renderWalks() {
  const list = document.getElementById('paymentWalkList');
  if (!list) return;

  const rows = filteredWalks();
  list.innerHTML = rows.map(w => {
    const id = Number(w.id);
    const selected = Number(paymentState.selectedWalkId) === id;
    return `<button class="paid-walk-card ${selected ? 'is-active' : ''}" type="button" data-walk-id="${id}">
      <span><strong>${esc(w.title)}</strong><small>${esc(w.route_name || '')} · ${esc(w.walk_date || '')} ${esc(String(w.start_time || '').slice(0,5))}</small></span>
      <b>${money(w.payment_amount, w.payment_currency)}</b>
      <em>${Number(w.registrant_count || 0)} registered · ${Number(w.paid_count || 0)} paid</em>
    </button>`;
  }).join('') || '<p class="muted">No paid walks found. Open Walks and set Payment model = Paid.</p>';
}

function filteredRows() {
  const q = (document.getElementById('paymentSearch')?.value || '').toLowerCase().trim();
  const status = document.getElementById('paymentStatusFilter')?.value || '';
  return (paymentState.rows || []).filter(row => {
    const hay = `${row.full_name || ''} ${row.email || ''} ${row.mobile || ''} ${row.payment_type || ''} ${row.reference_no || ''}`.toLowerCase();
    const rowStatus = String(row.payment_status_effective || 'unpaid');
    return (!q || hay.includes(q)) && (!status || rowStatus === status);
  });
}

function renderSummary(summary) {
  const selected = paymentState.selectedWalk;
  const currency = selected?.payment_currency || selected?.walk_currency || '';

  document.getElementById('payTotalDue').textContent = money(summary?.total_due || 0, currency);
  document.getElementById('payTotalPaid').textContent = money(summary?.total_paid || 0, currency);
  document.getElementById('payBalance').textContent = money(summary?.balance_due || 0, currency);

  document.getElementById('payRegistrantCount').textContent = Number(summary?.registrants || 0);
  document.getElementById('payPaidCount').textContent = Number(summary?.paid_count || 0);
  document.getElementById('payPartialCount').textContent = Number(summary?.partial_count || 0);
  document.getElementById('payUnpaidCount').textContent = Number(summary?.unpaid_count || 0);
}

function renderSelectedWalk() {
  const title = document.getElementById('selectedWalkTitle');
  const meta = document.getElementById('selectedWalkMeta');
  const w = paymentState.selectedWalk;

  if (!w) {
    title.textContent = 'Choose a paid walk';
    meta.textContent = 'No paid walk selected.';
    return;
  }

  title.textContent = w.title || 'Paid walk';
  meta.textContent = `${w.route_name || ''} · ${dateText(w.walk_date)} ${String(w.start_time || '').slice(0,5)} · Fee ${money(w.payment_amount, w.payment_currency)}`;
}


function receiptNo(row) {
  if (row.reference_no) return String(row.reference_no);
  const walkId = Number(paymentState.selectedWalkId || row.walk_id || 0);
  const regId = Number(row.registration_id || 0);
  return `PYRK-${walkId}-${regId || Number(row.user_id || 0)}`;
}

function printPaymentReceipt(row = null) {
  row = row || paymentState.currentRow;
  if (!row) {
    setPaymentMessage({ok:false, message:'No payment row selected.'});
    return;
  }

  const walk = paymentState.selectedWalk || {};
  const currency = row.currency_effective || walk.payment_currency || row.payment_currency || 'LBP';
  const paid = Number(row.amount_paid_effective ?? row.amount_paid ?? 0);
  const due = Number(row.amount_due_effective ?? row.amount_due ?? walk.payment_amount ?? 0);
  const balance = Math.max(0, Number(row.balance_due ?? (due - paid)));
  const status = String(row.payment_status_effective || row.payment_status || 'unpaid');

  if (paid <= 0 && status === 'unpaid') {
    setPaymentMessage({ok:false, message:'No paid amount to print yet.'});
    return;
  }

  const html = `<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Payment receipt ${esc(receiptNo(row))}</title>
<style>
  body { font-family: Arial, sans-serif; margin: 0; background: #f8fafc; color: #0f172a; }
  .receipt { width: 760px; max-width: calc(100% - 32px); margin: 24px auto; background: #fff; border-radius: 18px; padding: 30px; box-shadow: 0 20px 60px rgba(15,23,42,.12); }
  .head { display: flex; justify-content: space-between; gap: 18px; border-bottom: 2px solid #e2e8f0; padding-bottom: 18px; margin-bottom: 20px; }
  .brand { font-size: 24px; font-weight: 900; }
  .muted { color: #64748b; }
  .pill { display: inline-block; padding: 6px 12px; border-radius: 999px; background: #ecfdf3; color: #047857; font-weight: 800; text-transform: uppercase; font-size: 12px; }
  .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 20px 0; }
  .box { border: 1px solid #e2e8f0; border-radius: 14px; padding: 14px; }
  .box span { display: block; color: #64748b; font-size: 12px; text-transform: uppercase; font-weight: 800; margin-bottom: 5px; }
  .box strong { font-size: 16px; }
  table { width: 100%; border-collapse: collapse; margin-top: 18px; }
  th, td { padding: 12px; border-bottom: 1px solid #e2e8f0; text-align: left; }
  th { color: #64748b; font-size: 12px; text-transform: uppercase; }
  .total { font-size: 20px; font-weight: 900; }
  .footer { margin-top: 30px; font-size: 12px; color: #64748b; display: flex; justify-content: space-between; gap: 18px; }
  @media print {
    body { background: #fff; }
    .receipt { box-shadow: none; width: auto; margin: 0; border-radius: 0; }
    .no-print { display: none; }
  }
</style>
</head>
<body>
  <div class="receipt">
    <div class="head">
      <div>
        <div class="brand">Pyrk Walking Club</div>
        <div class="muted">Payment receipt</div>
      </div>
      <div style="text-align:right">
        <div class="pill">${esc(status)}</div>
        <div class="muted" style="margin-top:8px">Receipt: <strong>${esc(receiptNo(row))}</strong></div>
      </div>
    </div>

    <div class="grid">
      <div class="box"><span>Member</span><strong>${esc(row.full_name || 'Member')}</strong><div class="muted">${esc(row.email || '')}</div></div>
      <div class="box"><span>Walk</span><strong>${esc(walk.title || '')}</strong><div class="muted">${esc(walk.route_name || '')}</div></div>
      <div class="box"><span>Payment method</span><strong>${esc(typeLabel(row.payment_type))}</strong></div>
      <div class="box"><span>Paid at</span><strong>${esc(dateText(row.paid_at) || '—')}</strong></div>
    </div>

    <table>
      <thead><tr><th>Description</th><th>Amount</th></tr></thead>
      <tbody>
        <tr><td>Walk fee</td><td>${money(due, currency)}</td></tr>
        <tr><td>Amount paid</td><td class="total">${money(paid, currency)}</td></tr>
        <tr><td>Balance</td><td>${money(balance, currency)}</td></tr>
      </tbody>
    </table>

    ${row.notes ? `<p class="muted"><strong>Notes:</strong> ${esc(row.notes)}</p>` : ''}
    <div class="footer">
      <span>Printed ${new Date().toLocaleString()}</span>
      <span>This is a system-generated receipt.</span>
    </div>
  </div>
  <div class="no-print" style="text-align:center;margin:20px"><button onclick="window.print()">Print</button></div>
<script>window.onload = () => setTimeout(() => window.print(), 250);</script>
</body>
</html>`;

  const win = window.open('', '_blank');
  if (!win) {
    setPaymentMessage({ok:false, message:'Popup blocked. Allow popups to print the receipt.'});
    return;
  }
  win.document.open();
  win.document.write(html);
  win.document.close();
}


function renderRows() {
  const body = document.getElementById('paymentRows');
  if (!body) return;

  const rows = filteredRows();
  body.innerHTML = rows.map(row => {
    const status = row.payment_status_effective || 'unpaid';
    const currency = row.currency_effective || paymentState.selectedWalk?.payment_currency || '';
    return `<tr>
      <td>
        <div class="member-cell">
          <span class="avatar">${esc(String(row.full_name || 'M').slice(0,1).toUpperCase())}</span>
          <span><strong>${esc(row.full_name || 'Member')}</strong><small>${esc(row.email || '')}${row.mobile ? ' · ' + esc(row.mobile) : ''}</small></span>
        </div>
      </td>
      <td>${money(row.amount_due_effective, currency)}</td>
      <td><strong>${money(row.amount_paid_effective, currency)}</strong></td>
      <td>${money(row.balance_due, currency)}</td>
      <td>${statusPill(status)}</td>
      <td>${esc(typeLabel(row.payment_type))}</td>
      <td>${esc(dateText(row.paid_at))}</td>
      <td class="payment-actions">
        <button class="btn btn-small btn-light" type="button" data-edit-payment="${paymentRowKey(row)}" data-user-id="${Number(row.user_id)}" data-registration-id="${Number(row.registration_id || 0)}">Record</button>
        ${Number(row.amount_paid_effective || 0) > 0 ? `<button class="btn btn-small btn-light" type="button" data-print-receipt="${paymentRowKey(row)}" data-user-id="${Number(row.user_id)}" data-registration-id="${Number(row.registration_id || 0)}">Receipt</button>` : ''}
      </td>
    </tr>`;
  }).join('') || '<tr><td colspan="8" class="muted">No registrants found for this paid walk.</td></tr>';
}

function renderAll(data) {
  paymentState.walks = data.walks || paymentState.walks || [];
  paymentState.selectedWalk = data.selected_walk || null;
  paymentState.selectedWalkId = Number(paymentState.selectedWalk?.id || paymentState.selectedWalkId || 0);
  paymentState.rows = data.rows || [];
  paymentState.paymentTypes = data.payment_types || paymentState.paymentTypes || {};
  renderPaymentTypeOptions(document.getElementById('payType')?.value || 'cash');

  renderWalks();
  renderSelectedWalk();
  renderSummary(data.summary || {});
  renderRows();
}

async function loadPayments(walkId = 0) {
  const params = {action: 'overview'};
  if (walkId) params.walk_id = walkId;

  const res = await Pyrk.get('walk_payments.php', params);
  if (!res.ok) {
    document.getElementById('paymentRows').innerHTML = `<tr><td colspan="8" class="notice bad">${esc(res.message)}</td></tr>`;
    return;
  }

  renderAll(res.data || {});
}

function openPaymentModal(row) {
  paymentState.currentRow = row;
  const currency = row.currency_effective || paymentState.selectedWalk?.payment_currency || 'LBP';

  document.getElementById('paymentModalTitle').textContent = row.full_name || 'Member payment';
  document.getElementById('paymentModalSub').textContent = `${paymentState.selectedWalk?.title || ''} · due ${money(row.amount_due_effective, currency)}`;

  document.getElementById('payWalkId').value = paymentState.selectedWalkId || row.walk_id || '';
  document.getElementById('payUserId').value = row.user_id || '';
  document.getElementById('payRegistrationId').value = row.registration_id || '';
  document.getElementById('payAmountDue').value = Number(row.amount_due_effective || 0).toFixed(2);
  document.getElementById('payAmountPaid').value = Number(row.amount_paid_effective || 0).toFixed(2);
  document.getElementById('payCurrency').value = currency;
  document.getElementById('payStatus').value = row.payment_status_effective || 'unpaid';
  renderPaymentTypeOptions(row.payment_type || 'cash');
  document.getElementById('payReference').value = row.reference_no || '';
  document.getElementById('payNotes').value = row.notes || '';

  setPaidDateFields(row.paid_at || '');

  document.getElementById('paymentMsg').textContent = '';
  paymentOpenModal('paymentModal');
}

async function savePayment(e) {
  e.preventDefault();

  const saveBtn = e.currentTarget?.querySelector('button[type="submit"]');
  if (saveBtn) {
    saveBtn.disabled = true;
    saveBtn.textContent = 'Saving...';
  }

  syncPaymentStatusFromAmounts();
  const paidAt = paymentPaidAtPayload();
  if (!paidAt.ok) {
    setPaymentMessage({ok:false, message: paidAt.message});
    if (saveBtn) {
      saveBtn.disabled = false;
      saveBtn.textContent = 'Save payment';
    }
    return;
  }

  const payload = {
    action: 'save',
    walk_id: document.getElementById('payWalkId').value,
    user_id: document.getElementById('payUserId').value,
    registration_id: document.getElementById('payRegistrationId').value,
    amount_due: document.getElementById('payAmountDue').value,
    amount_paid: document.getElementById('payAmountPaid').value,
    currency: document.getElementById('payCurrency').value,
    payment_status: document.getElementById('payStatus').value,
    payment_type: document.getElementById('payType').value,
    reference_no: document.getElementById('payReference').value,
    notes: document.getElementById('payNotes').value,
    paid_date: document.getElementById('payPaidDate').value,
    paid_time: document.getElementById('payPaidTime').value,
    paid_at: paidAt.value
  };

  try {
    const res = await Pyrk.post('walk_payments.php', payload);
    setPaymentMessage(res);
    if (res.ok) {
      await loadPayments(paymentState.selectedWalkId);
      window.setTimeout(() => paymentCloseModal('paymentModal'), 350);
    }
  } catch (err) {
    console.error(err);
    setPaymentMessage({ok:false, message:'Payment could not be saved. Check console/network error.'});
  } finally {
    if (saveBtn) {
      saveBtn.disabled = false;
      saveBtn.textContent = 'Save payment';
    }
  }
}

async function deletePayment() {
  const row = paymentState.currentRow;
  if (!row) return;
  if (!confirm('Remove this payment record?')) return;

  const res = await Pyrk.post('walk_payments.php', {
    action: 'delete',
    walk_id: paymentState.selectedWalkId,
    user_id: row.user_id
  });
  setPaymentMessage(res);
  if (res.ok) {
    await loadPayments(paymentState.selectedWalkId);
    paymentCloseModal('paymentModal');
  }
}

function markFullPaid() {
  const due = Number(document.getElementById('payAmountDue').value || 0);
  document.getElementById('payAmountPaid').value = due.toFixed(2);
  document.getElementById('payStatus').value = 'paid';
  if (!document.getElementById('payPaidDate').value) {
    document.getElementById('payPaidDate').value = todayDmy();
  }
  paymentPaidAtPayload();
}

document.getElementById('paymentWalkList')?.addEventListener('click', e => {
  const btn = e.target.closest('[data-walk-id]');
  if (!btn) return;
  paymentState.selectedWalkId = Number(btn.dataset.walkId || 0);
  loadPayments(paymentState.selectedWalkId);
});

document.getElementById('paymentRows')?.addEventListener('click', e => {
  const editBtn = e.target.closest('[data-edit-payment]');
  const receiptBtn = e.target.closest('[data-print-receipt]');
  const btn = editBtn || receiptBtn;
  if (!btn) return;
  e.preventDefault();
  e.stopPropagation();

  const key = String((editBtn ? btn.dataset.editPayment : btn.dataset.printReceipt) || '');
  const userId = Number(btn.dataset.userId || 0);
  const registrationId = Number(btn.dataset.registrationId || 0);

  let row = (paymentState.rows || []).find(r => paymentRowKey(r) === key);
  if (!row && registrationId) row = (paymentState.rows || []).find(r => Number(r.registration_id || 0) === registrationId);
  if (!row && userId) row = (paymentState.rows || []).find(r => Number(r.user_id || 0) === userId);

  if (!row) {
    setPaymentMessage({ok:false, message:'Could not find this payment row. Please refresh the page.'});
    return;
  }

  if (receiptBtn) printPaymentReceipt(row);
  else openPaymentModal(row);
});

document.getElementById('paymentWalkSearch')?.addEventListener('input', renderWalks);
document.getElementById('paymentSearch')?.addEventListener('input', renderRows);
document.getElementById('paymentStatusFilter')?.addEventListener('change', renderRows);
document.getElementById('refreshPaymentsBtn')?.addEventListener('click', () => loadPayments(paymentState.selectedWalkId));
document.getElementById('closePaymentModalBtn')?.addEventListener('click', () => paymentCloseModal('paymentModal'));
document.getElementById('paymentForm')?.addEventListener('submit', savePayment);
document.getElementById('deletePaymentBtn')?.addEventListener('click', deletePayment);
document.getElementById('markPaidBtn')?.addEventListener('click', markFullPaid);


document.getElementById('payPaidDate')?.addEventListener('blur', e => {
  const value = normaliseDmyDate(e.target.value);
  if (value) {
    e.target.value = value;
    syncNativePaymentDate();
  }
});
document.getElementById('payPaidDate')?.addEventListener('input', e => {
  let v = String(e.target.value || '').replace(/[^\d]/g, '').slice(0, 8);
  if (v.length >= 5) v = `${v.slice(0,2)}/${v.slice(2,4)}/${v.slice(4)}`;
  else if (v.length >= 3) v = `${v.slice(0,2)}/${v.slice(2)}`;
  e.target.value = v;
});

document.getElementById('payStatus')?.addEventListener('change', e => {
  if (e.target.value === 'paid') markFullPaid();
  if (e.target.value === 'unpaid') {
    document.getElementById('payAmountPaid').value = '0.00';
    document.getElementById('payPaidDate').value = '';
    document.getElementById('payPaidTime').value = '';
    document.getElementById('payPaidAt').value = '';
  }
});


document.getElementById('payAmountPaid')?.addEventListener('input', syncPaymentStatusFromAmounts);
document.getElementById('payAmountDue')?.addEventListener('input', syncPaymentStatusFromAmounts);
document.getElementById('printPaymentReceiptBtn')?.addEventListener('click', () => printPaymentReceipt(paymentState.currentRow));

document.getElementById('payPaidDateCalendarBtn')?.addEventListener('click', () => {
  const picker = document.getElementById('payPaidDatePicker');
  syncNativePaymentDate();
  if (picker?.showPicker) picker.showPicker();
  else picker?.click();
});
document.getElementById('payPaidDatePicker')?.addEventListener('change', e => {
  const dmy = isoToDmy(e.target.value);
  if (dmy) document.getElementById('payPaidDate').value = dmy;
});

loadPayments();


document.getElementById('paymentModal')?.addEventListener('click', e => {
  if (e.target && e.target.id === 'paymentModal') paymentCloseModal('paymentModal');
});
document.addEventListener('keydown', e => {
  if (e.key === 'Escape' && !document.getElementById('paymentModal')?.hidden) paymentCloseModal('paymentModal');
});
