// Deepavali Jyoti (Diwali) Effect for Seazonify Controller
const deepavaliEffect = {
    name: "Deepavali Jyoti",
    description: "A grand Diwali celebration with a row of realistic Diyas, falling marigold petals, golden bokeh, and a cinematic greeting.",
    icon: "🪔",
    type: "visual",
    author: "Md Mim Akhtar",
    thumbnail: "assets/effects/visual/thumbnails/deepavali-jyoti.webp",
    version: "1.2.0",
    license: "https://seazonify.com/license",
    created: "2026-01-25",
    category: "festive",
    tags: ["diwali", "deepavali", "lights", "fire", "lamp", "realistic", "marigold", "bokeh", "greeting"],
    css: `
    .szfy-diwali-container-v1-2-0 {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 9999;
      overflow: hidden;
      font-family: 'Cinzel', serif;
    }
    @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@700&display=swap');
    #szfy-diwali-canvas-v1-2-0 {
      width: 100%;
      height: 100%;
      display: block;
    }
    `,
    html: `
    <div class="szfy-diwali-container-v1-2-0" id="szfy-diwali-container-v1-2-0">
      <canvas id="szfy-diwali-canvas-v1-2-0"></canvas>
    </div>
    `,
    js: `
    (function() {
      if (typeof window.szfyDiwaliCleanup === 'function') {
          try { window.szfyDiwaliCleanup(); } catch(e) { console.error(e); }
      }
      
      const oldIDs = ['szfy-diwali-container-v1', 'szfy-diwali-container-v1-1', 'szfy-diwali-container-v1-1-0', 'szfy-diwali-container-v1-1-1'];
      oldIDs.forEach(id => {
         const old = document.getElementById(id);
         if (old) old.remove();
      });

      const container = document.getElementById('szfy-diwali-container-v1-2-0');
      const canvas = document.getElementById('szfy-diwali-canvas-v1-2-0');
      if (!container || !canvas) return;

      const ctx = canvas.getContext('2d', { alpha: true });
      let width, height;
      let animationId = null;
      let time = 0;
      let scaleFactor = 1;

      function resize() {
          width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
          height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
          if (!width) width = 1000;
          if (!height) height = 800;

          const dpr = Math.min(window.devicePixelRatio || 1, 2);
          canvas.width = width * dpr;
          canvas.height = height * dpr;
          ctx.setTransform(1, 0, 0, 1, 0, 0); 
          ctx.scale(dpr, dpr);
          
          scaleFactor = Math.min(width, height) / 1000;
          if(scaleFactor < 0.5) scaleFactor = 0.5;
          
          init();
      }
      window.addEventListener('resize', resize);
      
      // --- CLASSES ---

      class FlameParticle {
          constructor(x, y, scale) {
              this.originX = x;
              this.originY = y;
              this.x = x;
              this.y = y;
              this.life = 1.0;
              this.decay = 0.05 + Math.random() * 0.05; 
              this.radius = (3 + Math.random() * 4) * scale;
              const angle = -Math.PI/2 + (Math.random()-0.5) * 0.5;
              const speed = (0.5 + Math.random() * 1.5) * scale; 
              this.vx = Math.cos(angle) * speed;
              this.vy = Math.sin(angle) * speed;
          }
          update(windX) {
              this.x += this.vx + windX;
              this.y += this.vy;
              this.life -= this.decay;
              this.radius *= 0.92; 
              return this.life > 0;
          }
          draw() {
              const alpha = Math.max(0, this.life);
              let r, g, b;
              if (this.life > 0.7) { r = 255; g = 255; b = 150; } 
              else if (this.life > 0.4) { r = 255; g = 150; b = 0; } 
              else { r = 200; g = 50; b = 0; }
              ctx.beginPath();
              ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
              ctx.fillStyle = \`rgba(\${r},\${g},\${b},\${alpha})\`;
              ctx.fill();
          }
      }
      
      class Diya {
          constructor(x, y, scale) {
              this.x = x; 
              this.y = y;
              this.scale = scale; 
              this.particles = [];
              this.oilColor = '#FFD700';   
              this.flickerIntensity = 0;
          }
          update(mouseX) {
             const particlesPerFrame = 2; 
             for(let i=0; i<particlesPerFrame; i++) {
                 const wickX = this.x + (40 * this.scale); 
                 const wickY = this.y - (10 * this.scale);
                 this.particles.push(new FlameParticle(wickX, wickY, this.scale)); 
             }
             let wind = 0;
             if (mouseX) {
                 const dist = mouseX - this.x;
                 if (Math.abs(dist) < 200) {
                     wind = (dist > 0 ? -1 : 1) * (1 - Math.abs(dist)/200);
                 }
             }
             this.flickerIntensity += (Math.random()-0.5) * 0.1;
             this.flickerIntensity *= 0.9; 
             wind += this.flickerIntensity;
             for(let i=this.particles.length-1; i>=0; i--) {
                 const p = this.particles[i];
                 const alive = p.update(wind);
                 if(!alive) this.particles.splice(i, 1);
             }
          }
          draw() {
              const s = this.scale;
              // Glow
              const wickX = this.x + (40 * s); 
              const wickY = this.y - (10 * s);
              const glowRadius = 120 * s + (Math.random() * 10 * s);
              const grad = ctx.createRadialGradient(wickX, wickY, 5*s, wickX, wickY, glowRadius);
              grad.addColorStop(0, "rgba(255, 180, 50, 0.4)"); 
              grad.addColorStop(1, "rgba(255, 100, 0, 0)");
              ctx.globalCompositeOperation = 'screen';
              ctx.fillStyle = grad;
              ctx.beginPath();
              ctx.arc(wickX, wickY, glowRadius, 0, Math.PI*2);
              ctx.fill();
              ctx.globalCompositeOperation = 'source-over';
              // Body
              ctx.save();
              ctx.translate(this.x, this.y);
              ctx.scale(s, s);
              ctx.fillStyle = "rgba(0,0,0,0.3)";
              ctx.beginPath();
              ctx.ellipse(5, 25, 45, 15, 0, 0, Math.PI*2);
              ctx.fill();
              ctx.beginPath();
              ctx.moveTo(-40, 0);
              ctx.quadraticCurveTo(-40, 30, 0, 30); 
              ctx.quadraticCurveTo(40, 30, 60, -5); 
              ctx.quadraticCurveTo(40, 0, 0, 0); 
              ctx.quadraticCurveTo(-40, 0, -40, 0);
              ctx.closePath();
              const clayGrad = ctx.createLinearGradient(-40, -20, 40, 30);
              clayGrad.addColorStop(0, '#A0522D');
              clayGrad.addColorStop(1, '#5D2906');
              ctx.fillStyle = clayGrad;
              ctx.fill();
              ctx.beginPath();
              ctx.ellipse(0, 3, 30, 10, 0, 0, Math.PI*2);
              ctx.fillStyle = this.oilColor;
              ctx.fill();
              ctx.strokeStyle = "rgba(255,255,255,0.2)";
              ctx.lineWidth = 1;
              ctx.stroke();
              ctx.beginPath();
              ctx.moveTo(30, 3);
              ctx.lineTo(45, -5);
              ctx.strokeStyle = "#DDD";
              ctx.lineWidth = 3;
              ctx.stroke();
              ctx.restore();
              ctx.globalCompositeOperation = 'lighter'; 
              this.particles.forEach(p => p.draw());
              ctx.globalCompositeOperation = 'source-over';
          }
      }

      class MarigoldPetal {
          constructor() { this.reset(true); }
          reset(init) {
              this.x = Math.random() * width;
              this.y = init ? Math.random() * height : -50;
              this.size = (5 + Math.random() * 8) * scaleFactor;
              this.speedY = (0.5 + Math.random() * 1.5) * scaleFactor;
              this.speedX = (Math.random() - 0.5) * scaleFactor;
              this.rotation = Math.random() * Math.PI * 2;
              this.rotationSpeed = (Math.random() - 0.5) * 0.05;
              this.color = Math.random() > 0.5 ? '#FFA500' : '#FFD700'; 
              this.opacity = 0.8 + Math.random()*0.2;
          }
          update() {
              this.y += this.speedY;
              this.x += this.speedX + Math.sin(time * 0.01 + this.rotation) * 0.5;
              this.rotation += this.rotationSpeed;
              if (this.y > height + 20) this.reset();
          }
          draw() {
              ctx.save();
              ctx.translate(this.x, this.y);
              ctx.rotate(this.rotation);
              ctx.globalAlpha = this.opacity;
              ctx.fillStyle = this.color;
              ctx.beginPath();
              ctx.ellipse(0, 0, this.size, this.size * 0.6, 0, 0, Math.PI*2);
              ctx.fill();
              ctx.strokeStyle = "rgba(0,0,0,0.1)";
              ctx.lineWidth = 0.5;
              ctx.moveTo(-this.size, 0); ctx.lineTo(this.size, 0);
              ctx.stroke();
              ctx.restore();
          }
      }

      class Bokeh {
          constructor() { this.reset(); }
          reset() {
              this.x = Math.random() * width;
              this.y = height + Math.random() * 100;
              this.radius = Math.random() * 30 + 10;
              this.speed = 0.2 + Math.random() * 0.5;
              this.alpha = 0;
              this.targetAlpha = 0.05 + Math.random() * 0.15; 
              this.phase = "in";
          }
          update() {
              this.y -= this.speed;
              if (this.phase === "in") {
                  if (this.alpha < this.targetAlpha) this.alpha += 0.002;
                  else this.phase = "float";
              } else if (this.phase === "float") {
                  if (this.y < height * 0.4) this.phase = "out";
                  this.x += Math.sin(time * 0.01 + this.y) * 0.2;
              } else {
                  this.alpha -= 0.002;
                  if (this.alpha <= 0) this.reset();
              }
          }
          draw() {
              if (this.alpha <= 0) return;
              ctx.beginPath();
              ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
              ctx.fillStyle = \`rgba(255, 220, 150, \${this.alpha})\`;
              ctx.fill();
              ctx.beginPath();
              ctx.arc(this.x, this.y, this.radius * 0.7, 0, Math.PI*2);
              ctx.fillStyle = \`rgba(255, 255, 200, \${this.alpha * 0.5})\`;
              ctx.fill();
          }
      }

      // --- CINEMATIC GREETING ---
      class CinematicGreeting {
          constructor() {
              this.active = false;
              this.state = "idle"; // idle, in, hold, out
              this.timer = 0;
              // Timer for EVERY 3 MINUTES (60fps * 180s = 10800 frames)
              // But let's show one initially at frame 300 (5s) then repeats
              this.interval = 180 * 60; 
              this.nextTrigger = 300; 
              
              this.alpha = 0;
              this.blur = 20;
              this.scale = 0.8;
              this.shinePos = -0.5; // -0.5 to 1.5
              
              this.lightRaysRotation = 0;
          }
          
          update(globalTime) {
              this.lightRaysRotation += 0.005;
              
              if (!this.active) {
                  if (globalTime >= this.nextTrigger) {
                      this.start();
                  }
                  return;
              }
              
              if (this.state === "in") {
                  this.alpha += 0.02;
                  this.blur *= 0.95;
                  this.scale += (1 - this.scale) * 0.05;
                  if (this.alpha >= 1 && this.blur < 0.5) {
                      this.alpha = 1;
                      this.blur = 0;
                      this.state = "hold";
                      this.timer = 0;
                  }
              } else if (this.state === "hold") {
                  this.timer++;
                  // Shine wipe happens here
                  this.shinePos += 0.02;
                  if (this.timer > 300) { // Hold for 5s
                      this.state = "out";
                  }
              } else if (this.state === "out") {
                  this.alpha -= 0.02;
                  this.blur += 0.5;
                  this.scale += 0.005;
                  if (this.alpha <= 0) {
                      this.active = false;
                      this.nextTrigger = globalTime + this.interval;
                  }
              }
          }
          
          start() {
              this.active = true;
              this.state = "in";
              this.alpha = 0;
              this.blur = 20;
              this.scale = 0.8;
              this.shinePos = -0.5;
              this.timer = 0;
          }
          
          draw() {
              if (!this.active && this.alpha <= 0) return;
              
              const cx = width / 2;
              const cy = height / 2;
              
              ctx.save();
              ctx.translate(cx, cy);
              
              // 1. God Rays (Behind)
              if (this.alpha > 0.2) {
                  ctx.save();
                  ctx.globalAlpha = this.alpha * 0.3;
                  ctx.rotate(this.lightRaysRotation);
                  const rayCount = 12;
                  for(let i=0; i<rayCount; i++) {
                      ctx.rotate((Math.PI * 2) / rayCount);
                      ctx.beginPath();
                      ctx.moveTo(0, 0);
                      ctx.lineTo(100, -width); // Use width for length
                      ctx.lineTo(-100, -width);
                      ctx.closePath();
                      const grad = ctx.createLinearGradient(0, 0, 0, -width/2);
                      grad.addColorStop(0, "rgba(255, 215, 0, 0.5)"); // Gold
                      grad.addColorStop(1, "rgba(255, 215, 0, 0)");
                      ctx.fillStyle = grad;
                      ctx.fill();
                  }
                  ctx.restore();
              }
              
              // 2. Text
              ctx.scale(this.scale, this.scale);
              ctx.textAlign = "center";
              ctx.textBaseline = "middle";
              
              // Font size responsive
              const fontSize = Math.min(width * 0.08, 80);
              ctx.font = "700 " + fontSize + "px 'Cinzel', serif";
              
              // We need masking for the shine effect
              // Easier to just clip text
              ctx.globalAlpha = this.alpha;
              
              // Shadow/Glow
              ctx.shadowColor = "rgba(255, 140, 0, 0.8)";
              ctx.shadowBlur = 20 * (1 - this.blur/20); // Sharpens as it focuses
              
              // Base Gold Text
              // Simulate filter blur manually if ctx.filter not supported (safari old compatibility)
              // But most allow it. Let's try native blur for performance
              if (this.blur > 1) {
                  // Hacky blur: draw multiple offsets? No, just opacity fade is okay for fallback
                  // If browser supports filter:
                  if (ctx.filter) ctx.filter = "blur(" + this.blur + "px)";
              }
              
              ctx.fillStyle = "#FFC800"; // Deep Gold
              ctx.fillText("Happy Deepavali", 0, 0);
              ctx.shadowBlur = 0;
              if (ctx.filter) ctx.filter = "none";
              
              // 3. Shine Wipe (Overlay)
              // We use composite operation 'source-atop' to draw ONLY on the text we just drew?
              // Standard canvas doesn't layer text easily without offscreen buffer.
              // Simpler: Draw text again in white with gradient, masked by position
              
              ctx.globalCompositeOperation = "source-atop";
              const shineWidth = width * 0.3;
              const shineX = (this.shinePos * width) - (width/2); // Relative to center
              
              const grad = ctx.createLinearGradient(shineX - shineWidth/2, 0, shineX + shineWidth/2, 0);
              grad.addColorStop(0, "rgba(255,255,255,0)");
              grad.addColorStop(0.5, "rgba(255,255,255,0.8)"); // Bright shine
              grad.addColorStop(1, "rgba(255,255,255,0)");
              
              ctx.fillStyle = grad;
              ctx.fillText("Happy Deepavali", 0, 0);
              
              ctx.restore();
              ctx.globalCompositeOperation = "source-over"; // Reset
          }
      }

      let diyas = [];
      let petals = [];
      let bokehs = [];
      let greeting;
      let mouseX = 0;
      
      function init() {
          diyas = [];
          petals = [];
          bokehs = [];
          greeting = new CinematicGreeting();
          
          let maxDiyas;
          let diyaBaseScale;
          
          if (width < 600) { 
              maxDiyas = 3;
              diyaBaseScale = 0.7; 
          } else if (width < 1024) { 
              maxDiyas = 6;
              diyaBaseScale = 0.9;
          } else { 
              maxDiyas = 10;
              diyaBaseScale = 1.0;
          }
          
          const finalScale = diyaBaseScale * scaleFactor;
          const padding = 50 * scaleFactor;
          const availableWidth = width - (padding * 2);
          const step = availableWidth / (maxDiyas + 1); 
          const yPos = height - (80 * finalScale);
          
          for(let i=1; i<=maxDiyas; i++) {
              const xPos = padding + (step * i);
              const yOff = (i % 2 === 0) ? -10 * scaleFactor : 10 * scaleFactor; 
              diyas.push(new Diya(xPos, yPos + yOff, finalScale));
          }
          
          const petalCount = width > 1000 ? 25 : 12; 
          for(let i=0; i<petalCount; i++) petals.push(new MarigoldPetal());
          
          const bokehCount = width > 1000 ? 30 : 15;
          for(let i=0; i<bokehCount; i++) bokehs.push(new Bokeh());
      }

      function animateFrame() {
          time++;
          ctx.clearRect(0, 0, width, height);
          
          if (diyas.length === 0) init();
          
          bokehs.forEach(b => { b.update(); b.draw(); });
          
          for(let i=0; i<petals.length/2; i++) {
              petals[i].update();
              petals[i].draw();
          }

          diyas.forEach(d => {
              d.update(mouseX);
              d.draw();
          });
          
           for(let i=Math.ceil(petals.length/2); i<petals.length; i++) {
              petals[i].update();
              petals[i].draw();
          }
          
          // Greeting on top
          if(greeting) {
              greeting.update(time);
              greeting.draw();
          }

          animationId = requestAnimationFrame(animateFrame);
      }
      
      resize();
      animateFrame();
      
      window.addEventListener('mousemove', (e) => {
          mouseX = e.clientX;
      });

      window.szfyDiwaliCleanup = function() {
          if (animationId) cancelAnimationFrame(animationId);
          window.removeEventListener('resize', resize);
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          if (container) container.remove();
      };
    })();
    `
};

if (typeof window !== 'undefined' && window.SeazonifyController) {
    window.SeazonifyController.injectVisualEffect(deepavaliEffect);
}
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { visual: deepavaliEffect };
}