import { MailerService } from '@nestjs-modules/mailer';
import { BadRequestException, Injectable } from '@nestjs/common';
import { getAuth } from 'firebase-admin/auth';
import { join } from 'path';
import { ZodError } from 'zod';
import { SenderSchema, ShareByEMail, ShareByEMailSchema, User } from '../models/db.model';
import { ErrorResponse, MailInfo, isEmpty } from '../models/main.model';
import { UserService } from '../user/user.service';
// const __filename = fileURLToPath(import.meta.url);
// const __dirname = path.dirname(__filename);

@Injectable()
export class MailService {
  constructor(
    private mailerService: MailerService,
    private userService: UserService,
  ) {}

  async sendInquiry(mailInfo: MailInfo): Promise<void | ErrorResponse> {
    try {
      SenderSchema.parse(mailInfo.sender);
    } catch (error) {
      if (error instanceof ZodError) {
        const formattedErrors = error.errors.map(err => ({
          field: err.path.join('.'),
          message: err.message,
        }));
        throw new BadRequestException(formattedErrors);
      }
      throw error;
    }
    const user = await this.userService.getUserByMail(mailInfo.email);
    if (isEmpty(mailInfo.sender.name)) {
      return { fields: [{ fieldname: 'name', message: 'Required' }] };
    }
    await this.mailerService.sendMail({
      to: user.email,
      from: '"Bizmatch Team" <info@bizmatch.net>', // override default from
      subject: `Inquiry from ${mailInfo.sender.name}`,
      //template: './inquiry', // `.hbs` extension is appended automatically
      template: join(__dirname, '../..', 'mail/templates/inquiry.hbs'),
      context: {
        // ✏️ filling curly brackets with content
        name: user.firstname,
        inquiry: mailInfo.sender.comments,
        internalListingNumber: mailInfo.listing.internalListingNumber,
        title: mailInfo.listing.title,
        iname: mailInfo.sender.name,
        phone: mailInfo.sender.phoneNumber,
        email: mailInfo.sender.email,
        id: mailInfo.listing.id,
        url: mailInfo.url,
      },
    });
  }
  async sendVerificationEmail(
    email: string, 
    redirectConfig: { protocol: string, hostname: string, port?: number }
  ): Promise<void | ErrorResponse> {
    try {
      // Firebase Auth-Instanz holen
      const auth = getAuth();
      
      // Baue den Redirect-URL aus den übergebenen Parametern
      let continueUrl = `${redirectConfig.protocol}://${redirectConfig.hostname}`;
      if (redirectConfig.port) {
        continueUrl += `:${redirectConfig.port}`;
      }
      continueUrl += '/auth/verify-email-success'; // Beispiel für einen Weiterleitungspfad
      
      // Custom Verification Link generieren
      const firebaseActionLink = await auth.generateEmailVerificationLink(email, {
        url: continueUrl,
        handleCodeInApp: false,
      });

      // Extrahiere den oobCode aus dem Firebase Link
      const actionLinkUrl = new URL(firebaseActionLink);
      const oobCode = actionLinkUrl.searchParams.get('oobCode');
      
      if (!oobCode) {
        throw new BadRequestException('Failed to generate verification code');
      }
      
      // Erstelle die benutzerdefinierte URL mit dem oobCode
      let customActionLink = `${redirectConfig.protocol}://${redirectConfig.hostname}`;
      if (redirectConfig.port) {
        customActionLink += `:${redirectConfig.port}`;
      }
    
      // Ersetze die Platzhalter mit den tatsächlichen Werten
      customActionLink += `/email-authorized?email=${encodeURIComponent(email)}&mode=verifyEmail&oobCode=${oobCode}`;
      
      // Zufallszahl für die E-Mail generieren
      const randomNumber = Math.floor(Math.random() * 10000);
  
      // E-Mail senden
      await this.mailerService.sendMail({
        to: email,
        from: '"Bizmatch Team" <info@bizmatch.net>',
        subject: 'Verify your email address',
        template: join(__dirname, '../..', 'mail/templates/email-verification.hbs'),
        context: {
          actionLink: customActionLink,
          randomNumber: randomNumber
        },
      });
  
      return;
    } catch (error) {
      console.error('Error sending verification email:', error);
      throw new BadRequestException('Failed to send verification email');
    }
  }
  async sendRequest(mailInfo: MailInfo): Promise<void | ErrorResponse> {
    try {
      SenderSchema.parse(mailInfo.sender);
    } catch (error) {
      if (error instanceof ZodError) {
        const formattedErrors = error.errors.map(err => ({
          field: err.path.join('.'),
          message: err.message,
        }));
        throw new BadRequestException(formattedErrors);
      }
      throw error;
    }
    await this.mailerService.sendMail({
      to: 'support@bizmatch.net',
      from: `"Bizmatch Support Team" <info@bizmatch.net>`,
      subject: `Support Request from ${mailInfo.sender.name}`,
      //template: './inquiry', // `.hbs` extension is appended automatically
      template: join(__dirname, '../..', 'mail/templates/request.hbs'),
      context: {
        // ✏️ filling curly brackets with content
        request: mailInfo.sender.comments,
        iname: mailInfo.sender.name,
        phone: mailInfo.sender.phoneNumber,
        email: mailInfo.sender.email,
      },
    });
  }
  async sendSubscriptionConfirmation(user: User): Promise<void> {
    await this.mailerService.sendMail({
      to: user.email,
      from: `"Bizmatch Support Team" <info@bizmatch.net>`,
      subject: `Subscription Confirmation`,
      //template: './inquiry', // `.hbs` extension is appended automatically
      template: join(__dirname, '../..', 'mail/templates/subscriptionConfirmation.hbs'),
      context: {
        // ✏️ filling curly brackets with content
        firstname: user.firstname,
        lastname: user.lastname,
        subscriptionPlan: user.subscriptionPlan,
      },
    });
  }
  async send2Friend(shareByEMail: ShareByEMail): Promise<void | ErrorResponse> {
    try {
      ShareByEMailSchema.parse(shareByEMail);
    } catch (error) {
      if (error instanceof ZodError) {
        const formattedErrors = error.errors.map(err => ({
          field: err.path.join('.'),
          message: err.message,
        }));
        throw new BadRequestException(formattedErrors);
      }
      throw error;
    }
    await this.mailerService.sendMail({
      to: shareByEMail.recipientEmail,
      from: `"Bizmatch.net" <info@bizmatch.net>`,
      subject: `${shareByEMail.type === 'business' ? 'Business' : 'Commercial Property'} For Sale: ${shareByEMail.listingTitle}`,
      //template: './inquiry', // `.hbs` extension is appended automatically
      template: join(__dirname, '../..', 'mail/templates/send2Friend.hbs'),
      context: {
        name: shareByEMail.yourName,
        email: shareByEMail.yourEmail,
        listingTitle: shareByEMail.listingTitle,
        url: shareByEMail.url,
        id: shareByEMail.id,
        type: shareByEMail.type,
      },
    });
  }
}
