"use strict";

// Data komt uit products.js (window.PRODUCTS / window.CATEGORIES).
const PRODUCTS = window.PRODUCTS || [];
const CATEGORIES = window.CATEGORIES || [{ key: "all", label: "Alles" }];

const TAX_RATE = 0.21;

// Winkelmandje: Map van product-id -> aantal.
const cart = new Map();
let activeFilter = "all";

const els = {
  grid: document.getElementById("grid"),
  filters: document.getElementById("filters"),
  productCount: document.getElementById("productCount"),
  overlay: document.getElementById("overlay"),
  drawer: document.getElementById("drawer"),
  cartItems: document.getElementById("cartItems"),
  cartCount: document.getElementById("cartCount"),
  cartSub: document.getElementById("cartSub"),
  cartTax: document.getElementById("cartTax"),
  cartTotal: document.getElementById("cartTotal"),
  checkoutBtn: document.getElementById("checkoutBtn"),
  modalWrap: document.getElementById("modalWrap"),
  modalContent: document.getElementById("modalContent"),
  toast: document.getElementById("toast"),
  openCart: document.getElementById("openCart"),
  closeCart: document.getElementById("closeCart"),
};

// Hulpfuncties voor opmaak.
const formatPrice = (value) => "\u20AC" + value.toFixed(2).replace(".", ",");
const escapeHtml = (str) =>
  String(str).replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));
const stars = (rating) => "\u2605".repeat(rating) + "\u2606".repeat(5 - rating);
const findProduct = (id) => PRODUCTS.find((p) => p.id === id);

// Tegelinhoud: toon de foto als die er is, val anders terug op de connector-tegel.
// onerror verwijdert een gebroken afbeelding en toont alsnog de connectors.
function thumbInner(p) {
  const fallback = `
    <span class="conn">${escapeHtml(p.from)}</span>
    <span class="arrow">&rarr;</span>
    <span class="conn">${escapeHtml(p.to)}</span>
  `;
  if (p.image) {
    return `<img src="${escapeHtml(p.image)}" alt="${escapeHtml(p.name)}"
      onerror="this.remove(); this.parentNode.classList.add('thumb--fallback'); this.parentNode.insertAdjacentHTML('beforeend', this.parentNode.dataset.fallback);"
      />`;
  }
  return fallback;
}

// Rendering.
function renderFilters() {
  els.filters.innerHTML = CATEGORIES.map((c) =>
    `<button class="filter${c.key === activeFilter ? " active" : ""}" data-filter="${c.key}">${escapeHtml(c.label)}</button>`
  ).join("");
}

function visibleProducts() {
  return activeFilter === "all" ? PRODUCTS : PRODUCTS.filter((p) => p.category === activeFilter);
}

function renderCatalog() {
  const list = visibleProducts();
  els.productCount.textContent = list.length + " producten" + (activeFilter === "all" ? "" : " in deze categorie");
  els.grid.innerHTML = list.map((p) => {
    const fallback = `<span class="conn">${escapeHtml(p.from)}</span><span class="arrow">&rarr;</span><span class="conn">${escapeHtml(p.to)}</span>`;
    const thumb = p.image
      ? `<img src="${escapeHtml(p.image)}" alt="${escapeHtml(p.name)}" onerror="this.remove(); this.parentNode.innerHTML = this.parentNode.dataset.fallback;" />`
      : fallback;
    return `
      <article class="card">
        <div class="thumb" data-fallback="${escapeHtml(fallback)}">
          ${thumb}
        </div>
        <div class="body">
          <div class="meta">
            <span class="sku">${escapeHtml(p.id)}</span>
            <span class="stars">${stars(p.rating)}<span class="reviews">(${p.reviews})</span></span>
          </div>
          <h3>${escapeHtml(p.name)}</h3>
          <p class="desc">${escapeHtml(p.desc)}</p>
          <div class="foot">
            <span class="price">${formatPrice(p.price)}<small>${formatPrice(p.old)}</small></span>
            <button class="add-btn" data-add="${p.id}">Toevoegen</button>
          </div>
        </div>
      </article>
    `;
  }).join("");
}

function cartTotals() {
  let count = 0;
  let subtotal = 0;
  for (const [id, qty] of cart) {
    const product = findProduct(id);
    if (!product) continue;
    count += qty;
    subtotal += product.price * qty;
  }
  const tax = subtotal * TAX_RATE;
  return { count, subtotal, tax, total: subtotal + tax };
}

function renderCart() {
  const { count, subtotal, tax, total } = cartTotals();
  els.cartCount.textContent = String(count);
  els.cartSub.innerHTML = formatPrice(subtotal);
  els.cartTax.innerHTML = formatPrice(tax);
  els.cartTotal.innerHTML = formatPrice(total);
  els.checkoutBtn.disabled = count === 0;

  if (cart.size === 0) {
    els.cartItems.innerHTML = '<div class="cart-empty">Uw winkelmandje is leeg.</div>';
    return;
  }

  const rows = [];
  for (const [id, qty] of cart) {
    const p = findProduct(id);
    if (!p) continue;
    const tile = p.image
      ? `<img src="${escapeHtml(p.image)}" alt="" onerror="this.remove(); this.parentNode.textContent = this.parentNode.dataset.fallback;" />`
      : escapeHtml(p.from);
    rows.push(`
      <div class="cart-row">
        <div class="tile" data-fallback="${escapeHtml(p.from)}" aria-hidden="true">${tile}</div>
        <div class="info">
          <strong>${escapeHtml(p.name)}</strong>
          <span class="unit">${formatPrice(p.price)} per stuk</span>
          <div class="qty">
            <button data-step="-1" data-id="${p.id}" aria-label="Aantal verlagen">&minus;</button>
            <span>${qty}</span>
            <button data-step="1" data-id="${p.id}" aria-label="Aantal verhogen">+</button>
          </div>
        </div>
        <span class="line-total">${formatPrice(p.price * qty)}</span>
      </div>
    `);
  }
  els.cartItems.innerHTML = rows.join("");
}

