/* ============================================
   CLUB JEN — main.js
   Particles · Reveal · Form Validation
   ============================================ */

'use strict';

/* ─────────────────────────────────────────────
   1. PARTICLE SYSTEM
   Floating gold/purple/pink sparkles
───────────────────────────────────────────── */
(function initParticles() {
  const canvas = document.getElementById('particles');
  if (!canvas) return;

  const ctx = canvas.getContext('2d');
  let W, H, particles;

  const COLORS = [
    'rgba(212,175,55,',   // gold
    'rgba(255,215,0,',    // bright gold
    'rgba(123,31,162,',   // purple
    'rgba(255,0,110,',    // pink
    'rgba(0,212,255,',    // blue
  ];
  const COUNT = window.innerWidth < 600 ? 45 : 80;

  class Particle {
    constructor() { this.reset(true); }

    reset(init = false) {
      this.x     = Math.random() * W;
      this.y     = init ? Math.random() * H : H + 10;
      this.size  = Math.random() * 2.2 + 0.4;
      this.speed = Math.random() * 0.5 + 0.15;
      this.drift = (Math.random() - 0.5) * 0.3;
      this.color = COLORS[Math.floor(Math.random() * COLORS.length)];
      this.alpha = Math.random() * 0.6 + 0.2;
      this.fade  = Math.random() * 0.006 + 0.002;
      this.dir   = Math.random() > 0.5 ? 1 : -1;
      this.twinkleSpeed = Math.random() * 0.03 + 0.01;
      this.twinklePhase = Math.random() * Math.PI * 2;
    }

    update(t) {
      this.y -= this.speed;
      this.x += this.drift;
      this.twinklePhase += this.twinkleSpeed;
      this.alpha = (Math.sin(this.twinklePhase) * 0.3 + 0.5) * 0.7;
      if (this.y < -10) this.reset(false);
    }

    draw() {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
      ctx.fillStyle = this.color + this.alpha.toFixed(2) + ')';
      ctx.fill();
    }
  }

  function resize() {
    W = canvas.width  = window.innerWidth;
    H = canvas.height = window.innerHeight;
  }

  function initPool() {
    particles = Array.from({ length: COUNT }, () => new Particle());
  }

  let raf;
  function loop(t) {
    ctx.clearRect(0, 0, W, H);
    particles.forEach(p => { p.update(t); p.draw(); });
    raf = requestAnimationFrame(loop);
  }

  resize();
  initPool();
  loop(0);

  window.addEventListener('resize', () => {
    resize();
    initPool();
  });
})();


/* ─────────────────────────────────────────────
   2. SCROLL REVEAL
   IntersectionObserver — fade in elements
───────────────────────────────────────────── */
(function initReveal() {
  const els = document.querySelectorAll('.reveal');
  if (!els.length) return;

  // Trigger immediately for elements already in view
  const io = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('visible');
        io.unobserve(entry.target);
      }
    });
  }, { threshold: 0.12 });

  els.forEach(el => io.observe(el));
})();


/* ─────────────────────────────────────────────
   3. SMOOTH SCROLL (for any in-page anchors)
───────────────────────────────────────────── */
document.querySelectorAll('a[href^="#"]').forEach(link => {
  link.addEventListener('click', function (e) {
    const target = document.querySelector(this.getAttribute('href'));
    if (target) {
      e.preventDefault();
      target.scrollIntoView({ behavior: 'smooth' });
    }
  });
});


