// ============================================================
// EMAIL MODULE — SMTP via Nodemailer
// Envia e-mails usando a configuração SMTP do tenant
// ============================================================
import {
  Injectable, Logger, BadRequestException,
  Module, Controller, Post, Body, UseGuards, Request,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsString, IsEmail, IsOptional, IsArray } from 'class-validator';
import { DataSource } from 'typeorm';
import * as nodemailer from 'nodemailer';

interface SmtpConfig {
  host: string;
  port: number;
  user: string;
  pass: string;
  from: string;
  secure: boolean;
}

// ============================================================
// DTO
// ============================================================
export class SendMailDto {
  @ApiProperty() @IsEmail({}, { each: true }) @IsArray() to: string[];
  @ApiProperty() @IsString() subject: string;
  @ApiProperty() @IsString() html: string;
  @ApiPropertyOptional() @IsOptional() @IsString() text?: string;
  @ApiPropertyOptional() @IsOptional() @IsArray() @IsEmail({}, { each: true }) cc?: string[];
  @ApiPropertyOptional() @IsOptional() @IsArray() @IsEmail({}, { each: true }) bcc?: string[];
}

// ============================================================
// SERVICE
// ============================================================
@Injectable()
export class MailService {
  private readonly logger = new Logger(MailService.name);

  constructor(private readonly dataSource: DataSource) {}

  private async getSmtpConfig(tenantId: string): Promise<SmtpConfig> {
    const rows = await this.dataSource.query(
      `SELECT smtp_host, smtp_port, smtp_user, smtp_pass, smtp_from, smtp_secure FROM tenants WHERE id = $1`,
      [tenantId],
    );
    const t = rows?.[0];
    if (!t?.smtp_host || !t?.smtp_user || !t?.smtp_pass) {
      throw new BadRequestException('SMTP não configurado. Configure em Configurações > E-mail.');
    }
    return {
      host:   t.smtp_host,
      port:   Number(t.smtp_port ?? 587),
      user:   t.smtp_user,
      pass:   t.smtp_pass,
      from:   t.smtp_from || t.smtp_user,
      secure: Boolean(t.smtp_secure),
    };
  }

  private createTransporter(cfg: SmtpConfig) {
    return nodemailer.createTransport({
      host: cfg.host,
      port: cfg.port,
      secure: cfg.secure,
      auth: { user: cfg.user, pass: cfg.pass },
      tls: { rejectUnauthorized: false },
    });
  }

  async sendMail(
    tenantId: string,
    mail: { to: string | string[]; subject: string; html: string; text?: string; cc?: string[]; bcc?: string[] },
  ): Promise<{ messageId: string }> {
    const cfg = await this.getSmtpConfig(tenantId);
    const transporter = this.createTransporter(cfg);
    const info = await transporter.sendMail({
      from:    cfg.from,
      to:      Array.isArray(mail.to) ? mail.to.join(', ') : mail.to,
      cc:      mail.cc?.join(', '),
      bcc:     mail.bcc?.join(', '),
      subject: mail.subject,
      html:    mail.html,
      text:    mail.text,
    });
    this.logger.log(`E-mail enviado para ${mail.to} — messageId: ${info.messageId}`);
    return { messageId: info.messageId };
  }

  async testConnection(tenantId: string): Promise<{ ok: boolean; message: string }> {
    try {
      const cfg = await this.getSmtpConfig(tenantId);
      const transporter = this.createTransporter(cfg);
      await transporter.verify();
      return { ok: true, message: `Conexão com ${cfg.host}:${cfg.port} bem-sucedida.` };
    } catch (err) {
      return { ok: false, message: (err as Error).message };
    }
  }
}

// ============================================================
// CONTROLLER
// ============================================================
@ApiTags('E-mail')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@Controller('email')
export class EmailController {
  constructor(private readonly mailService: MailService) {}

  @Post('test')
  @ApiOperation({ summary: 'Testa conexão SMTP configurada para o tenant' })
  test(@Request() req: any) {
    return this.mailService.testConnection(req.user.tenantId);
  }

  @Post('send')
  @ApiOperation({ summary: 'Envia e-mail usando SMTP do tenant' })
  send(@Request() req: any, @Body() dto: SendMailDto) {
    return this.mailService.sendMail(req.user.tenantId, dto);
  }
}

// ============================================================
// MODULE
// ============================================================
@Module({
  providers: [MailService],
  controllers: [EmailController],
  exports: [MailService],
})
export class EmailModule {}
