import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import nodemailer from 'nodemailer';
import { AppConfig } from '../../config/configs';
import { Logger } from 'pino-nestjs';

@Injectable()
export class MailService {
  private transporter: nodemailer.Transporter;

  constructor(
    private readonly configService: ConfigService<AppConfig, true>,
    private readonly logger: Logger,
  ) {
    const host = this.configService.get('mail.host', { infer: true });
    const port = this.configService.get('mail.port', { infer: true });
    const user = this.configService.get('mail.username', { infer: true });
    const pass = this.configService.get('mail.password', { infer: true });

    this.transporter = nodemailer.createTransport({
      host,
      port,
      secure: true,
      logger: true,
      debug: true,
      auth: {
        user,
        pass,
      },
    });
  }

  async sendOtpEmail(to: string, name: string, otp: string) {
    const fromAddress = this.configService.get('mail.fromAddress', { infer: true });
    const username = this.configService.get('mail.username', { infer: true });
    const from = `${fromAddress} <${username}>`;

    const mailOptions = {
      from,
      to,
      subject: 'Your OTP Code',
      html: `
        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #eeeeee; border-radius: 8px;">
          <h2 style="color: #4A90E2; text-align: center;">The Fur Finder</h2>
          <hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;"/>
          <p>Dear <strong>${name}</strong>,</p>
          <p>Your password reset OTP code is:</p>
          <div style="text-align: center; margin: 30px 0;">
            <span style="font-size: 32px; font-weight: bold; letter-spacing: 6px; color: #333333; background-color: #f7f9fc; padding: 12px 24px; border-radius: 4px; border: 1px dashed #cccccc; display: inline-block;">${otp}</span>
          </div>
          <p>This code is valid for <strong>10 minutes</strong>.</p>
          <p>If you did not request this password reset, please ignore this email or contact support if you have security concerns.</p>
          <hr style="border: 0; border-top: 1px solid #eeeeee; margin: 20px 0;"/>
          <p style="font-size: 12px; color: #999999; text-align: center;">Best regards,<br/>The Fur Finder Team</p>
        </div>
      `,
    };

    this.logger.log(`Sending OTP email to ${to}`);
    try {
      await this.transporter.sendMail(mailOptions);
      this.logger.log(`OTP email successfully sent to ${to}`);
      return {
        status: 'success',
        message: 'Email sent to ' + to,
      };
    } catch (error) {
      this.logger.error(`Error sending email to ${to}:`, error);
      throw new InternalServerErrorException('Failed to send verification email');
    }
  }

  /** Best-effort ops alert — logs and swallows failures instead of throwing. */
  async sendAlertEmail(to: string[], subject: string, message: string) {
    try {
      await this.transporter.sendMail({
        from: this.from,
        to: to.join(','),
        subject,
        html: `<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;"><h2 style="color: #d0021b;">${subject}</h2><p>${message}</p></div>`,
        text: message,
      });
      this.logger.log(`Alert email sent to ${to.join(', ')}`);
    } catch (error) {
      this.logger.error(`Failed to send alert email to ${to.join(', ')}`, error);
    }
  }

  private get from() {
    const fromAddress = this.configService.get('mail.fromAddress', { infer: true });
    const username = this.configService.get('mail.username', { infer: true });
    return `${fromAddress} <${username}>`;
  }

  /** Derives a friendly display name from the local part of an email address. */
  static nameFromEmail(email: string): string {
    const local = email.split('@')[0];
    return local.replace(/[._-]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
  }

  async sendAndroidInviteEmail(email: string, name: string, downloadLink: string) {
    const html = `
      <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #eeeeee; border-radius: 8px;">
        <h2 style="color: #4A90E2; text-align: center;">The Fur Finder</h2>
        <p>Hi <strong>${name}</strong>,</p>
        <p>You're invited to test The Fur Finder on Android!</p>
        <div style="text-align: center; margin: 30px 0;">
          <a href="${downloadLink}" style="background-color: #4A90E2; color: #ffffff; padding: 12px 24px; border-radius: 4px; text-decoration: none;">Download the app</a>
        </div>
        <p style="font-size: 12px; color: #999999; text-align: center;">The Fur Finder Team</p>
      </div>`;

    await this.transporter.sendMail({
      from: this.from,
      to: email,
      subject: "You're Invited to Test The Fur Finder on Android!",
      html,
      text: `Hi ${name}, you're invited to test The Fur Finder on Android. Download it here: ${downloadLink}`,
    });
    this.logger.log(`Invite sent to ${email}`);
    return { status: 'success', message: `Invite sent to ${email}` };
  }

  async sendAppUpdateEmail(
    email: string,
    name: string,
    version: string,
    buildNumber: string,
    downloadLink: string,
  ): Promise<{ email: string; status: 'sent' | 'failed'; error?: string }> {
    try {
      const html = `
        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #eeeeee; border-radius: 8px;">
          <h2 style="color: #4A90E2; text-align: center;">The Fur Finder</h2>
          <p>Hi <strong>${name}</strong>,</p>
          <p>Version <strong>${version}</strong> (build ${buildNumber}) of The Fur Finder is available to test.</p>
          <div style="text-align: center; margin: 30px 0;">
            <a href="${downloadLink}" style="background-color: #4A90E2; color: #ffffff; padding: 12px 24px; border-radius: 4px; text-decoration: none;">Update the app</a>
          </div>
          <p style="font-size: 12px; color: #999999; text-align: center;">The Fur Finder Team</p>
        </div>`;

      await this.transporter.sendMail({
        from: this.from,
        to: email,
        subject: `The Fur Finder ${version} is ready to test`,
        html,
        text: `Hi ${name}, version ${version} (build ${buildNumber}) of The Fur Finder is available. Update here: ${downloadLink}`,
      });
      this.logger.log(`Update email sent to ${email}`);
      return { email, status: 'sent' };
    } catch (error: any) {
      this.logger.error(`Failed to send update email to ${email}`, error);
      return { email, status: 'failed', error: error?.message ?? String(error) };
    }
  }
}
