import { 
  BackgroundConfig, 
  ColorStop, 
  LinearGradientConfig, 
  RadialGradientConfig, 
  ConicGradientConfig,
  PatternConfig,
  ImageBackgroundConfig,
  SolidBackgroundConfig,
  AnimatedBackgroundConfig,
  MeshGradientConfig,
  NoiseConfig,
  GlassConfig
} from '../types/background.types';

export class BackgroundGenerator {
  
  static generateCss(config: BackgroundConfig): { [key: string]: string } {
    switch (config.type) {
      case 'solid':
        return this.generateSolid(config);
      case 'linear-gradient':
        return this.generateLinearGradient(config);
      case 'radial-gradient':
        return this.generateRadialGradient(config);
      case 'conic-gradient':
        return this.generateConicGradient(config);
      case 'pattern':
        return this.generatePattern(config);
      case 'image':
        return this.generateImage(config);
      case 'animated':
        return this.generateAnimated(config);
      case 'mesh':
        return this.generateMesh(config);
      case 'noise':
        return this.generateNoise(config);
      case 'glass':
        return this.generateGlass(config);
      default:
        return { background: 'transparent' };
    }
  }

  private static generateSolid(config: SolidBackgroundConfig): { [key: string]: string } {
    return {
      background: config.color,
      'background-size': 'cover',
      'background-position': 'center',
      'background-repeat': 'no-repeat'
    };
  }

  private static generateLinearGradient(config: LinearGradientConfig): { [key: string]: string } {
    const direction = config.direction || 'to bottom';
    const colorStops = this.formatColorStops(config.colors);
    
    return {
      background: `linear-gradient(${direction}, ${colorStops})`,
      'background-size': 'cover',
      'background-position': 'center',
      'background-repeat': 'no-repeat'
    };
  }

  private static generateRadialGradient(config: RadialGradientConfig): { [key: string]: string } {
    const shape = config.shape || 'ellipse';
    const size = config.size || 'farthest-corner';
    const position = config.position || 'center';
    const colorStops = this.formatColorStops(config.colors);
    
    return {
      background: `radial-gradient(${shape} ${size} at ${position}, ${colorStops})`,
      'background-size': 'cover',
      'background-position': 'center',
      'background-repeat': 'no-repeat'
    };
  }

  private static generateConicGradient(config: ConicGradientConfig): { [key: string]: string } {
    const angle = config.angle ? `from ${config.angle}deg` : '';
    const position = config.position ? `at ${config.position}` : '';
    const colorStops = this.formatColorStops(config.colors);
    
    return {
      background: `conic-gradient(${angle} ${position}, ${colorStops})`,
      'background-size': 'cover',
      'background-position': 'center',
      'background-repeat': 'no-repeat'
    };
  }

  private static generatePattern(config: PatternConfig): { [key: string]: string } {
    const primaryColor = config.primaryColor || '#000000';
    const secondaryColor = config.secondaryColor || '#ffffff';
    const size = typeof config.size === 'number' ? `${config.size}px` : (config.size || '20px');
    const opacity = config.opacity || 1;

    const patternCss = this.getPatternCss(config.pattern, primaryColor, secondaryColor, size);
    
    return {
      background: patternCss,
      opacity: opacity.toString(),
      'background-size': size,
      'background-repeat': 'repeat'
    };
  }

  private static generateImage(config: ImageBackgroundConfig): { [key: string]: string } {
    const styles: { [key: string]: string } = {
      'background-image': `url(${config.url})`,
      'background-size': config.size || 'cover',
      'background-position': config.position || 'center',
      'background-repeat': config.repeat || 'no-repeat'
    };

    if (config.attachment) {
      styles['background-attachment'] = config.attachment;
    }

    if (config.opacity !== undefined) {
      styles['opacity'] = config.opacity.toString();
    }

    return styles;
  }

  private static generateAnimated(config: AnimatedBackgroundConfig): { [key: string]: string } {
    const baseStyles = this.generateCss(config.baseConfig);
    const duration = config.duration || '5s';
    const timing = config.timing || 'ease-in-out';
    const iteration = config.iteration === 'infinite' ? 'infinite' : (config.iteration || 1).toString();

    return {
      ...baseStyles,
      animation: `background-animation ${duration} ${timing} ${iteration}`,
    };
  }

