import { render } from '@react-email/components';
import { fail, info } from '@zen/core/shared/logger';
import { sendEmail } from '@zen/core/email';
import { VerificationEmail } from './templates/VerificationEmail.js';
import { PasswordResetEmail } from './templates/PasswordResetEmail.js';
import { PasswordChangedEmail } from './templates/PasswordChangedEmail.js';
import { EmailChangeConfirmEmail } from './templates/EmailChangeConfirmEmail.js';
import { EmailChangeNotifyEmail } from './templates/EmailChangeNotifyEmail.js';
import { InvitationEmail } from './templates/InvitationEmail.js';

export { createEmailVerification, verifyEmailToken, createPasswordReset, verifyResetToken, deleteResetToken }
  from '../../core/users/verifications.js';

export { createEmailChangeToken, verifyEmailChangeToken, applyEmailChange }
  from '../../core/users/emailChange.js';

async function sendVerificationEmail(email, token, baseUrl) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const verificationUrl = `${baseUrl}/auth/confirm?email=${encodeURIComponent(email)}&token=${token}`;
  const html = await render(<VerificationEmail verificationUrl={verificationUrl} companyName={appName} />);
  const result = await sendEmail({ to: email, subject: `Confirmez votre adresse courriel – ${appName}`, html });
  if (!result.success) {
    fail(`Auth: failed to send verification email to ${email}: ${result.error}`);
    throw new Error('Failed to send verification email');
  }
  info(`Auth: verification email sent to ${email}`);
  return result;
}

async function sendPasswordResetEmail(email, token, baseUrl) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const resetUrl = `${baseUrl}/auth/reset?email=${encodeURIComponent(email)}&token=${token}`;
  const html = await render(<PasswordResetEmail resetUrl={resetUrl} companyName={appName} />);
  const result = await sendEmail({ to: email, subject: `Réinitialisation du mot de passe – ${appName}`, html });
  if (!result.success) {
    fail(`Auth: failed to send password reset email to ${email}: ${result.error}`);
    throw new Error('Failed to send password reset email');
  }
  info(`Auth: password reset email sent to ${email}`);
  return result;
}

async function sendPasswordChangedEmail(email) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const html = await render(<PasswordChangedEmail email={email} companyName={appName} />);
  const result = await sendEmail({ to: email, subject: `Mot de passe modifié – ${appName}`, html });
  if (!result.success) {
    fail(`Auth: failed to send password changed email to ${email}: ${result.error}`);
    throw new Error('Failed to send password changed email');
  }
  info(`Auth: password changed email sent to ${email}`);
  return result;
}

async function sendEmailChangeConfirmEmail(newEmail, token, baseUrl) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const confirmUrl = `${baseUrl}/admin/confirm-email-change?token=${encodeURIComponent(token)}`;
  const html = await render(<EmailChangeConfirmEmail confirmUrl={confirmUrl} newEmail={newEmail} companyName={appName} />);
  const result = await sendEmail({ to: newEmail, subject: `Confirmez votre nouvelle adresse courriel – ${appName}`, html });
  if (!result.success) {
    fail(`Auth: failed to send email change confirmation to ${newEmail}: ${result.error}`);
    throw new Error('Failed to send email change confirmation');
  }
  info(`Auth: email change confirmation sent to ${newEmail}`);
  return result;
}

async function sendEmailChangeOldNotifyEmail(oldEmail, newEmail, variant) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const subjects = {
    pending: `Demande de modification de courriel – ${appName}`,
    changed: `Votre adresse courriel a été modifiée – ${appName}`,
  };
  const subject = subjects[variant] || subjects.changed;
  const html = await render(<EmailChangeNotifyEmail oldEmail={oldEmail} newEmail={newEmail} variant={variant} companyName={appName} />);
  const result = await sendEmail({ to: oldEmail, subject, html });
  if (!result.success) {
    fail(`Auth: failed to send email change notification to ${oldEmail}: ${result.error}`);
    throw new Error('Failed to send email change notification');
  }
  info(`Auth: email change notification (${variant}) sent to ${oldEmail}`);
  return result;
}

async function sendEmailChangeNewNotifyEmail(newEmail, oldEmail) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const html = await render(<EmailChangeNotifyEmail oldEmail={oldEmail} newEmail={newEmail} variant="admin_new" companyName={appName} />);
  const result = await sendEmail({ to: newEmail, subject: `Votre compte est maintenant associé à cette adresse – ${appName}`, html });
  if (!result.success) {
    fail(`Auth: failed to send email change welcome to ${newEmail}: ${result.error}`);
    throw new Error('Failed to send email change welcome');
  }
  info(`Auth: email change welcome sent to ${newEmail}`);
  return result;
}

async function sendInvitationEmail(email, token, baseUrl) {
  const appName = process.env.ZEN_NAME || 'ZEN';
  const setupUrl = `${baseUrl}/auth/setup?email=${encodeURIComponent(email)}&token=${token}`;
  const html = await render(<InvitationEmail setupUrl={setupUrl} companyName={appName} />);
  const result = await sendEmail({ to: email, subject: `Terminez la création de votre compte – ${appName}`, html });
  if (!result.success) {
    fail(`Auth: failed to send invitation email to ${email}: ${result.error}`);
    throw new Error('Failed to send invitation email');
  }
  info(`Auth: invitation email sent to ${email}`);
  return result;
}

export { sendVerificationEmail, sendPasswordResetEmail, sendPasswordChangedEmail, sendEmailChangeConfirmEmail, sendEmailChangeOldNotifyEmail, sendEmailChangeNewNotifyEmail, sendInvitationEmail };
