import QRCode from 'qrcode';

interface QRCodeOptions {
  size?: number;
  margin?: number;
  color?: {
    dark?: string;
    light?: string;
  };
  errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H';
}

interface QRCodeResult {
  dataUrl: string;
  svg: string;
  size: number;
}

export class QRCodeGenerator {
  private defaultOptions: QRCodeOptions = {
    size: 256,
    margin: 2,
    color: {
      dark: '#000000',
      light: '#FFFFFF'
    },
    errorCorrectionLevel: 'M'
  };

  /**
   * Generate QR code for event ticket URL
   */
  async generateEventQR(eventSlug: string, options: QRCodeOptions = {}): Promise<QRCodeResult> {
    const ticketUrl = `${import.meta.env.PUBLIC_SITE_URL || 'https://portal.blackcanyontickets.com'}/e/${eventSlug}`;
    return this.generateQRCode(ticketUrl, options);
  }

  /**
   * Generate QR code for any URL
   */
  async generateQRCode(url: string, options: QRCodeOptions = {}): Promise<QRCodeResult> {
    const mergedOptions = { ...this.defaultOptions, ...options };
    
    try {
      // Generate data URL (base64 PNG)
      const dataUrl = await QRCode.toDataURL(url, {
        width: mergedOptions.size,
        margin: mergedOptions.margin,
        color: mergedOptions.color,
        errorCorrectionLevel: mergedOptions.errorCorrectionLevel
      });

      // Generate SVG
      const svg = await QRCode.toString(url, {
        type: 'svg',
        width: mergedOptions.size,
        margin: mergedOptions.margin,
        color: mergedOptions.color,
        errorCorrectionLevel: mergedOptions.errorCorrectionLevel
      });

      return {
        dataUrl,
        svg,
        size: mergedOptions.size || this.defaultOptions.size!
      };
    } catch (error) {

      throw new Error('Failed to generate QR code');
    }
  }

  /**
   * Generate QR code with custom branding/logo overlay
   */
  async generateBrandedQR(
    url: string, 
    logoDataUrl?: string, 
    options: QRCodeOptions = {}
  ): Promise<QRCodeResult> {
    const qrResult = await this.generateQRCode(url, {
      ...options,
      errorCorrectionLevel: 'H' // Higher error correction for logo overlay
    });

    if (!logoDataUrl) {
      return qrResult;
    }

    // If logo is provided, we'll need to composite it onto the QR code
    // This would typically be done server-side with canvas or image processing
    // For now, we'll return the base QR code and handle logo overlay in the image generation
    return qrResult;
  }

  /**
   * Validate URL before QR generation
   */
  private validateUrl(url: string): boolean {
    try {
      new URL(url);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * Get optimal QR code size for different use cases
   */
  getRecommendedSize(useCase: 'social' | 'flyer' | 'email' | 'print'): number {
    switch (useCase) {
      case 'social':
        return 200;
      case 'flyer':
        return 300;
      case 'email':
        return 150;
      case 'print':
        return 600;
      default:
        return 256;
    }
  }

  /**
   * Generate multiple QR code formats for different use cases
   */
  async generateMultiFormat(url: string): Promise<{
    social: QRCodeResult;
    flyer: QRCodeResult;
    email: QRCodeResult;
    print: QRCodeResult;
  }> {
    const [social, flyer, email, print] = await Promise.all([
      this.generateQRCode(url, { size: this.getRecommendedSize('social') }),
      this.generateQRCode(url, { size: this.getRecommendedSize('flyer') }),
      this.generateQRCode(url, { size: this.getRecommendedSize('email') }),
      this.generateQRCode(url, { size: this.getRecommendedSize('print') })
    ]);

    return { social, flyer, email, print };
  }
}

// Export singleton instance
export const qrGenerator = new QRCodeGenerator();