import type pg from 'pg';
import type { PasswordResetMailer } from '../domain/ports.js';
import { SmtpPasswordResetMailer, type SmtpPasswordResetMailerOptions } from './smtp-password-reset-mailer.js';

const SMTP_KEYS = ['smtp_host', 'smtp_port', 'smtp_secure', 'smtp_user', 'smtp_pass', 'smtp_from'] as const;

/** Reads SMTP credentials from store_settings so admins can change them without a deploy. */
export class SettingsPasswordResetMailer implements PasswordResetMailer {
  constructor(private readonly pool: pg.Pool) {}

  isConfigured(): boolean {
    return true;
  }

  async assertReady(): Promise<void> {
    await this.readMailer();
  }

  async sendPasswordReset(input: { email: string; resetUrl: string; locale?: string }): Promise<void> {
    const mailer = await this.readMailer();
    await mailer.sendPasswordReset(input);
  }

  private async readMailer(): Promise<SmtpPasswordResetMailer> {
    const result = await this.pool.query<{ key: string; value: string }>(
      `SELECT key, value FROM store_settings WHERE key = ANY($1::text[])`,
      [SMTP_KEYS],
    );
    const settings = Object.fromEntries(result.rows.map((row) => [row.key, row.value]));
    const host = settings.smtp_host?.trim();
    const user = settings.smtp_user?.trim();
    const password = settings.smtp_pass;
    const from = settings.smtp_from?.trim() || user;
    if (!host || !user || !password || !from) {
      throw new Error('SMTP is not configured in Ajustes → SMTP / Email');
    }
    const port = Number(settings.smtp_port || '465');
    if (!Number.isInteger(port) || port < 1 || port > 65535) {
      throw new Error('SMTP port is invalid in Ajustes → SMTP / Email');
    }
    const options: SmtpPasswordResetMailerOptions = {
      host,
      port,
      secure: settings.smtp_secure !== 'false' || port === 465,
      user,
      password,
      from,
    };
    return new SmtpPasswordResetMailer(options);
  }
}
