import { ReplitConnectors } from "@replit/connectors-sdk";
import { logger } from "./logger";

// Email is sent via the Replit-managed Gmail connector (connector id
// ccfg_google-mail). The connector proxies Gmail's REST API with automatic
// OAuth token injection/refresh. Messages are sent from the connected
// Google account.
const connectors = new ReplitConnectors();

const FROM_EMAIL = process.env.MAIL_FROM_EMAIL ?? "";
const FROM_NAME = process.env.MAIL_FROM_NAME ?? "Model Directory";

export interface SendEmailParams {
  to: string;
  subject: string;
  html: string;
  text?: string;
}

function buildRawMessage({ to, subject, html }: SendEmailParams): string {
  const from = FROM_EMAIL ? `${FROM_NAME} <${FROM_EMAIL}>` : FROM_NAME;
  const headers = [
    FROM_EMAIL ? `From: ${from}` : null,
    `To: ${to}`,
    `Subject: ${subject}`,
    "MIME-Version: 1.0",
    'Content-Type: text/html; charset="UTF-8"',
    "Content-Transfer-Encoding: 7bit",
  ]
    .filter(Boolean)
    .join("\r\n");
  const message = `${headers}\r\n\r\n${html}`;
  // Gmail expects a base64url-encoded RFC 2822 message.
  return Buffer.from(message)
    .toString("base64")
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/, "");
}

/**
 * Send a transactional email through the Gmail connector. Throws on failure so
 * callers can decide how to handle it (e.g. forgot-password swallows the error
 * to avoid leaking account existence).
 */
export async function sendEmail(params: SendEmailParams): Promise<void> {
  const raw = buildRawMessage(params);
  const response = await connectors.proxy("google-mail", "/gmail/v1/users/me/messages/send", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ raw }),
  });

  if (!response.ok) {
    const body = await response.text().catch(() => "");
    throw new Error(`Gmail send failed: ${response.status} ${body}`);
  }
  logger.info(`[email] sent to=${params.to} subject="${params.subject}"`);
}

export async function sendPasswordResetEmail(to: string, resetUrl: string): Promise<void> {
  const subject = "Reset your Model Directory password";
  const html = `
    <div style="font-family:system-ui,sans-serif;max-width:480px;margin:0 auto;">
      <h2>Reset your password</h2>
      <p>We received a request to reset your password. Click the button below to choose a new one. This link expires in 1 hour.</p>
      <p style="margin:24px 0;">
        <a href="${resetUrl}" style="background:#111;color:#fff;padding:12px 20px;border-radius:8px;text-decoration:none;display:inline-block;">Reset password</a>
      </p>
      <p>If the button doesn't work, copy this link:<br><a href="${resetUrl}">${resetUrl}</a></p>
      <p style="color:#888;font-size:13px;">If you didn't request this, you can safely ignore this email.</p>
    </div>`;
  await sendEmail({ to, subject, html, text: `Reset your password: ${resetUrl}` });
}
