/**
 * Manifest Generator
 * 
 * PWA manifest.json generator with template support
 * Extracted from Holy Habit manifest configuration
 */

import { PWAManifest, PWAConfig, PWAIcon, PWAShortcut, PWAScreenshot, ManifestError } from '../types/PWA';

export class ManifestGenerator {
  private config: PWAConfig;

  constructor(config: PWAConfig) {
    this.config = config;
    this.validateConfig();
  }

  /**
   * Generate complete PWA manifest
   * 
   * @returns PWA manifest object
   */
  generate(): PWAManifest {
    return {
      name: this.config.name,
      short_name: this.config.shortName,
      description: this.config.description,
      start_url: this.config.startUrl || '/',
      display: this.config.display || 'standalone',
      background_color: this.config.backgroundColor,
      theme_color: this.config.themeColor,
      orientation: this.config.orientation || 'portrait',
      scope: this.config.scope || '/',
      lang: this.config.lang || 'en-US',
      icons: this.generateIcons(),
      shortcuts: this.generateShortcuts(),
      categories: this.config.categories || ['productivity'],
      iarc_rating_id: this.generateIarcRatingId(),
      edge_side_panel: this.generateEdgeSidePanel(),
      file_handlers: this.generateFileHandlers(),
      protocol_handlers: this.generateProtocolHandlers(),
      screenshots: this.generateScreenshots(),
      related_applications: [],
      prefer_related_applications: false
    };
  }

  /**
   * Generate icons array with all standard sizes
   * 
   * @returns Array of PWA icons
   */
  private generateIcons(): PWAIcon[] {
    const standardSizes = this.config.icons.sizes.length > 0 
      ? this.config.icons.sizes 
      : [72, 96, 128, 144, 152, 192, 384, 512];

    return standardSizes.map(size => ({
      src: `${this.config.icons.basePath}/icon-${size}x${size}.png`,
      sizes: `${size}x${size}`,
      type: 'image/png',
      purpose: 'any maskable'
    }));
  }

  /**
   * Generate shortcuts for PWA
   * 
   * @returns Array of PWA shortcuts
   */
  private generateShortcuts(): PWAShortcut[] | undefined {
    if (!this.config.shortcuts) return undefined;

    return this.config.shortcuts.map(shortcut => ({
      ...shortcut,
      icons: [{
        src: `${this.config.icons.basePath}/shortcut-${shortcut.name.toLowerCase().replace(/\s+/g, '-')}-icon.png`,
        sizes: '96x96',
        type: 'image/png'
      }]
    }));
  }

  /**
   * Generate screenshots for app stores
   * 
   * @returns Array of PWA screenshots
   */
  private generateScreenshots(): PWAScreenshot[] | undefined {
    if (!this.config.screenshots) return undefined;

    return this.config.screenshots.map((screenshot, index) => ({
      src: `${this.config.icons.basePath}/screenshot-${index + 1}.png`,
      sizes: screenshot.sizes,
      type: screenshot.type,
      label: screenshot.label,
      platform: screenshot.platform
    }));
  }

  /**
   * Generate IARC rating ID
   * 
   * @returns IARC rating ID
   */
  private generateIarcRatingId(): string {
    return this.config.name.toLowerCase().replace(/\s+/g, '-');
  }

  /**
   * Generate Edge side panel configuration
   * 
   * @returns Edge side panel config
   */
  private generateEdgeSidePanel() {
    return {
      preferred_width: 480
    };
  }

  /**
   * Generate file handlers
   * 
   * @returns Array of file handlers
   */
  private generateFileHandlers() {
    // Common file handlers for productivity apps
    return [
      {
        action: '/editor',
        accept: {
          'text/plain': ['.txt', '.md'],
          'application/json': ['.json']
        }
      }
    ];
  }

  /**
   * Generate protocol handlers
   * 
   * @returns Array of protocol handlers
   */
  private generateProtocolHandlers() {
    const protocolName = this.config.name.toLowerCase().replace(/\s+/g, '');
    
    return [
      {
        protocol: `web+${protocolName}`,
        url: '/?url=%s'
      }
    ];
  }

  /**
   * Generate JSON string with formatting
   * 
   * @param indent - Indentation spaces (default: 2)
   * @returns Formatted JSON string
   */
  generateJSON(indent: number = 2): string {
    const manifest = this.generate();
    return JSON.stringify(manifest, null, indent);
  }