/* ─────────────────────────────────────────────
   4. RSVP FORM VALIDATION & SUBMISSION
   Pure-JS validation — hook into Django POST
───────────────────────────────────────────── */
(function initForm() {
  const form    = document.getElementById('rsvp-form');
  if (!form) return;

  const wrapper = document.getElementById('form-wrapper');
  const rsvpHeader = document.getElementById('rsvp-header');
  const success = document.getElementById('success-state');
  const nameEl  = document.getElementById('success-name');

  /* --- helpers --- */
  function getField(id) { return document.getElementById(id); }
  function getError(id) { return document.getElementById('err-' + id); }

  function showError(id, msg) {
    const input = getField(id);
    const err   = getError(id);
    if (input) input.classList.add('error');
    if (err)   err.textContent = msg;
    return false;
  }

  function clearError(id) {
    const input = getField(id);
    const err   = getError(id);
    if (input) input.classList.remove('error');
    if (err)   err.textContent = '';
  }

  function clearAll() {
    ['first_name','last_name','email','whatsapp'].forEach(clearError);
  }

  /* --- live clear on input --- */
  ['first_name','last_name','email','whatsapp'].forEach(id => {
    const el = getField(id);
    if (el) el.addEventListener('input', () => clearError(id));
  });

  /* --- validation --- */
  function validate() {
    let valid = true;
    clearAll();

    const first   = getField('first_name').value.trim();
    const last    = getField('last_name').value.trim();
    const email   = getField('email').value.trim();
    const phone   = getField('whatsapp').value.trim();

    if (!first)               { showError('first_name', 'First name is required.');  valid = false; }
    if (!last)                { showError('last_name',  'Last name is required.');   valid = false; }

    if (!email) {
      showError('email', 'Email address is required.');
      valid = false;
    } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      showError('email', 'Please enter a valid email address.');
      valid = false;
    }

    if (!phone) {
      showError('whatsapp', 'WhatsApp number is required.');
      valid = false;
    } else if (!/^\d{5,15}$/.test(phone.replace(/[\s\-]/g, ''))) {
      showError('whatsapp', 'Please enter a valid phone number (5-15 digits).');
      valid = false;
    }

    return { valid, first, last, email, phone };
  }

  /* --- submission --- */
  form.addEventListener('submit', async function (e) {
    e.preventDefault();

    const { valid, first, last, email, phone } = validate();
    if (!valid) return;

    const submitBtn = form.querySelector('[type="submit"]');
    const btnText   = submitBtn.querySelector('.btn__text');

    // Loading state
    submitBtn.disabled  = true;
    btnText.textContent = 'Confirming…';

    try {
      // Get CSRF token from the form's hidden input
      const csrfToken = form.querySelector('[name="csrfmiddlewaretoken"]').value;

      // Get country code and phone number, combine them
      const countryCode = form.querySelector('[name="country_code"]').value;
      const phoneNumber = form.querySelector('#whatsapp').value.trim();
      const fullPhone = countryCode + phoneNumber;

      // Create FormData and map whatsapp to phone for the backend
      const formData = new FormData(form);
      formData.set('phone', fullPhone);

      const res = await fetch(form.action, {
        method: 'POST',
        headers: { 'X-CSRFToken': csrfToken },
        body: formData,
      });

      // Check content type before parsing as JSON
      const contentType = res.headers.get('content-type');
      if (!contentType || !contentType.includes('application/json')) {
        // If not JSON, something went wrong - could be 403, 500, etc.
        if (!res.ok) {
          throw new Error(`Server error: ${res.status}`);
        }
        throw new Error('Invalid response from server');
      }

      const data = await res.json();

      if (!res.ok) {
        throw new Error(data.message || 'Server error');
      }

      // Show success
      showSuccess(first);

    } catch (err) {
      console.error('RSVP error:', err);
      
      // Show error message
      if (err.message && err.message !== 'Server error') {
        alert(err.message);
      } else {
        alert('Something went wrong. Please try again.');
      }
      
      btnText.textContent = 'Try Again';
      submitBtn.disabled  = false;
    }
  });

  function showSuccess(firstName) {
    if (nameEl) nameEl.textContent = firstName;

    // Fade out form, reveal success (with null checks)
    if (wrapper) {
      wrapper.style.transition = 'opacity 0.45s ease, transform 0.45s ease';
      wrapper.style.opacity    = '0';
      wrapper.style.transform  = 'scale(0.96)';
    }

    setTimeout(() => {
      if (wrapper) wrapper.classList.add('hidden');
      if (rsvpHeader) rsvpHeader.classList.add('hidden');
      if (success) {
        success.classList.remove('hidden');
        success.scrollIntoView({ behavior: 'smooth', block: 'center' });
      }
      launchConfetti();
    }, 500);
  }

  /* --- micro confetti burst --- */
  function launchConfetti() {
    const canvas  = document.getElementById('particles');
    if (!canvas) return;
    // Trigger a quick gold burst by temporarily boosting particle count
    // (the particle system will naturally handle this via the existing canvas)
    // For a richer effect, you could use a dedicated confetti library.
    const burstColors = ['#D4AF37','#FFD700','#FF006E','#00D4FF','#7B1FA2'];

    for (let i = 0; i < 60; i++) {
      setTimeout(() => {
        const el = document.createElement('div');
        el.style.cssText = `
          position:fixed;
          left:${Math.random()*100}vw;
          top:-10px;
          width:${Math.random()*8+4}px;
          height:${Math.random()*8+4}px;
          border-radius:${Math.random() > 0.5 ? '50%' : '2px'};
          background:${burstColors[Math.floor(Math.random()*burstColors.length)]};
          pointer-events:none;
          z-index:9999;
          animation: confettiFall ${Math.random()*2+1.5}s ease-in forwards;
        `;
        document.body.appendChild(el);
        setTimeout(() => el.remove(), 3600);
      }, Math.random() * 600);
    }

    // Inject keyframes once
    if (!document.getElementById('confetti-style')) {
      const s = document.createElement('style');
      s.id = 'confetti-style';
      s.textContent = `
        @keyframes confettiFall {
          0%   { transform: translateY(0) rotate(0deg); opacity:1; }
          100% { transform: translateY(105vh) rotate(${Math.random()*720}deg); opacity:0; }
        }
      `;
      document.head.appendChild(s);
    }
  }
})();


/* ─────────────────────────────────────────────
   5. BUTTON RIPPLE EFFECT
───────────────────────────────────────────── */
document.querySelectorAll('.btn').forEach(btn => {
  btn.addEventListener('pointerdown', function (e) {
    const rect   = btn.getBoundingClientRect();
    const ripple = document.createElement('span');
    const size   = Math.max(rect.width, rect.height) * 1.5;
    ripple.style.cssText = `
      position:absolute;
      border-radius:50%;
      width:${size}px;
      height:${size}px;
      left:${e.clientX - rect.left - size/2}px;
      top:${e.clientY  - rect.top  - size/2}px;
      background:rgba(255,255,255,0.18);
      transform:scale(0);
      animation:rippleOut 0.55s ease-out forwards;
      pointer-events:none;
    `;
    if (!document.getElementById('ripple-style')) {
      const s = document.createElement('style');
      s.id = 'ripple-style';
      s.textContent = '@keyframes rippleOut{to{transform:scale(1);opacity:0;}}';
      document.head.appendChild(s);
    }
    btn.appendChild(ripple);
    setTimeout(() => ripple.remove(), 600);
  });
});