  private static generateMesh(config: MeshGradientConfig): { [key: string]: string } {
    // Generate mesh gradient using multiple radial gradients
    const colors = config.colors;
    const complexity = config.complexity || 'medium';
    
    // Create multiple overlapping radial gradients
    const gradients = this.generateMeshGradients(colors, complexity);
    
    return {
      background: gradients.join(', '),
      'background-size': '400% 400%',
      animation: 'mesh-animation 15s ease infinite'
    };
  }

  private static generateNoise(config: NoiseConfig): { [key: string]: string } {
    const baseColor = config.baseColor || '#000000';
    const intensity = config.intensity || 0.5;
    const scale = config.scale || 100;
    const opacity = config.opacity || 1;

    // Create noise effect using CSS filters and patterns
    return {
      background: baseColor,
      'background-image': `url("data:image/svg+xml,%3Csvg viewBox='0 0 ${scale} ${scale}' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='${intensity}'/%3E%3C/svg%3E")`,
      opacity: opacity.toString()
    };
  }

  private static generateGlass(config: GlassConfig): { [key: string]: string } {
    const intensity = config.intensity || 10;
    const tint = config.tint || 'rgba(255, 255, 255, 0.1)';
    const opacity = config.opacity || 0.8;
    
    const styles: { [key: string]: string } = {
      background: tint,
      opacity: opacity.toString(),
      'backdrop-filter': `blur(${intensity}px)`
    };

    if (config.backdrop === 'saturate' || config.backdrop === 'both') {
      styles['backdrop-filter'] += ` saturate(150%)`;
    }

    return styles;
  }

  private static formatColorStops(colors: ColorStop[]): string {
    return colors.map(stop => {
      if (stop.position !== undefined) {
        const position = typeof stop.position === 'number' ? `${stop.position}%` : stop.position;
        return `${stop.color} ${position}`;
      }
      return stop.color;
    }).join(', ');
  }

  private static getPatternCss(pattern: string, primary: string, secondary: string, size: string): string {
    const patterns: { [key: string]: string } = {
      'dots': `radial-gradient(circle, ${primary} 20%, transparent 20%)`,
      'grid': `linear-gradient(${primary} 1px, transparent 1px), linear-gradient(90deg, ${primary} 1px, transparent 1px)`,
      'stripes': `linear-gradient(45deg, ${primary} 25%, transparent 25%, transparent 50%, ${primary} 50%, ${primary} 75%, transparent 75%)`,
      'diagonal-stripes': `linear-gradient(45deg, ${primary} 25%, transparent 25%, transparent 50%, ${primary} 50%, ${primary} 75%, transparent 75%)`,
      'chevron': `linear-gradient(45deg, ${primary} 25%, transparent 25%), linear-gradient(-45deg, ${primary} 25%, transparent 25%)`,
      'waves': `radial-gradient(circle at 50% 100%, transparent 40%, ${primary} 40%, ${primary} 60%, transparent 60%)`,
      'hexagon': `radial-gradient(circle at 50% 0%, transparent 40%, ${primary} 40%, ${primary} 60%, transparent 60%)`,
      'triangles': `linear-gradient(60deg, ${primary} 25%, transparent 25%), linear-gradient(120deg, ${primary} 25%, transparent 25%)`,
      'checkerboard': `linear-gradient(45deg, ${primary} 25%, transparent 25%, transparent 75%, ${primary} 75%), linear-gradient(45deg, ${primary} 25%, transparent 25%, transparent 75%, ${primary} 75%)`,
      'circles': `radial-gradient(circle, ${primary} 40%, transparent 40%)`,
      'crosshatch': `linear-gradient(0deg, ${primary} 1px, transparent 1px), linear-gradient(90deg, ${primary} 1px, transparent 1px), linear-gradient(45deg, ${primary} 1px, transparent 1px), linear-gradient(-45deg, ${primary} 1px, transparent 1px)`,
      'polka-dots': `radial-gradient(circle, ${primary} 25%, transparent 25%)`
    };

    return patterns[pattern] || patterns['dots'];
  }

  private static generateMeshGradients(colors: string[], complexity: string): string[] {
    const gradientCount = complexity === 'high' ? 6 : complexity === 'medium' ? 4 : 2;
    const gradients: string[] = [];

    for (let i = 0; i < gradientCount; i++) {
      const color1 = colors[i % colors.length];
      const color2 = colors[(i + 1) % colors.length];
      const x = Math.random() * 100;
      const y = Math.random() * 100;
      const size = 50 + Math.random() * 50;
      
      gradients.push(
        `radial-gradient(${size}% ${size}% at ${x}% ${y}%, ${color1}, transparent)`
      );
    }

    return gradients;
  }
}