  /**
   * Validate configuration
   * 
   * @throws ManifestError if configuration is invalid
   */
  private validateConfig(): void {
    const required = ['name', 'shortName', 'description', 'themeColor', 'backgroundColor'];
    
    for (const field of required) {
      if (!this.config[field as keyof PWAConfig]) {
        throw new ManifestError(`Missing required field: ${field}`);
      }
    }

    // Validate color format
    const colorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
    if (!colorRegex.test(this.config.themeColor)) {
      throw new ManifestError(`Invalid theme color format: ${this.config.themeColor}`);
    }
    if (!colorRegex.test(this.config.backgroundColor)) {
      throw new ManifestError(`Invalid background color format: ${this.config.backgroundColor}`);
    }

    // Validate icons configuration
    if (!this.config.icons || !this.config.icons.basePath) {
      throw new ManifestError('Icons configuration is required');
    }
  }

  /**
   * Update configuration
   * 
   * @param newConfig - New configuration to merge
   */
  updateConfig(newConfig: Partial<PWAConfig>): void {
    this.config = { ...this.config, ...newConfig };
    this.validateConfig();
  }

  /**
   * Get current configuration
   * 
   * @returns Current PWA configuration
   */
  getConfig(): PWAConfig {
    return { ...this.config };
  }

  /**
   * Create manifest for specific use cases
   */
  static createTemplates() {
    return {
      /**
       * Create manifest for productivity app
       */
      productivity: (config: Partial<PWAConfig>): ManifestGenerator => {
        const productivityConfig: PWAConfig = {
          name: 'Productivity App',
          shortName: 'ProductivityApp',
          description: 'A powerful productivity application',
          themeColor: '#3b82f6',
          backgroundColor: '#ffffff',
          display: 'standalone',
          categories: ['productivity', 'business'],
          icons: {
            sizes: [72, 96, 128, 144, 152, 192, 384, 512],
            basePath: '/assets/icons'
          },
          shortcuts: [
            {
              name: 'New Document',
              short_name: 'New Doc',
              description: 'Create a new document',
              url: '/new'
            },
            {
              name: 'Dashboard',
              short_name: 'Dashboard',
              description: 'View your dashboard',
              url: '/dashboard'
            }
          ],
          ...config
        };

        return new ManifestGenerator(productivityConfig);
      },

      /**
       * Create manifest for social app
       */
      social: (config: Partial<PWAConfig>): ManifestGenerator => {
        const socialConfig: PWAConfig = {
          name: 'Social App',
          shortName: 'SocialApp',
          description: 'Connect with friends and family',
          themeColor: '#1da1f2',
          backgroundColor: '#ffffff',
          display: 'standalone',
          categories: ['social', 'lifestyle'],
          icons: {
            sizes: [72, 96, 128, 144, 152, 192, 384, 512],
            basePath: '/assets/icons'
          },
          shortcuts: [
            {
              name: 'New Post',
              short_name: 'Post',
              description: 'Create a new post',
              url: '/compose'
            },
            {
              name: 'Messages',
              short_name: 'Messages',
              description: 'View your messages',
              url: '/messages'
            }
          ],
          ...config
        };

        return new ManifestGenerator(socialConfig);
      },

      /**
       * Create manifest for e-commerce app
       */
      ecommerce: (config: Partial<PWAConfig>): ManifestGenerator => {
        const ecommerceConfig: PWAConfig = {
          name: 'Shop App',
          shortName: 'ShopApp',
          description: 'Shop your favorite products',
          themeColor: '#059669',
          backgroundColor: '#ffffff',
          display: 'standalone',
          categories: ['shopping', 'business'],
          icons: {
            sizes: [72, 96, 128, 144, 152, 192, 384, 512],
            basePath: '/assets/icons'
          },
          shortcuts: [
            {
              name: 'Browse Products',
              short_name: 'Browse',
              description: 'Browse all products',
              url: '/products'
            },
            {
              name: 'My Cart',
              short_name: 'Cart',
              description: 'View your shopping cart',
              url: '/cart'
            }
          ],
          ...config
        };

        return new ManifestGenerator(ecommerceConfig);
      }
    };
  }
}