/* =========================================================
   SAMYTH — Crème Capillaire Protéinée
   Vanilla JS · interactions, animations & form logic
   ========================================================= */
'use strict';

document.addEventListener('DOMContentLoaded', () => {

  /* ---------- Lucide icons (self-healing loader) ---------- */
  const renderIcons = () => {
    if (window.lucide && typeof window.lucide.createIcons === 'function') {
      window.lucide.createIcons();
      return true;
    }
    return false;
  };
  if (!renderIcons()) {
    // The vendored lucide script may not have executed yet (or failed to
    // load under heavy concurrency) — load it on demand, then render.
    const s = document.createElement('script');
    s.src = 'assets/vendor/lucide.min.js';
    s.onload = renderIcons;
    document.head.appendChild(s);
  }
  // Final safety net once everything (including images) has settled.
  window.addEventListener('load', renderIcons);

  /* ---------- AOS scroll animations ---------- */
  if (window.AOS) {
    AOS.init({
      duration: 750,
      easing: 'ease-out-cubic',
      once: true,
      offset: 60,
      disable: window.matchMedia('(prefers-reduced-motion: reduce)').matches,
    });
  }

  /* ---------- Current year ---------- */
  const yearEl = document.getElementById('year');
  if (yearEl) yearEl.textContent = new Date().getFullYear();

  /* =======================================================
     NAVBAR — scroll state + mobile menu
     ======================================================= */
  const navbar = document.getElementById('navbar');
  const onScroll = () => {
    if (window.scrollY > 30) navbar.classList.add('scrolled');
    else navbar.classList.remove('scrolled');
  };
  window.addEventListener('scroll', onScroll, { passive: true });
  onScroll();

  // Build a lightweight mobile menu on demand
  const navToggle = document.getElementById('navToggle');
  let mobileMenu = null;
  const buildMobileMenu = () => {
    mobileMenu = document.createElement('div');
    mobileMenu.className = 'mobile-menu p-8 flex flex-col gap-6';
    mobileMenu.innerHTML = `
      <button id="menuClose" class="self-end p-2 text-dark" aria-label="Fermer">
        <i data-lucide="x" class="w-7 h-7"></i>
      </button>
      <a href="#benefits" class="text-lg font-600 text-dark">Bienfaits</a>
      <a href="#ingredients" class="text-lg font-600 text-dark">Ingrédients</a>
      <a href="#results" class="text-lg font-600 text-dark">Résultats</a>
      <a href="#testimonials" class="text-lg font-600 text-dark">Avis</a>
      <a href="#faq" class="text-lg font-600 text-dark">FAQ</a>
      <a href="#order" class="btn-primary justify-center mt-4">Commander</a>`;
    document.body.appendChild(mobileMenu);
    if (window.lucide) lucide.createIcons();

    const close = () => mobileMenu.classList.remove('open');
    mobileMenu.querySelector('#menuClose').addEventListener('click', close);
    mobileMenu.querySelectorAll('a').forEach(a => a.addEventListener('click', close));
  };
  if (navToggle) {
    navToggle.addEventListener('click', () => {
      if (!mobileMenu) buildMobileMenu();
      requestAnimationFrame(() => mobileMenu.classList.add('open'));
    });
  }

  /* =======================================================
     GSAP — hero parallax + scroll reveals
     ======================================================= */
  if (window.gsap) {
    gsap.registerPlugin(ScrollTrigger);

    // Gentle parallax on the hero product as the user scrolls
    const heroPot = document.getElementById('heroPot');
    if (heroPot) {
      gsap.to(heroPot, {
        yPercent: 8,
        ease: 'none',
        scrollTrigger: { trigger: '#hero', start: 'top top', end: 'bottom top', scrub: true },
      });
    }

    // Staggered pop-in for the showcase feature chips
    const chips = gsap.utils.toArray('.feature-chip');
    if (chips.length) {
      gsap.from(chips, {
        opacity: 0, y: 24, scale: 0.9, duration: 0.5, ease: 'back.out(1.6)', stagger: 0.1,
        scrollTrigger: { trigger: '#showcase', start: 'top 70%' },
      });
    }

    // Subtle scale-reveal for the large image frames
    gsap.utils.toArray('.proof-frame, .salon-frame').forEach((el) => {
      gsap.from(el, {
        opacity: 0, scale: 0.94, duration: 0.7, ease: 'power3.out',
        scrollTrigger: { trigger: el, start: 'top 82%' },
      });
    });
  }

  /* =======================================================
     COUNTERS — animate numbers when in view
     ======================================================= */
  const counters = document.querySelectorAll('.counter');
  const runCounter = (el) => {
    const target = +el.dataset.target;
    const duration = 1600;
    const start = performance.now();
    const step = (now) => {
      const p = Math.min((now - start) / duration, 1);
      const eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
      el.textContent = Math.round(eased * target).toLocaleString('fr-FR');
      if (p < 1) requestAnimationFrame(step);
    };
    requestAnimationFrame(step);
  };
  if (counters.length) {
    const counterObserver = new IntersectionObserver((entries, obs) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          runCounter(entry.target);
          obs.unobserve(entry.target);
        }
      });
    }, { threshold: 0.5 });
    counters.forEach(c => counterObserver.observe(c));
  }

  /* =======================================================
     TESTIMONIALS — Swiper auto slider
     ======================================================= */
  if (window.Swiper) {
    // Mobile-only layout (480px column): keep one full-width card so the
    // review text stays readable. No window-based breakpoints — the column
    // width never changes, only the browser window does.
    new Swiper('.testimonial-swiper', {
      slidesPerView: 1,
      spaceBetween: 16,
      loop: true,
      grabCursor: true,
      autoHeight: true,
      autoplay: { delay: 4200, disableOnInteraction: false },
      pagination: { el: '.testimonial-swiper .swiper-pagination', clickable: true },
    });

    // Image gallery carousel — slight peek of the next slide, fixed for the column.
    if (document.querySelector('.gallery-swiper')) {
      new Swiper('.gallery-swiper', {
        slidesPerView: 1.15,
        spaceBetween: 14,
        centeredSlides: false,
        loop: true,
        grabCursor: true,
        autoplay: { delay: 3000, disableOnInteraction: false },
        pagination: { el: '.gallery-pagination', clickable: true },
      });
    }
  }

  /* =======================================================
     BEFORE / AFTER — interactive comparison slider
     ======================================================= */
  const baRange = document.getElementById('baRange');
  const baWrap = document.getElementById('baBeforeWrap');
  const baHandle = document.getElementById('baHandle');
  if (baRange && baWrap && baHandle) {
    const updateBA = (val) => {
      baWrap.style.clipPath = `inset(0 ${100 - val}% 0 0)`;
      baHandle.style.left = `${val}%`;
    };
    baRange.addEventListener('input', (e) => updateBA(+e.target.value));
    updateBA(50);
  }

  /* =======================================================
     FAQ accordion
     ======================================================= */
  const faqItems = document.querySelectorAll('.faq-item');
  faqItems.forEach(item => {
    const btn = item.querySelector('.faq-q');
    const ans = item.querySelector('.faq-a');
    btn.addEventListener('click', () => {
      const isOpen = item.classList.contains('open');
      // close all
      faqItems.forEach(other => {
        other.classList.remove('open');
        other.querySelector('.faq-q').setAttribute('aria-expanded', 'false');
        other.querySelector('.faq-a').style.maxHeight = null;
      });
      // open clicked (if it was closed)
      if (!isOpen) {
        item.classList.add('open');
        btn.setAttribute('aria-expanded', 'true');
        ans.style.maxHeight = ans.scrollHeight + 'px';
      }
    });
  });

  /* =======================================================
     ORDER FORM — quantity, summary & validation
     ======================================================= */
  const UNIT_PRICE = 230000;
  // Google Sheet Web App endpoint (Apps Script). Orders are appended as rows.
  const SHEET_ENDPOINT = 'https://script.google.com/macros/s/AKfycbxgtR6WFfUvpRTJQKysQbxcHgHd77aJ_DVzW6XBEn6G7uKTtmY2rjdgK2gY0Xc703ShJw/exec';

  // --- Meta Pixel helpers ---
  const getCookie = (name) => {
    const m = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
    return m ? m.pop() : '';
  };
  const fbTrack = (event, data, opts) => {
    if (typeof window.fbq === 'function') window.fbq('track', event, data, opts);
  };
  const qtyBtns = document.querySelectorAll('.qty-btn');
  const quantityInput = document.getElementById('quantity');
  const sumQty = document.getElementById('sumQty');
  const sumTotal = document.getElementById('sumTotal');

  const formatGNF = (n) => n.toLocaleString('fr-FR') + ' GNF';

  const updateSummary = () => {
    const q = +quantityInput.value;
    if (sumQty) sumQty.textContent = q + (q > 1 ? ' pots' : ' pot');
    if (sumTotal) sumTotal.textContent = formatGNF(q * UNIT_PRICE);
  };

  qtyBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      qtyBtns.forEach(b => b.classList.remove('is-active'));
      btn.classList.add('is-active');
      quantityInput.value = btn.dataset.qty;
      updateSummary();
    });
  });
  updateSummary();

  // --- Validation helpers ---
  const form = document.getElementById('orderForm');

  const setError = (field, msg) => {
    field.classList.add('invalid');
    const small = field.querySelector('.error-msg');
    if (small) small.textContent = msg;
  };
  const clearError = (field) => {
    field.classList.remove('invalid');
    const small = field.querySelector('.error-msg');
    if (small) small.textContent = '';
  };

  const validators = {
    fullname: (v) => v.trim().length >= 3 || 'Veuillez entrer votre nom complet.',
    phone: (v) => /^[+]?[\d\s().-]{8,15}$/.test(v.trim()) || 'Numéro de téléphone invalide.',
    address: (v) => v.trim().length >= 4 || 'Veuillez préciser votre adresse complète.',
  };

  const validateField = (input) => {
    const rule = validators[input.name];
    if (!rule) return true;
    const result = rule(input.value);
    const field = input.closest('.field');
    if (result === true) { clearError(field); return true; }
    setError(field, result);
    return false;
  };

  if (form) {
    // live-clear errors as the user types
    form.querySelectorAll('input, textarea').forEach(input => {
      input.addEventListener('input', () => {
        if (input.closest('.field').classList.contains('invalid')) validateField(input);
      });
    });

    form.addEventListener('submit', (e) => {
      e.preventDefault();
      let valid = true;
      let firstInvalid = null;

      Object.keys(validators).forEach(name => {
        const input = form.elements[name];
        if (!validateField(input)) {
          valid = false;
          if (!firstInvalid) firstInvalid = input;
        }
      });

      if (!valid) {
        firstInvalid && firstInvalid.focus();
        return;
      }

      // ---- Build the payload expected by the Google Apps Script (cols B–F) ----
      const quantity = +form.elements.quantity.value;
      const orderTotal = quantity * UNIT_PRICE;

      // Unique id shared by the browser Pixel event and the server CAPI event,
      // so Meta deduplicates the two into a single Purchase.
      const eventId = 'samyth_' + Date.now() + '_' + Math.random().toString(36).slice(2, 9);

      const payload = {
        Customer_Name: form.elements.fullname.value.trim(),
        Phone: form.elements.phone.value.trim(),
        address: form.elements.address.value.trim(),
        Quantity: quantity,
        total_price: orderTotal,
        // --- Meta Conversions API fields (read by the Apps Script, ignored by the sheet) ---
        event_id: eventId,
        event_source_url: window.location.href,
        fbp: getCookie('_fbp'),
        fbc: getCookie('_fbc'),
        user_agent: navigator.userAgent,
      };

      // Product details reused across the Pixel events.
      const fbContents = [{ id: 'samyth-cream', quantity: quantity, item_price: UNIT_PRICE }];

      // Funnel signal: the shopper pressed "Commander".
      fbTrack('InitiateCheckout', {
        content_name: 'SAMYTH Crème Capillaire Protéinée',
        content_ids: ['samyth-cream'],
        content_type: 'product',
        contents: fbContents,
        num_items: quantity,
        currency: 'GNF',
        value: orderTotal,
      });

      // Loading state on the submit button
      const submitBtn = form.querySelector('button[type="submit"]');
      const submitHtml = submitBtn.innerHTML;
      submitBtn.disabled = true;
      submitBtn.innerHTML = '<span class="btn-spinner"></span> Envoi en cours…';

      const resetForm = () => {
        form.reset();
        qtyBtns.forEach(b => b.classList.remove('is-active'));
        qtyBtns[0].classList.add('is-active');
        quantityInput.value = 1;
        updateSummary();
      };

      // Apps Script Web Apps don't return CORS headers. Sending the JSON as
      // text/plain keeps this a "simple" request (no preflight), and no-cors
      // lets it go through. The response is opaque, so a resolved fetch means
      // the order was submitted to the sheet.
      fetch(SHEET_ENDPOINT, {
        method: 'POST',
        mode: 'no-cors',
        headers: { 'Content-Type': 'text/plain;charset=utf-8' },
        body: JSON.stringify(payload),
      })
        .then(() => {
          // Conversion: browser-side Purchase (deduplicated with the server
          // CAPI event via the shared eventID).
          fbTrack('Purchase', {
            content_name: 'SAMYTH Crème Capillaire Protéinée',
            content_ids: ['samyth-cream'],
            content_type: 'product',
            contents: fbContents,
            num_items: quantity,
            currency: 'GNF',
            value: orderTotal,
          }, { eventID: eventId });
          openModal();
          resetForm();
        })
        .catch(() => {
          alert("Une erreur s'est produite lors de l'envoi de votre commande. Vérifiez votre connexion internet et réessayez.");
        })
        .finally(() => {
          submitBtn.disabled = false;
          submitBtn.innerHTML = submitHtml;
        });
    });
  }

  /* =======================================================
     SUCCESS MODAL
     ======================================================= */
  const modal = document.getElementById('successModal');
  const openModal = () => {
    modal.classList.add('show');
    modal.setAttribute('aria-hidden', 'false');
    document.body.style.overflow = 'hidden';
  };
  const closeModal = () => {
    modal.classList.remove('show');
    modal.setAttribute('aria-hidden', 'true');
    document.body.style.overflow = '';
  };
  if (modal) {
    document.getElementById('modalClose').addEventListener('click', closeModal);
    document.getElementById('modalOk').addEventListener('click', closeModal);
    modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
    document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeModal(); });
  }

  /* =======================================================
     Smooth-scroll for in-page anchors (offset for navbar)
     ======================================================= */
  document.querySelectorAll('a[href^="#"]').forEach(link => {
    link.addEventListener('click', (e) => {
      const id = link.getAttribute('href');
      if (id.length <= 1) return;
      const target = document.querySelector(id);
      if (!target) return;
      e.preventDefault();
      const top = target.getBoundingClientRect().top + window.scrollY - 70;
      window.scrollTo({ top, behavior: 'smooth' });
    });
  });

});
