import { getError } from "@pkg/logger";
import { ERROR_CODES, type Result } from "@pkg/result";
import { createElement } from "react";
import { Resend } from "resend";
import PnrConfirmationEmail from "../emails/uid-confirmation";
import { type EmailPayload, type EmailServiceProvider } from "./data";

export class ResendEmailSvcProvider implements EmailServiceProvider {
  private client: Resend | null = null;

  constructor(private apiKey: string) {}

  initialize(): Result<boolean> {
    try {
      this.client = new Resend(this.apiKey);
      return { data: true };
    } catch (e) {
      return {
        error: getError(
          {
            code: ERROR_CODES.INTERNAL_SERVER_ERROR,
            message: "Failed to initialize Resend client",
            userHint: "Please check API key configuration",
            detail: "Error initializing Resend client",
          },
          e,
        ),
      };
    }
  }

  async sendEmail(payload: EmailPayload): Promise<Result<boolean>> {
    try {
      if (!this.client) {
        const initResult = this.initialize();
        if (initResult.error) return initResult;
      }

      await this.client!.emails.send({
        from: payload.from || "onboarding@resend.dev",
        to: payload.to,
        subject: payload.subject,
        html: payload.html ?? "",
        text: payload.text,
        cc: payload.cc,
        bcc: payload.bcc,
        attachments: payload.attachments,
      });

      return { data: true };
    } catch (e) {
      return {
        error: getError(
          {
            code: ERROR_CODES.INTERNAL_SERVER_ERROR,
            message: "Failed to send email",
            userHint: "Please try again later",
            detail: "Error sending email via Resend",
          },
          e,
        ),
      };
    }
  }

  async sendEmailWithReact(payload: {
    to: string;
    subject: string;
    from: string;
    cc?: string[];
    bcc?: string[];
    attachments?: any[];
    template: string;
    templateData: any;
  }): Promise<Result<boolean>> {
    try {
      if (!this.client) {
        const initResult = this.initialize();
        if (initResult.error) return initResult;
      }

      let body = undefined as any;

      switch (payload.template) {
        case "uid-confirmation":
          body = createElement(PnrConfirmationEmail, payload.templateData);
          break;
        default:
          return {
            error: getError(
              {
                code: ERROR_CODES.INTERNAL_SERVER_ERROR,
                message: "Unsupported email template",
                userHint: "Please check email configuration",
                detail: "Unsupported email template",
              },
              new Error("Unsupported email template"),
            ),
          };
      }

      await this.client!.emails.send({
        from: payload.from,
        to: payload.to,
        subject: payload.subject,
        cc: payload.cc,
        bcc: payload.bcc,
        attachments: payload.attachments,
        react: body,
      });

      return { data: true };
    } catch (e) {
      return {
        error: getError(
          {
            code: ERROR_CODES.INTERNAL_SERVER_ERROR,
            message: "Failed to send email with React template",
            userHint: "Please try again later",
            detail: "Error sending email via Resend",
          },
          e,
        ),
      };
    }
  }
}
