/**
 * SMTP Configuration Model
 *
 * A collection, not a singleton: the Super Admin can set up several providers at
 * once — Brevo, Zoho Mail, a backup relay — each with its own credentials and
 * sender identity, and mark ONE as the default. Every transactional email (OTP,
 * verification, password reset, notifications) goes out through the default.
 *
 * Keeping them side by side means switching provider is a single click rather
 * than retyping credentials, and a spare configuration can be verified with its
 * own Test button before it is promoted.
 *
 * The password is encrypted at rest with the same AES helper used for payment
 * gateway keys, and is never returned to the client.
 */

import mongoose, { Schema, Document } from 'mongoose';

/**
 * Known provider presets plus `custom` for anything else. The preset only fills
 * in host/port/encryption defaults — every field stays editable, so an
 * unlisted SMTP service works via `custom`.
 */
export type SmtpProviderId =
  | 'brevo'
  | 'zoho'
  | 'gmail'
  | 'sendgrid'
  | 'mailgun'
  | 'ses'
  | 'postmark'
  | 'outlook'
  | 'custom';

/** Transport security. `ssl` = implicit TLS (port 465), `tls` = STARTTLS (587). */
export type SmtpEncryption = 'none' | 'tls' | 'ssl';

export interface ISmtpConfig extends Document {
  /** Label the Super Admin gives this configuration, e.g. "Brevo Production". */
  name: string;
  provider: SmtpProviderId;
  host: string;
  port: number;
  encryption: SmtpEncryption;
  username: string;
  /** AES-encrypted at rest — never sent to the client. */
  password: string;
  senderName: string;
  senderEmail: string;
  /** Optional Reply-To; falls back to senderEmail when blank. */
  replyToEmail?: string;
  /**
   * Per-configuration switch. A disabled configuration is kept for reference but
   * can never be used for sending, and cannot be made the default.
   */
  isActive: boolean;
  /**
   * The one configuration outgoing system email actually uses. Exactly one row
   * carries this; setting it on another clears the previous holder.
   */
  isDefault: boolean;
  /** Reject self-signed/invalid certificates. Off only for internal relays. */
  rejectUnauthorized: boolean;
  // Diagnostics from the last "Test Connection" / "Send Test Email" run
  lastTestedAt?: Date;
  lastTestSuccess?: boolean;
  lastTestMessage?: string;
  updatedBy?: string;
  createdAt: Date;
  updatedAt: Date;
}

const SmtpConfigSchema = new Schema<ISmtpConfig>({
  name: {
    type: String,
    default: '',
    trim: true,
    maxlength: [80, 'Name cannot exceed 80 characters'],
  },
  provider: {
    type: String,
    enum: ['brevo', 'zoho', 'gmail', 'sendgrid', 'mailgun', 'ses', 'postmark', 'outlook', 'custom'],
    default: 'brevo',
  },
  host: { type: String, default: '', trim: true },
  port: { type: Number, default: 587, min: [1, 'Port must be between 1 and 65535'], max: [65535, 'Port must be between 1 and 65535'] },
  encryption: { type: String, enum: ['none', 'tls', 'ssl'], default: 'tls' },
  username: { type: String, default: '', trim: true },
  password: { type: String, default: '' },
  senderName: { type: String, default: '', trim: true, maxlength: [100, 'Sender name cannot exceed 100 characters'] },
  senderEmail: { type: String, default: '', trim: true, lowercase: true },
  replyToEmail: { type: String, default: '', trim: true, lowercase: true },
  isActive: { type: Boolean, default: false },
  isDefault: { type: Boolean, default: false },
  rejectUnauthorized: { type: Boolean, default: true },
  lastTestedAt: { type: Date },
  lastTestSuccess: { type: Boolean },
  lastTestMessage: { type: String },
  updatedBy: { type: String },
}, {
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true },
});

// Sending always resolves through these two flags, so index them together.
SmtpConfigSchema.index({ isDefault: 1, isActive: 1 });
SmtpConfigSchema.index({ createdAt: 1 });

export const SmtpConfig = mongoose.models.SmtpConfig || mongoose.model<ISmtpConfig>('SmtpConfig', SmtpConfigSchema);
