// Texture generation and overlay module
// Adds film grain, noise, and other texture effects for realism

class TextureManager {
  constructor() {
    this.textureCache = new Map();
  }

  // Generate film grain texture
  generateFilmGrain(ctx, width, height, opacity = 0.02) {
    ctx.save();
    ctx.globalAlpha = opacity;

    // Random noise pixels
    const grainDensity = width * height * 0.01; // 1% coverage
    for (let i = 0; i < grainDensity; i++) {
      const x = Math.random() * width;
      const y = Math.random() * height;
      const brightness = Math.random() > 0.5 ? 255 : 0;
      ctx.fillStyle = `rgb(${brightness}, ${brightness}, ${brightness})`;
      ctx.fillRect(x, y, 1, 1);
    }

    ctx.restore();
  }

  // Generate noise texture overlay
  generateNoiseTexture(ctx, width, height, scale = 1, opacity = 0.03) {
    ctx.save();
    ctx.globalAlpha = opacity;

    const noiseSize = Math.max(2, scale);
    for (let x = 0; x < width; x += noiseSize) {
      for (let y = 0; y < height; y += noiseSize) {
        if (Math.random() > 0.7) { // 30% coverage
          const brightness = Math.floor(Math.random() * 50);
          ctx.fillStyle = `rgb(${brightness}, ${brightness}, ${brightness})`;
          ctx.fillRect(x, y, noiseSize, noiseSize);
        }
      }
    }

    ctx.restore();
  }

  // Apply light leaks at edges
  applyLightLeaks(ctx, width, height, color, opacity = 0.15) {
    ctx.save();

    // Random edge selection
    const edges = ['top', 'bottom', 'left', 'right'];
    const selectedEdge = edges[Math.floor(Math.random() * edges.length)];

    const hexToRgba = (hex, alpha) => {
      const r = parseInt(hex.slice(1, 3), 16);
      const g = parseInt(hex.slice(3, 5), 16);
      const b = parseInt(hex.slice(5, 7), 16);
      return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    };

    let gradient;
    switch (selectedEdge) {
      case 'top':
        gradient = ctx.createLinearGradient(0, 0, 0, height * 0.3);
        gradient.addColorStop(0, hexToRgba(color, opacity));
        gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
        break;
      case 'bottom':
        gradient = ctx.createLinearGradient(0, height, 0, height * 0.7);
        gradient.addColorStop(0, hexToRgba(color, opacity));
        gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
        break;
      case 'left':
        gradient = ctx.createLinearGradient(0, 0, width * 0.3, 0);
        gradient.addColorStop(0, hexToRgba(color, opacity));
        gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
        break;
      case 'right':
        gradient = ctx.createLinearGradient(width, 0, width * 0.7, 0);
        gradient.addColorStop(0, hexToRgba(color, opacity));
        gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
        break;
    }

    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    ctx.restore();
  }

  // Apply scan lines for tech feel
  applyScanLines(ctx, width, height, opacity = 0.02) {
    ctx.save();
    ctx.globalAlpha = opacity;
    ctx.strokeStyle = '#FFFFFF';
    ctx.lineWidth = 1;

    for (let y = 0; y < height; y += 4) {
      ctx.beginPath();
      ctx.moveTo(0, y);
      ctx.lineTo(width, y);
      ctx.stroke();
    }

    ctx.restore();
  }

  // Apply subtle scratches/dust
  applyScratches(ctx, width, height, count = 5, opacity = 0.1) {
    ctx.save();
    ctx.globalAlpha = opacity;
    ctx.strokeStyle = '#FFFFFF';
    ctx.lineWidth = 1;

    for (let i = 0; i < count; i++) {
      const x1 = Math.random() * width;
      const y1 = Math.random() * height;
      const x2 = x1 + (Math.random() - 0.5) * 100;
      const y2 = y1 + (Math.random() - 0.5) * 100;

      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.stroke();
    }

    ctx.restore();
  }

  // Apply all textures (randomized combination)
  applyTextureOverlay(ctx, width, height, colorScheme) {
    // Always apply subtle film grain
    this.generateFilmGrain(ctx, width, height, 0.015);

    // 70% chance for noise texture
    if (Math.random() > 0.3) {
      this.generateNoiseTexture(ctx, width, height, 2, 0.02);
    }

    // 50% chance for light leaks
    if (Math.random() > 0.5) {
      const leakColor = colorScheme.accent || '#FFFFFF';
      this.applyLightLeaks(ctx, width, height, leakColor, 0.12);
    }

    // 30% chance for scan lines (tech feel)
    if (Math.random() > 0.7) {
      this.applyScanLines(ctx, width, height, 0.015);
    }

    // 40% chance for subtle scratches
    if (Math.random() > 0.6) {
      this.applyScratches(ctx, width, height, 3, 0.08);
    }
  }
}

module.exports = TextureManager;
