window.sketch = (p) => {
  let buildings = [];
  let embers = [];
  let explosions = [];
  let smokeParticles = [];
  let heatDistortion = [];
  const BUILDING_COUNT = 15;
  const EMBER_COUNT = 100;
  const SMOKE_COUNT = 50;
  const EXPLOSION_FREQUENCY = 120; // frames

  p.setup = () => {
    p.createCanvas(p.windowWidth, p.windowHeight);
    p.noiseSeed(42);
    p.colorMode(p.HSB, 360, 100, 100, 1.0);

    // Initialize buildings
    for (let i = 0; i < BUILDING_COUNT; i++) {
      buildings.push({
        x: p.random(p.width),
        width: p.random(30, 100),
        height: p.random(100, p.height * 0.8),
        baseHeight: p.random(100, p.height * 0.8),
        fireIntensity: p.random(0.3, 1.0),
        fireOffset: p.random(1000),
        shattered: p.random() > 0.7,
        moltenStreams: [],
        collapseProgress: 0,
        isCollapsing: p.random() > 0.8
      });

      // Add molten streams to some buildings
      if (buildings[i].shattered && p.random() > 0.5) {
        const streamCount = p.floor(p.random(1, 4));
        for (let j = 0; j < streamCount; j++) {
          buildings[i].moltenStreams.push({
            x: buildings[i].x + p.random(-10, buildings[i].width + 10),
            y: p.random(50, buildings[i].height * 0.3),
            length: p.random(50, buildings[i].height * 0.7),
            speed: p.random(1, 3),
            width: p.random(2, 8),
            offset: p.random(1000)
          });
        }
      }
    }

    // Initialize embers
    for (let i = 0; i < EMBER_COUNT; i++) {
      embers.push({
        x: p.random(p.width),
        y: p.random(p.height * 0.3, p.height * 0.7),
        size: p.random(2, 8),
        speedY: p.random(-1, -3),
        speedX: p.random(-1, 1),
        life: p.random(100, 300),
        maxLife: p.random(100, 300),
        hue: p.random(0, 30),
        brightness: p.random(80, 100),
        offset: p.random(1000)
      });
    }

    // Initialize smoke particles
    for (let i = 0; i < SMOKE_COUNT; i++) {
      smokeParticles.push({
        x: p.random(p.width),
        y: p.random(p.height * 0.1, p.height * 0.4),
        size: p.random(10, 40),
        speedY: p.random(-0.5, -1.5),
        speedX: p.random(-0.5, 0.5),
        alpha: p.random(0.1, 0.4),
        offset: p.random(1000)
      });
    }

    // Initialize heat distortion grid
    for (let i = 0; i < 20; i++) {
      heatDistortion.push({
        x: p.random(p.width),
        y: p.random(p.height),
        size: p.random(50, 150),
        speed: p.random(0.1, 0.5),
        offset: p.random(1000),
        direction: p.random() > 0.5 ? 1 : -1
      });
    }
  };

  p.windowResized = () => {
    p.resizeCanvas(p.windowWidth, p.windowHeight);
  };

  p.draw = () => {
    // Sky gradient (dark with red/orange tint)
    for (let y = 0; y < p.height; y++) {
      const inter = p.map(y, 0, p.height, 0, 1);
      const hue = p.map(inter, 0, 1, 0, 20);
      const sat = p.map(inter, 0, 1, 80, 40);
      const bright = p.map(inter, 0, 1, 10, 30);
      p.stroke(hue, sat, bright, 0.8);
      p.line(0, y, p.width, y);
    }

    // Draw heat distortion effect
    p.push();
    p.blendMode(p.SCREEN);
    p.noStroke();
    heatDistortion.forEach(distortion => {
      const noiseVal = p.noise(distortion.offset + p.frameCount * 0.01) * 2 * p.PI;
      distortion.x += p.cos(noiseVal) * distortion.speed * distortion.direction;
      distortion.y -= p.sin(noiseVal) * distortion.speed * 0.5;

      if (distortion.x < -distortion.size) distortion.x = p.width + distortion.size;
      if (distortion.x > p.width + distortion.size) distortion.x = -distortion.size;
      if (distortion.y < -distortion.size) distortion.y = p.height + distortion.size;

      const alpha = p.map(p.sin(p.frameCount * 0.05 + distortion.offset), -1, 1, 0, 0.3);
      p.fill(0, 0, 100, alpha);
      p.ellipse(distortion.x, distortion.y, distortion.size);
    });
    p.pop();

    // Draw smoke
    p.push();
    p.blendMode(p.MULTIPLY);
    smokeParticles.forEach(particle => {
      const noiseVal = p.noise(particle.offset + p.frameCount * 0.01) * 2 * p.PI;
      particle.x += p.cos(noiseVal) * particle.speedX * 2;
      particle.y += particle.speedY + p.sin(noiseVal) * 0.2;

      // Respawn if out of bounds
      if (particle.y < 0 || particle.x < 0 || particle.x > p.width) {
        particle.x = p.random(p.width);
        particle.y = p.height * 0.8;
        particle.size = p.random(10, 40);
        particle.alpha = p.random(0.1, 0.4);
      }

      p.noStroke();
      p.fill(0, 0, 0, particle.alpha);
      p.ellipse(particle.x, particle.y, particle.size);
    });
    p.pop();

    // Draw explosions in the distance
    if (p.frameCount % EXPLOSION_FREQUENCY === 0) {
      explosions.push({
        x: p.random(p.width * 0.1, p.width * 0.9),
        y: p.random(p.height * 0.4, p.height * 0.6),
        size: 0,
        maxSize: p.random(50, 150),
        hue: p.random(0, 30),
        life: 0,
        maxLife: 60
      });
    }

    explosions.forEach((explosion, index) => {
      explosion.life++;
      explosion.size = p.map(explosion.life, 0, explosion.maxLife, 0, explosion.maxSize);

      if (explosion.life > explosion.maxLife) {
        explosions.splice(index, 1);
        return;
      }

      p.push();
      p.blendMode(p.ADD);
      p.noStroke();
      const alpha = p.map(explosion.life, 0, explosion.maxLife, 0.8, 0);
      p.fill(explosion.hue, 100, 100, alpha);
      p.ellipse(explosion.x, explosion.y, explosion.size);

      // Inner glow
      p.fill(0, 0, 100, alpha * 0.5);
      p.ellipse(explosion.x, explosion.y, explosion.size * 0.6);
      p.pop();
    });

    // Draw buildings
    buildings.forEach(building => {
      // Building base (silhouette)
      p.push();
      p.noStroke();
      p.fill(0, 0, 20);
      p.rect(building.x, p.height - building.height, building.width, building.height);

      // Fire effect on building
      const fireHeight = building.height * building.fireIntensity * 0.8;
      const fireWidth = building.width * 1.2;

      p.blendMode(p.ADD);
      for (let y = 0; y < fireHeight; y += 5) {
        const noiseVal = p.noise(
          building.fireOffset + y * 0.01 + p.frameCount * 0.05,
          building.x * 0.01
        );
        const fireWidthAtY = p.map(noiseVal, 0, 1, fireWidth * 0.7, fireWidth * 1.3);
        const hue = p.map(y, 0, fireHeight, 0, 30);
        const sat = p.map(y, 0, fireHeight, 100, 80);
        const bright = p.map(y, 0, fireHeight, 100, 60);
        const alpha = p.map(y, 0, fireHeight, 0.8, 0);

        p.fill(hue, sat, bright, alpha);
        p.ellipse(
          building.x + building.width / 2,
          p.height - building.height + y,
          fireWidthAtY,
          5
        );
      }
      p.pop();

      // Molten streams
      if (building.moltenStreams.length > 0) {
        p.push();
        p.blendMode(p.ADD);
        building.moltenStreams.forEach(stream => {
          const noiseVal = p.noise(stream.offset + p.frameCount * 0.02);
          const wobble = p.map(noiseVal, 0, 1, -5, 5);

          p.noStroke();
          p.fill(10, 100, 100, 0.9);
          p.beginShape();
          p.vertex(stream.x + wobble, stream.y);
          p.vertex(stream.x + wobble + stream.width / 2, stream.y + stream.length / 2);
          p.vertex(stream.x + wobble, stream.y + stream.length);
          p.vertex(stream.x + wobble - stream.width / 2, stream.y + stream.length / 2);
          p.endShape(p.CLOSE);

          // Glow effect
          p.fill(0, 0, 100, 0.3);
          p.ellipse(stream.x + wobble, stream.y + stream.length / 2, stream.width * 2);
        });
        p.pop();
      }

      // Building collapse effect
      if (building.isCollapsing) {
        building.collapseProgress += 0.005;
        if (building.collapseProgress >= 1) {
          building.collapseProgress = 0;
          building.height = p.random(100, p.height * 0.8);
          building.x = p.random(p.width);
          building.width = p.random(30, 100);
        }

        const collapseHeight = building.baseHeight * (1 - building.collapseProgress);
        p.push();
        p.noStroke();
        p.fill(0, 0, 30);
        p.rect(
          building.x - building.width * building.collapseProgress * 0.5,
          p.height - collapseHeight,
          building.width * (1 + building.collapseProgress),
          collapseHeight
        );

        // Dust from collapse
        p.fill(0, 0, 50, 0.5);
        p.ellipse(
          building.x + building.width / 2,
          p.height - collapseHeight,
          building.width * (1 + building.collapseProgress * 2),
          20
        );
        p.pop();
      }
    });

    // Draw embers
    p.push();
    p.blendMode(p.ADD);
    embers.forEach(ember => {
      ember.life--;
      ember.y += ember.speedY;
      ember.x += ember.speedX + p.sin(p.frameCount * 0.1 + ember.offset) * 0.5;

      // Respawn if dead or out of bounds
      if (ember.life <= 0 || ember.y > p.height) {
        ember.x = p.random(p.width);
        ember.y = p.random(p.height * 0.3, p.height * 0.7);
        ember.life = ember.maxLife;
        ember.size = p.random(2, 8);
        ember.hue = p.random(0, 30);
      }

      const flicker = p.sin(p.frameCount * 0.2 + ember.offset) * 0.3 + 0.7;
      p.noStroke();
      p.fill(ember.hue, 100, ember.brightness * flicker, 0.9);
      p.ellipse(ember.x, ember.y, ember.size);

      // Trail
      p.fill(ember.hue, 100, ember.brightness * flicker * 0.5, 0.3);
      p.ellipse(ember.x, ember.y + ember.speedY * 2, ember.size * 1.5);
    });
    p.pop();

    // Ground glow from fire
    p.push();
    p.blendMode(p.ADD);
    p.noStroke();
    p.fill(10, 80, 80, 0.2);
    p.rect(0, p.height - 20, p.width, 20);
    p.pop();
  };
};
