// AWS SES Integration Service
// Integration with AWS SES for email notifications

import { retryWithBackoff } from '@/shared/utils/retry';
import { logger } from '@/infrastructure/monitoring/logger';

export interface SESEmailRequest {
  to: string;
  subject: string;
  body: string;
  from?: string;
}

export class SESIntegration {
  /**
   * Send email via AWS SES
   */
  async sendEmail(request: SESEmailRequest): Promise<{ messageId: string }> {
    const awsRegion = process.env.AWS_REGION || 'us-east-1';
    const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
    const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
    const fromEmail = request.from || process.env.EMAIL_FROM || 'noreply@dbis.org';

    if (!awsAccessKeyId || !awsSecretAccessKey) {
      throw new Error('AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are required');
    }

    // AWS SES API endpoint
    const sesEndpoint = `https://email.${awsRegion}.amazonaws.com`;

    // Create SES request
    const sesRequest = {
      Action: 'SendEmail',
      Version: '2010-12-01',
      Source: fromEmail,
      Destination: {
        ToAddresses: [request.to],
      },
      Message: {
        Subject: {
          Data: request.subject,
          Charset: 'UTF-8',
        },
        Body: {
          Html: {
            Data: request.body,
            Charset: 'UTF-8',
          },
        },
      },
    };

    // AWS Signature Version 4 signing would go here
    // For now, use AWS SDK would be preferred in production
    // This is a simplified implementation

    // Try to use AWS SDK v3 if available, fallback to fetch
    let response: Response;
    
    try {
      // Dynamic import of AWS SDK v3
      const { SESClient, SendEmailCommand } = await import('@aws-sdk/client-ses');
      const sesClient = new SESClient({
        region: awsRegion,
        credentials: {
          accessKeyId: awsAccessKeyId,
          secretAccessKey: awsSecretAccessKey,
        },
      });

      const command = new SendEmailCommand({
        Source: fromEmail,
        Destination: {
          ToAddresses: [request.to],
        },
        Message: {
          Subject: {
            Data: request.subject,
            Charset: 'UTF-8',
          },
          Body: {
            Html: {
              Data: request.body,
              Charset: 'UTF-8',
            },
          },
        },
      });

      const result = await retryWithBackoff(
        async () => {
          return await sesClient.send(command);
        },
        {
          maxRetries: 3,
          initialDelayMs: 1000,
          onRetry: (attempt, error) => {
            logger.warn('AWS SES retry', {
              attempt,
              error: error.message,
            });
          },
        }
      );

      return {
        messageId: result.MessageId || 'unknown',
      };
    } catch (sdkError) {
      // Fallback to fetch if SDK not available
      logger.warn('AWS SDK not available, using fetch fallback', {
        error: sdkError instanceof Error ? sdkError.message : 'Unknown error',
      });

      response = await retryWithBackoff(
        async () => {
          return await fetch(sesEndpoint, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/x-amz-json-1.0',
              'X-Amz-Target': 'AWSSimpleEmailService.SendEmail',
              'Authorization': `AWS4-HMAC-SHA256 Credential=${awsAccessKeyId}/...`, // Simplified
            },
            body: JSON.stringify(sesRequest),
          });
        },
        {
          maxRetries: 3,
          initialDelayMs: 1000,
          onRetry: (attempt, error) => {
            logger.warn('AWS SES retry', {
              attempt,
              error: error.message,
            });
          },
        }
      );

      if (!response.ok) {
        const error = await response.text();
        throw new Error(`AWS SES API error: ${response.status} ${error}`);
      }

      const data = await response.json();

      return {
        messageId: data.SendEmailResponse?.SendEmailResult?.MessageId || 'unknown',
      };
    }
  }
}

export const sesIntegration = new SESIntegration();
