import { Resend } from "resend"
import dotenv from "dotenv"
import fs from "fs"
import path from "path"
import { marked } from "marked"
import { STATUS_EMAIL_RECIPIENTS, CRON_EMAIL_SUBJECT_PREFIX } from "../constants/index.js"
dotenv.config()

let resend: Resend | null = null

function getResendClient(): Resend {
  if (!resend) {
    const apiKey = process.env.RESEND_API_KEY
    if (!apiKey) {
      throw new Error("RESEND_API_KEY environment variable is required for email functionality")
    }
    resend = new Resend(apiKey)
  }
  return resend
}

function escapeRegex(string: string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
}

function flattenObject(
  obj: any,
  prefix = "",
  res: Record<string, string> = {},
): Record<string, string> {
  for (const key in obj) {
    const value = obj[key]
    const fullKey = prefix ? `${prefix}.${key}` : key
    if (typeof value === "object" && value !== null) {
      flattenObject(value, fullKey, res)
    } else {
      res[fullKey] = String(value)
    }
  }
  return res
}

export async function loadAndRenderHtml(
  templatePath: string,
  params: Record<string, any>,
): Promise<string> {
  const rawHtml = fs.readFileSync(path.resolve(templatePath), "utf-8")
  const flatParams = flattenObject(params)
  if (flatParams.optimization_explanation) {
    flatParams.optimization_explanation = await marked.parse(flatParams.optimization_explanation)
  }
  let renderedHtml = rawHtml
  for (const [key, value] of Object.entries(flatParams)) {
    const safeKey = escapeRegex(key)
    const regex = new RegExp(`{{\\s*${safeKey}\\s*}}`, "g")
    renderedHtml = renderedHtml.replace(regex, value ?? "")
  }
  return renderedHtml
}

export async function sendEmail({
  to,
  cc,
  subject,
  html,
}: {
  to: string
  cc?: string[]
  subject: string
  html: string
}) {
  const fromEmail = process.env.RESEND_FROM_EMAIL
  if (!fromEmail || fromEmail.trim() === "") {
    throw new Error("RESEND_FROM_EMAIL environment variable is missing or empty")
  }

  // TODO: Add logic to check if the email was already sent (e.g., using a database or cache)

  console.log(fromEmail)

  console.log(
    `Preparing to send email to ${to} with subject "${subject}"${cc ? `, CC: ${cc.join(", ")}` : ""}`,
  )

  const response = await getResendClient().emails.send({
    from: fromEmail,
    to: [to],
    cc,
    subject,
    html,
  })

  console.log(`Email send response: ${JSON.stringify(response)}`)
  return response
}
const templatePath = path.join(process.cwd(), "resend", "./corn-email-template.html")
const templateHtml = fs.readFileSync(templatePath, "utf-8")

export async function sendStatusEmail(
  status: string,
  startTime: Date,
  endTime: Date,
  duration: string,
  errorMessage?: string,
) {
  const html = templateHtml
    .replace("{{status}}", status)
    .replace("{{startTime}}", startTime.toISOString())
    .replace("{{endTime}}", endTime.toISOString())
    .replace("{{duration}}", duration)
    .replace("{{errorMessage}}", errorMessage || "")
  await sendEmail({
    to: STATUS_EMAIL_RECIPIENTS.to,
    cc: STATUS_EMAIL_RECIPIENTS.cc,
    subject: `${CRON_EMAIL_SUBJECT_PREFIX} - ${status}`,
    html,
  })
}