// Toast.
let toastTimer;
function showToast(message) {
  els.toast.textContent = message;
  els.toast.classList.add("show");
  clearTimeout(toastTimer);
  toastTimer = setTimeout(() => els.toast.classList.remove("show"), 2200);
}

// Mandje-operaties.
function addToCart(id) {
  const product = findProduct(id);
  if (!product) return;
  cart.set(id, (cart.get(id) || 0) + 1);
  renderCart();
  showToast(product.name + " toegevoegd aan het mandje.");
}

function stepQuantity(id, step) {
  if (!cart.has(id)) return;
  const next = cart.get(id) + step;
  if (next <= 0) {
    cart.delete(id);
  } else {
    cart.set(id, next);
  }
  renderCart();
}

function clearCart() {
  cart.clear();
  renderCart();
}

// Drawer.
function openCart() {
  els.overlay.classList.add("open");
  els.drawer.classList.add("open");
}
function closeCart() {
  els.overlay.classList.remove("open");
  els.drawer.classList.remove("open");
}

// Modal.
function openModal() { els.modalWrap.classList.add("open"); }
function closeModal() { els.modalWrap.classList.remove("open"); }

function renderCheckoutForm() {
  const { total } = cartTotals();
  els.modalContent.innerHTML = `
    <h2>Afrekenen</h2>
    <p class="sub">Dit formulier verwerkt geen gegevens. Ingevoerde waarden worden niet opgeslagen of verzonden.</p>
    <form id="payForm" novalidate>
      <div class="field">
        <label for="f-name">Naam</label>
        <input id="f-name" name="name" required autocomplete="name" placeholder="Voor- en achternaam" />
      </div>
      <div class="field">
        <label for="f-email">E-mailadres</label>
        <input id="f-email" name="email" type="email" required autocomplete="email" placeholder="naam@voorbeeld.nl" />
      </div>
      <div class="field">
        <label for="f-address">Bezorgadres</label>
        <input id="f-address" name="address" required autocomplete="street-address" placeholder="Straat, huisnummer, plaats" />
      </div>
      <div class="field">
        <label for="f-card">Kaartnummer (voer geen echte gegevens in)</label>
        <input id="f-card" name="card" inputmode="numeric" required placeholder="0000 0000 0000 0000" />
      </div>
      <div class="row2">
        <div class="field">
          <label for="f-exp">Vervaldatum</label>
          <input id="f-exp" name="exp" required placeholder="MM/JJ" />
        </div>
        <div class="field">
          <label for="f-cvc">CVC</label>
          <input id="f-cvc" name="cvc" inputmode="numeric" required placeholder="123" />
        </div>
      </div>
      <button class="pay-btn" type="submit">Plaats bestelling (${formatPrice(total)})</button>
      <p class="pay-note">Demonstratieformulier. Er wordt geen betaling uitgevoerd.</p>
    </form>
  `;
  document.getElementById("payForm").addEventListener("submit", (event) => {
    event.preventDefault();
    const form = event.currentTarget;
    // Gebruik native validatie in plaats van ongeldige invoer te negeren.
    if (!form.checkValidity()) {
      form.reportValidity();
      return;
    }
    renderSuccess();
  });
}

function renderSuccess() {
  const { count } = cartTotals();
  const orderId = "CL-" + Math.floor(100000 + Math.random() * 900000);
  els.modalContent.innerHTML = `
    <div class="success">
      <div class="check" aria-hidden="true">&checkmark;</div>
      <h2>Bestelling geregistreerd</h2>
      <p>${count} fictief artikel(en) zijn vastgelegd in deze demonstratie.</p>
      <div class="order-id">Referentie: ${escapeHtml(orderId)}</div>
      <p>Verwachte levering: niet van toepassing.</p>
      <button class="pay-btn" id="doneBtn" style="margin-top:18px">Verder winkelen</button>
    </div>
  `;
  clearCart();
  document.getElementById("doneBtn").addEventListener("click", () => {
    closeModal();
    showToast("Winkelmandje geleegd.");
  });
}

// Event-koppeling (delegatie waar lijsten betrokken zijn).
els.filters.addEventListener("click", (event) => {
  const button = event.target.closest("[data-filter]");
  if (!button) return;
  activeFilter = button.dataset.filter;
  renderFilters();
  renderCatalog();
});

els.grid.addEventListener("click", (event) => {
  const button = event.target.closest("[data-add]");
  if (button) addToCart(button.dataset.add);
});

els.cartItems.addEventListener("click", (event) => {
  const button = event.target.closest("[data-step]");
  if (button) stepQuantity(button.dataset.id, Number(button.dataset.step));
});

els.openCart.addEventListener("click", openCart);
els.closeCart.addEventListener("click", closeCart);
els.overlay.addEventListener("click", closeCart);

els.checkoutBtn.addEventListener("click", () => {
  if (cart.size === 0) return;
  closeCart();
  renderCheckoutForm();
  openModal();
});

els.modalWrap.addEventListener("click", (event) => {
  if (event.target === els.modalWrap) closeModal();
});

document.addEventListener("keydown", (event) => {
  if (event.key === "Escape") {
    closeModal();
    closeCart();
  }
});

// Eerste render.
document.getElementById("year").textContent = String(new Date().getFullYear());
renderFilters();
renderCatalog();
renderCart();
