import { Injectable, Logger } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
import { getAppConfig } from '../config/env';

@Injectable()
export class MailerService {
  private readonly logger = new Logger(MailerService.name);
  private readonly config = getAppConfig();

  private createTransport() {
    if (!this.config.mailHost || !this.config.mailUser || !this.config.mailPassword) {
      return null;
    }

    return nodemailer.createTransport({
      host: this.config.mailHost,
      port: this.config.mailPort,
      secure: this.config.mailSecure,
      auth: {
        user: this.config.mailUser,
        pass: this.config.mailPassword,
      },
    });
  }

  async sendInvitationEmail(input: {
    to: string;
    name: string;
    roleName: string;
    invitationUrl: string;
    invitedBy: string;
  }) {
    const transporter = this.createTransport();
    if (!transporter) {
      this.logger.warn(`SMTP config missing, invitation email skipped for ${input.to}`);
      return { delivered: false };
    }

    await transporter.sendMail({
      from: this.config.mailFrom,
      to: input.to,
      subject: 'Set up your BizOne account',
      text: [
        `Hello ${input.name},`,
        '',
        `${input.invitedBy} invited you to BizOne as ${input.roleName}.`,
        'Open the link below to verify your email and create your password:',
        input.invitationUrl,
        '',
        'This invitation link will expire in 24 hours.',
      ].join('\n'),
      html: `
        <div style="font-family:Arial,sans-serif;line-height:1.6;color:#1f2937">
          <h2 style="margin:0 0 16px;color:#006d2f">BizOne Account Invitation</h2>
          <p>Hello ${escapeHtml(input.name)},</p>
          <p><strong>${escapeHtml(input.invitedBy)}</strong> invited you to BizOne as <strong>${escapeHtml(input.roleName)}</strong>.</p>
          <p>Click the button below to verify your email and create your password.</p>
          <p style="margin:24px 0">
            <a href="${input.invitationUrl}" style="background:#006d2f;color:#fff;text-decoration:none;padding:12px 18px;border-radius:8px;display:inline-block;font-weight:700">
              Set Password
            </a>
          </p>
          <p>If the button does not work, open this link manually:</p>
          <p><a href="${input.invitationUrl}">${input.invitationUrl}</a></p>
          <p>This invitation link will expire in 24 hours.</p>
        </div>
      `,
    });

    return { delivered: true };
  }

  async sendPasswordResetEmail(input: {
    to: string;
    name: string;
    resetUrl: string;
  }) {
    const transporter = this.createTransport();
    if (!transporter) {
      this.logger.warn(`SMTP config missing, password reset email skipped for ${input.to}`);
      return { delivered: false };
    }

    await transporter.sendMail({
      from: this.config.mailFrom,
      to: input.to,
      subject: 'Reset your BizOne password',
      text: [
        `Hello ${input.name},`,
        '',
        'We received a request to reset your BizOne password.',
        'Open the link below to choose a new password:',
        input.resetUrl,
        '',
        'This reset link will expire in 1 hour.',
        'If you did not request this, you can ignore this email.',
      ].join('\n'),
      html: `
        <div style="font-family:Arial,sans-serif;line-height:1.6;color:#1f2937">
          <h2 style="margin:0 0 16px;color:#006d2f">BizOne Password Reset</h2>
          <p>Hello ${escapeHtml(input.name)},</p>
          <p>We received a request to reset your BizOne password.</p>
          <p>Click the button below to choose a new password.</p>
          <p style="margin:24px 0">
            <a href="${input.resetUrl}" style="background:#006d2f;color:#fff;text-decoration:none;padding:12px 18px;border-radius:8px;display:inline-block;font-weight:700">
              Reset Password
            </a>
          </p>
          <p>If the button does not work, open this link manually:</p>
          <p><a href="${input.resetUrl}">${input.resetUrl}</a></p>
          <p>This reset link will expire in 1 hour. If you did not request this, you can ignore this email.</p>
        </div>
      `,
    });

    return { delivered: true };
  }

  async sendSecurityNotificationEmail(input: {
    to: string;
    name: string;
    subject: string;
    heading: string;
    intro: string;
    bullets: string[];
    note?: string;
  }) {
    const transporter = this.createTransport();
    if (!transporter) {
      this.logger.warn(`SMTP config missing, security notification email skipped for ${input.to}`);
      return { delivered: false };
    }

    const bulletText = input.bullets.map((item) => `- ${item}`).join('\n');
    const bulletHtml = input.bullets.map((item) => `<li>${escapeHtml(item)}</li>`).join('');

    await transporter.sendMail({
      from: this.config.mailFrom,
      to: input.to,
      subject: input.subject,
      text: [
        `Hello ${input.name},`,
        '',
        input.intro,
        '',
        bulletText,
        '',
        input.note || 'If this was not expected, review your account security immediately.',
      ].join('\n'),
      html: `
        <div style="font-family:Arial,sans-serif;line-height:1.6;color:#1f2937">
          <h2 style="margin:0 0 16px;color:#006d2f">${escapeHtml(input.heading)}</h2>
          <p>Hello ${escapeHtml(input.name)},</p>
          <p>${escapeHtml(input.intro)}</p>
          <ul style="padding-left:20px">${bulletHtml}</ul>
          <p>${escapeHtml(input.note || 'If this was not expected, review your account security immediately.')}</p>
        </div>
      `,
    });

    return { delivered: true };
  }
}

function escapeHtml(value: string) {
  return value
    .replaceAll('&', '&amp;')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}
