import 'server-only';

import { getEmailConfigurationForUse } from '@/features/foundation/email/server/email-config.service';
import { SmtpEmailProvider } from '@/features/foundation/email/server/smtp-provider';
import type {
  NotificationChannel,
  NotificationProvider,
  NotificationProviderSendInput,
  NotificationProviderSendResult,
} from '../types';

export class EmailNotificationProvider implements NotificationProvider {
  readonly channel: NotificationChannel = 'email';
  readonly key = 'smtp';

  constructor(private readonly organizationId: string) {}

  private async resolveConfig() {
    const config = await getEmailConfigurationForUse(this.organizationId, 'smtp');
    if (!config) {
      throw new Error('No active SMTP email configuration was found for this organization.');
    }

    return config;
  }

  async validate() {
    await this.resolveConfig();
  }

  async healthCheck() {
    try {
      const config = await this.resolveConfig();
      const provider = new SmtpEmailProvider();
      const result = await provider.testConnection(config);

      return result.ok
        ? { ok: true }
        : { ok: false, detail: result.detail ?? 'SMTP health check failed.' };
    } catch (error) {
      return {
        ok: false,
        detail: error instanceof Error ? error.message : 'Unknown SMTP health check failure',
      };
    }
  }

  async send(input: NotificationProviderSendInput): Promise<NotificationProviderSendResult> {
    const config = await this.resolveConfig();
    const provider = new SmtpEmailProvider();

    return provider.sendEmail(config, {
      subject: input.subject,
      text: input.bodyText,
      html: input.bodyHtml,
      to: input.to,
      cc: input.cc,
      bcc: input.bcc,
      replyTo: input.replyTo,
      attachments: input.attachments.map((attachment, index) => ({
        fileName: attachment.fileName,
        contentType: attachment.contentType,
        buffer: input.attachmentBuffers[index] ?? Buffer.alloc(0),
      })),
    });
  }
}
