/*
 * checkout.js — fluxo de checkout com 3 métodos de pagamento em SANDBOX.
 *
 * IMPORTANTE: este ficheiro SIMULA os pagamentos no cliente para permitir
 * testar o fluxo sem backend. A integração real (Stripe / PayPal / IfThenPay)
 * está descrita em PAGAMENTOS.md — nunca se validam cartões/nem se cobram
 * valores só no frontend em produção.
 */
(function () {
  'use strict';
  const S = window.STORE, CART = window.CART;

  const form = document.getElementById('checkout-form');
  const overlay = document.getElementById('pay-overlay');
  const ov = document.getElementById('ov-content');

  // Se o cesto estiver vazio, volta ao cesto.
  if (CART.count() === 0) { location.replace('carrinho.html'); return; }

  function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); }

  /* --------------------------- Resumo lateral --------------------------- */
  function renderSummary() {
    const lines = CART.detailed();
    document.getElementById('mini-lines').innerHTML = lines.map(function (l) {
      return '<li class="mini-line">' +
        '<img src="' + l.image + '" alt="" width="60" height="80" loading="lazy"><span class="mini-line__qty">' + l.qty + '</span>' +
        '<span class="mini-line__name">' + esc(l.name) + '<em>' + esc(l.color) + ' · ' + esc(l.size) + '</em></span>' +
        '<span class="mini-line__price">' + S.formatPrice(l.lineTotal) + '</span></li>';
    }).join('');
    document.getElementById('c-sub').textContent = S.formatPrice(CART.subtotal());
    const ship = CART.shipping();
    document.getElementById('c-ship').textContent = ship === 0 ? 'Grátis' : S.formatPrice(ship);
    document.getElementById('c-total').textContent = S.formatPrice(CART.total());
  }
  renderSummary();

  /* ------------------------- Troca de painéis --------------------------- */
  function currentMethod() { return form.querySelector('input[name="method"]:checked').value; }
  form.querySelectorAll('input[name="method"]').forEach(function (r) {
    r.addEventListener('change', function () {
      const m = currentMethod();
      form.querySelectorAll('.pay-panel').forEach(function (p) {
        p.hidden = p.getAttribute('data-panel') !== m;
      });
    });
  });

  /* ------------------- Máscaras e validação de cartão ------------------- */
  const cardNumber = form.cardNumber, cardExp = form.cardExp, cardCvc = form.cardCvc;
  if (cardNumber) {
    cardNumber.addEventListener('input', function () {
      let v = cardNumber.value.replace(/\D/g, '').slice(0, 19);
      cardNumber.value = v.replace(/(.{4})/g, '$1 ').trim();
    });
    cardExp.addEventListener('input', function () {
      let v = cardExp.value.replace(/\D/g, '').slice(0, 4);
      if (v.length >= 3) v = v.slice(0, 2) + '/' + v.slice(2);
      cardExp.value = v;
    });
    cardCvc.addEventListener('input', function () { cardCvc.value = cardCvc.value.replace(/\D/g, '').slice(0, 4); });
  }

  function luhn(num) {
    let sum = 0, alt = false;
    for (let i = num.length - 1; i >= 0; i--) {
      let n = parseInt(num[i], 10);
      if (alt) { n *= 2; if (n > 9) n -= 9; }
      sum += n; alt = !alt;
    }
    return sum % 10 === 0;
  }
  function validExpiry(v) {
    const m = /^(\d{2})\/(\d{2})$/.exec(v); if (!m) return false;
    const mm = +m[1], yy = 2000 + +m[2];
    if (mm < 1 || mm > 12) return false;
    const now = new Date();
    const exp = new Date(yy, mm, 1); // 1º dia do mês seguinte
    return exp > now;
  }

  /* -------------------------- Validação geral --------------------------- */
  function markInvalid(field, bad) {
    const label = field.closest('.field');
    if (label) label.classList.toggle('is-invalid', bad);
  }
  function validateShipping() {
    let ok = true;
    ['email', 'firstName', 'lastName', 'address', 'zip', 'city'].forEach(function (name) {
      const f = form[name];
      const bad = !f.value.trim() || (name === 'email' && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(f.value));
      markInvalid(f, bad);
      if (bad) ok = false;
    });
    return ok;
  }
  function validateCard() {
    const num = cardNumber.value.replace(/\s/g, '');
    let ok = true;
    const badNum = !(num.length >= 13 && luhn(num));
    markInvalid(cardNumber, badNum); if (badNum) ok = false;
    const badExp = !validExpiry(cardExp.value);
    markInvalid(cardExp, badExp); if (badExp) ok = false;
    const badCvc = !/^\d{3,4}$/.test(cardCvc.value);
    markInvalid(cardCvc, badCvc); if (badCvc) ok = false;
    return { ok: ok, num: num };
  }

  /* ------------------------------ Helpers ------------------------------- */
  function rnd(len) { let s = ''; for (let i = 0; i < len; i++) s += Math.floor(Math.random() * 10); return s; }
  function orderId() { return 'MSN-' + new Date().getFullYear() + '-' + rnd(6); }

  function openOverlay(html) { ov.innerHTML = html; overlay.hidden = false; document.body.style.overflow = 'hidden'; }
  function closeOverlay() { overlay.hidden = true; document.body.style.overflow = ''; }

  function spinner(text) {
    return '<div class="ov-state"><div class="ov-spin" aria-hidden="true"></div>' +
      '<p id="ov-title" class="ov-msg">' + esc(text) + '</p></div>';
  }
  function successView(order) {
    return '<div class="ov-state">' +
      '<div class="ov-check" aria-hidden="true">✓</div>' +
      '<h2 id="ov-title" class="display ov-big">Encomenda confirmada</h2>' +
      '<p class="ov-msg">Obrigado! Enviámos a confirmação para <strong>' + esc(order.email) + '</strong>.</p>' +
      '<p class="ov-order">Nº da encomenda<strong>' + esc(order.id) + '</strong></p>' +
      '<p class="ov-order">Total pago<strong>' + S.formatPrice(order.total) + '</strong> · ' + esc(order.methodLabel) + '</p>' +
      '<a class="add" href="index.html" data-transition data-label="Maison" style="margin-top:1.5rem;">Voltar à loja</a>' +
      '</div>';
  }
  function declinedView(msg) {
    return '<div class="ov-state">' +
      '<div class="ov-x" aria-hidden="true">✕</div>' +
      '<h2 id="ov-title" class="display ov-big">Pagamento recusado</h2>' +
      '<p class="ov-msg">' + esc(msg) + '</p>' +
      '<button type="button" class="add" id="ov-retry" style="margin-top:1.5rem;">Tentar novamente</button>' +
      '</div>';
  }

  function completeOrder(methodLabel) {
    const order = {
      id: orderId(),
      email: form.email.value.trim(),
      total: CART.total(),
      methodLabel: methodLabel
    };
    CART.clear();
    openOverlay(successView(order));
  }

  /* --------------------- Fluxos por método (sandbox) -------------------- */
  function payCard() {
    const res = validateCard();
    if (!res.ok) { form.querySelector('.field.is-invalid input').focus(); return; }
    openOverlay(spinner('A contactar o banco…'));
    // Simulação de autorização (à imagem dos cartões de teste Stripe)
    setTimeout(function () {
      if (res.num === '4000000000000002') {
        openOverlay(declinedView('O cartão foi recusado pelo emissor (cartão de teste 4000…0002). Experimente 4242 4242 4242 4242.'));
        document.getElementById('ov-retry').addEventListener('click', closeOverlay);
      } else if (res.num === '4242424242424242' || luhn(res.num)) {
        completeOrder('Cartão terminado em ' + res.num.slice(-4));
      } else {
        openOverlay(declinedView('Número de cartão inválido.'));
        document.getElementById('ov-retry').addEventListener('click', closeOverlay);
      }
    }, 1400);
  }

  function payMultibanco() {
    const entidade = '21883';                    // entidade de teste
    const referencia = rnd(9).replace(/(\d{3})(\d{3})(\d{3})/, '$1 $2 $3');
    const total = CART.total();
    openOverlay(
      '<div class="ov-state ov-mb">' +
      '<span class="overline">Multibanco · Aguarda pagamento</span>' +
      '<h2 id="ov-title" class="display ov-big">Referência gerada</h2>' +
      '<div class="mb-ref">' +
      '<div><span>Entidade</span><strong>' + entidade + '</strong></div>' +
      '<div><span>Referência</span><strong>' + referencia + '</strong></div>' +
      '<div><span>Valor</span><strong>' + S.formatPrice(total) + '</strong></div>' +
      '</div>' +
      '<p class="ov-msg">Pague em qualquer caixa Multibanco ou homebanking. A encomenda fica reservada 48h.</p>' +
      '<button type="button" class="add" id="mb-sim">Simular pagamento recebido</button>' +
      '<button type="button" class="ov-cancel" id="mb-cancel">Cancelar</button>' +
      '</div>'
    );
    document.getElementById('mb-sim').addEventListener('click', function () {
      openOverlay(spinner('A confirmar pagamento…'));
      setTimeout(function () { completeOrder('Multibanco · Ent. ' + entidade); }, 1200);
    });
    document.getElementById('mb-cancel').addEventListener('click', closeOverlay);
  }

  function payPaypal() {
    openOverlay(spinner('A redirecionar para o PayPal Sandbox…'));
    setTimeout(function () {
      openOverlay(
        '<div class="ov-state ov-paypal">' +
        '<div class="pp-logo"><em>Pay</em><b>Pal</b></div>' +
        '<span class="overline">Ambiente Sandbox</span>' +
        '<p class="ov-msg">Inicie sessão na sua conta de teste PayPal para autorizar o pagamento de <strong>' + S.formatPrice(CART.total()) + '</strong>.</p>' +
        '<button type="button" class="add pp-btn" id="pp-pay">Iniciar sessão e pagar</button>' +
        '<button type="button" class="ov-cancel" id="pp-cancel">Cancelar e voltar</button>' +
        '</div>'
      );
      document.getElementById('pp-pay').addEventListener('click', function () {
        openOverlay(spinner('A autorizar com o PayPal…'));
        setTimeout(function () { completeOrder('PayPal (sandbox)'); }, 1300);
      });
      document.getElementById('pp-cancel').addEventListener('click', closeOverlay);
    }, 1200);
  }

  /* ------------------------------ Submit -------------------------------- */
  form.addEventListener('submit', function (e) {
    e.preventDefault();
    if (!validateShipping()) {
      const first = form.querySelector('.field.is-invalid input');
      if (first) first.focus();
      return;
    }
    const method = currentMethod();
    if (method === 'card') payCard();
    else if (method === 'mb') payMultibanco();
    else if (method === 'paypal') payPaypal();
  });

  // Fecha overlay com ESC (exceto no ecrã de sucesso, que não tem retrocesso)
  document.addEventListener('keydown', function (e) {
    if (e.key === 'Escape' && !overlay.hidden && ov.querySelector('.ov-cancel, #ov-retry')) closeOverlay();
  });
})();
