import nodemailer from "nodemailer";
import type { DepartmentKey, RoleKey } from "@prisma/client";
import { getBaseAppUrl } from "@/lib/app-url";
import { getDepartmentLabel } from "@/lib/departments";
import { ROLE_LABELS } from "@/lib/utils";

type SendInvitationEmailInput = {
  toEmail: string;
  token: string;
  inviteeName: string;
  roleKey: RoleKey;
  department: DepartmentKey;
  departmentRole: string;
  expiresAt: Date;
  invitedByName?: string | null;
};

function parseBoolean(value: string | undefined, fallback: boolean) {
  if (!value) {
    return fallback;
  }
  return value.toLowerCase() === "true";
}

function parsePort(value: string | undefined, fallback: number) {
  const parsed = Number(value);
  return Number.isInteger(parsed) ? parsed : fallback;
}

function getSmtpConfig() {
  const host = process.env.SMTP_HOST;
  const user = process.env.SMTP_USER;
  const pass = process.env.SMTP_PASS;
  const from = process.env.SMTP_FROM;
  const port = parsePort(process.env.SMTP_PORT, 465);
  const secure = parseBoolean(process.env.SMTP_SECURE, true);

  if (!host || !user || !pass || !from) {
    return null;
  }

  return {
    host,
    port,
    secure,
    auth: {
      user,
      pass,
    },
    from,
  };
}

export function isSmtpConfigured() {
  return getSmtpConfig() !== null;
}

export async function sendInvitationEmail(input: SendInvitationEmailInput) {
  const smtpConfig = getSmtpConfig();
  if (!smtpConfig) {
    throw new Error("SMTP is not configured. Missing SMTP_HOST/SMTP_USER/SMTP_PASS/SMTP_FROM.");
  }

  const inviteUrl = new URL("/accept-invitation", getBaseAppUrl());
  inviteUrl.searchParams.set("token", input.token);
  inviteUrl.searchParams.set("email", input.toEmail);

  const transporter = nodemailer.createTransport({
    host: smtpConfig.host,
    port: smtpConfig.port,
    secure: smtpConfig.secure,
    auth: smtpConfig.auth,
  });

  const inviter = input.invitedByName?.trim() || "Casa Benell";
  const departmentLabel = getDepartmentLabel(input.department);
  const platformRoleLabel = ROLE_LABELS[input.roleKey];

  await transporter.sendMail({
    from: smtpConfig.from,
    to: input.toEmail,
    subject: "Invitacion a Casa Benell",
    text: [
      `Hola ${input.inviteeName},`,
      ``,
      `${inviter} te invito a Casa Benell.`,
      `Departamento: ${departmentLabel}`,
      `Rol dentro del departamento: ${input.departmentRole}`,
      `Nivel de acceso: ${platformRoleLabel}`,
      `Acepta tu invitacion aqui: ${inviteUrl.toString()}`,
      `Expira: ${input.expiresAt.toISOString()}`,
    ].join("\n"),
    html: `
      <p>Hola ${input.inviteeName},</p>
      <p><strong>${inviter}</strong> te invito a Casa Benell.</p>
      <p>Departamento: <strong>${departmentLabel}</strong></p>
      <p>Rol dentro del departamento: <strong>${input.departmentRole}</strong></p>
      <p>Nivel de acceso: <strong>${platformRoleLabel}</strong></p>
      <p><a href="${inviteUrl.toString()}">Aceptar invitacion</a></p>
      <p>Expira: ${input.expiresAt.toISOString()}</p>
    `,
  });
}

type SendVerificationEmailInput = {
  toEmail: string;
  token: string;
};

export async function sendEmailVerificationEmail(input: SendVerificationEmailInput) {
  const smtpConfig = getSmtpConfig();
  if (!smtpConfig) {
    throw new Error("SMTP is not configured. Missing SMTP_HOST/SMTP_USER/SMTP_PASS/SMTP_FROM.");
  }

  const verifyUrl = new URL("/api/auth/verify-email", getBaseAppUrl());
  verifyUrl.searchParams.set("token", input.token);
  verifyUrl.searchParams.set("email", input.toEmail);

  const transporter = nodemailer.createTransport({
    host: smtpConfig.host,
    port: smtpConfig.port,
    secure: smtpConfig.secure,
    auth: smtpConfig.auth,
  });

  await transporter.sendMail({
    from: smtpConfig.from,
    to: input.toEmail,
    subject: "Verifica tu correo en Casa Benell",
    text: [
      "Hola,",
      "",
      "Confirma tu cuenta para poder iniciar sesion:",
      verifyUrl.toString(),
    ].join("\n"),
    html: `
      <p>Hola,</p>
      <p>Confirma tu cuenta para poder iniciar sesión:</p>
      <p><a href="${verifyUrl.toString()}">Verificar correo</a></p>
    `,
  });
}

type SendPasswordResetEmailInput = {
  toEmail: string;
  token: string;
};

export async function sendPasswordResetEmail(input: SendPasswordResetEmailInput) {
  const smtpConfig = getSmtpConfig();
  if (!smtpConfig) {
    throw new Error("SMTP is not configured. Missing SMTP_HOST/SMTP_USER/SMTP_PASS/SMTP_FROM.");
  }

  const resetUrl = new URL("/reset-password", getBaseAppUrl());
  resetUrl.searchParams.set("token", input.token);
  resetUrl.searchParams.set("email", input.toEmail);

  const transporter = nodemailer.createTransport({
    host: smtpConfig.host,
    port: smtpConfig.port,
    secure: smtpConfig.secure,
    auth: smtpConfig.auth,
  });

  await transporter.sendMail({
    from: smtpConfig.from,
    to: input.toEmail,
    subject: "Recupera tu contrasena en Casa Benell",
    text: [
      "Hola,",
      "",
      "Recibimos una solicitud para restablecer tu contrasena.",
      "Si fuiste tu, usa este enlace:",
      resetUrl.toString(),
      "",
      "Si no solicitaste este cambio, ignora este mensaje.",
    ].join("\n"),
    html: `
      <p>Hola,</p>
      <p>Recibimos una solicitud para restablecer tu contraseña.</p>
      <p>Si fuiste tú, usa este enlace:</p>
      <p><a href="${resetUrl.toString()}">Restablecer contraseña</a></p>
      <p>Si no solicitaste este cambio, ignora este mensaje.</p>
    `,
  });
}
