import { Injectable } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';

// Templates
import { otpVerificationTemplate } from './templates/otp-verification.template';
import { passwordResetTemplate } from './templates/password-reset.template';
import { enrollmentConfirmationTemplate } from './templates/enrollment-confirmation.template';
import { courseCompletionTemplate } from './templates/course-completion.template';
import { adminNotificationTemplate } from './templates/admin-notification.template';
import { adminCourseApprovalTemplate } from './templates/admin-course-approval.template';

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

  constructor(
    private configService: ConfigService,
    private jwtService: JwtService
  ) {
    this.transporter = nodemailer.createTransport({
      host: this.configService.get<string>('MAIL_HOST'),
      port: this.configService.get<number>('MAIL_PORT'),
      secure: this.configService.get<string>('MAIL_SECURE') === 'true',
      auth: {
        user: this.configService.get<string>('MAIL_USER'),
        pass: this.configService.get<string>('MAIL_PASS'),
      },
    });
  }

  private get projectName(): string {
    return this.configService.get<string>('PROJECT_NAME') || 'TryTalento';
  }

  private async sendMail(to: string, subject: string, html: string) {
    const from = this.configService.get<string>('MAIL_FROM') || `"${this.projectName}" <no-reply@trytalento.com>`;
    const adminEmail = this.configService.get<string>('ADMIN_EMAIL') || 'admin@trytalento.com';

    try {
      await this.transporter.sendMail({
        from,
        to,
        cc: to !== adminEmail ? adminEmail : undefined,
        subject,
        html,
      });
      console.log(`Email sent to ${to}${to !== adminEmail ? ` (CC: ${adminEmail})` : ''}`);
    } catch (error) {
      console.error('Error sending email:', error);
    }
  }

  async sendOtpEmail(email: string, otp: string) {
    await this.sendMail(
      email,
      `${otp} is your verification code - ${this.projectName}`,
      otpVerificationTemplate(otp, this.projectName)
    );
  }

  async sendPasswordResetEmail(email: string, token: string) {
    const baseUrl = this.configService.get<string>('APP_BASE_URL_FRONT') || 'https://trytalento.com';
    const resetUrl = `${baseUrl}/auth/reset-password?token=${token}`;

    await this.sendMail(
      email,
      `Reset Your Password - ${this.projectName}`,
      passwordResetTemplate(resetUrl, this.projectName)
    );
  }

  async sendEnrollmentConfirmation(email: string, userName: string, courseTitle: string, courseId: number | string) {
    const baseUrl = this.configService.get<string>('APP_BASE_URL_FRONT') || 'https://trytalento.com';
    const courseUrl = `${baseUrl}/courses/${courseId}`;

    await this.sendMail(
      email,
      `Welcome to Your Course: ${courseTitle}`,
      enrollmentConfirmationTemplate(userName, courseTitle, courseUrl, this.projectName)
    );
  }

  async sendCourseCompletion(email: string, userName: string, courseTitle: string) {
    await this.sendMail(
      email,
      `Kudos on Completion: ${courseTitle}`,
      courseCompletionTemplate(userName, courseTitle, this.projectName)
    );
  }

  async sendAdminContactNotification(contactData: { title: string, subject: string, email: string }) {
    const mailTo = this.configService.get<string>('ADMIN_EMAIL') || 'admin@trytalento.com';

    await this.sendMail(
      mailTo,
      `New Website Contact Inquiry: ${contactData.title}`,
      adminNotificationTemplate(contactData, this.projectName)
    );
  }

  async sendCourseApprovalRequest(trainerName: string, courseTitle: string, courseId: number, isPublish: boolean) {
    const mailTo = this.configService.get<string>('ADMIN_EMAIL') || 'admin@trytalento.com';
    const baseUrl = this.configService.get<string>('APP_BASE_URL') || 'http://127.0.0.1:3002';

    // Generate signed tokens for security
    const approveToken = this.jwtService.sign({ courseId, action: 'approve', targetPublish: isPublish });
    const rejectToken = this.jwtService.sign({ courseId, action: 'reject', targetPublish: isPublish });

    const approveUrl = `${baseUrl}/courses/approve?token=${approveToken}`;
    const rejectUrl = `${baseUrl}/courses/reject?token=${rejectToken}`;

    const requestType = isPublish ? 'publish' : 'unpublish';

    await this.sendMail(
      mailTo,
      `Priority: Course ${requestType} request for "${courseTitle}"`,
      adminCourseApprovalTemplate(trainerName, courseTitle, approveUrl, rejectUrl, this.projectName, requestType)
    );
  }
}
