import nodemailer from 'nodemailer';
import { encryptionService } from './encryptionService';
import { UserMailAccount } from './userMailAccountService';

export interface SendMailDto {
  to: string;
  cc?: string;
  subject: string;
  html: string;
  text?: string;
  inReplyTo?: string;
  references?: string;
}

class UserMailSmtpService {
  private getSmtpConfig(account: UserMailAccount) {
    const decryptedPassword = encryptionService.decrypt(account.password);
    // IMAP host에서 SMTP host 추론
    const smtpHost = account.host
      .replace(/^imap\./, 'smtp.')
      .replace(/^mail\./, 'smtp.');
    // 포트 추론: TLS → 465, plain → 587
    const port = account.useTls ? 465 : 587;
    return {
      host: smtpHost,
      port,
      secure: account.useTls, // 465: true, 587: false (STARTTLS)
      auth: { user: account.username, pass: decryptedPassword },
      tls: { rejectUnauthorized: false },
    };
  }

  async sendMail(account: UserMailAccount, dto: SendMailDto): Promise<{ success: boolean; message: string }> {
    try {
      const transporter = nodemailer.createTransport(this.getSmtpConfig(account));
      await transporter.sendMail({
        from: `${account.displayName} <${account.email}>`,
        to: dto.to,
        cc: dto.cc,
        subject: dto.subject,
        html: dto.html,
        text: dto.text,
        inReplyTo: dto.inReplyTo,
        references: dto.references,
      });
      return { success: true, message: '발송 완료' };
    } catch (err) {
      return { success: false, message: err instanceof Error ? err.message : '발송 실패' };
    }
  }

  async testSmtpConnection(account: UserMailAccount): Promise<{ success: boolean; message: string }> {
    try {
      const transporter = nodemailer.createTransport(this.getSmtpConfig(account));
      await transporter.verify();
      return { success: true, message: 'SMTP 연결 성공' };
    } catch (err) {
      return { success: false, message: err instanceof Error ? err.message : 'SMTP 연결 실패' };
    }
  }
}

export const userMailSmtpService = new UserMailSmtpService();
