<?php
/**
 * Amazon SES Mailer.
 *
 * @package NimblyMail\SMTP
 */

namespace NimblyMail\SMTP\Mailers;

use PHPMailer\PHPMailer\PHPMailer;

defined( 'ABSPATH' ) || exit;

/**
 * Class SesMailer
 *
 * Sends email via Amazon SES SMTP.
 *
 * @since 1.0.0
 */
class SesMailer extends AbstractMailer {

    /**
     * {@inheritdoc}
     */
    public function get_slug(): string {
        return 'ses';
    }

    /**
     * {@inheritdoc}
     */
    public function get_title(): string {
        return __( 'Amazon SES', 'nimblymail-smtp' );
    }

    /**
     * Get the mailer description shown in the mailer-cards selector.
     *
     * @since 1.0.0
     *
     * @return string
     */
    public function get_description(): string {
        return __( 'Send via AWS Simple Email Service.', 'nimblymail-smtp' );
    }

    /**
     * Get the settings schema for this mailer as a section-shaped array.
     *
     * @since 1.0.0 Migrated to section-shaped return for SettingsProvider loop.
     *
     * @return array Section descriptor with id, title, description, help_url, and fields.
     */
    public function get_settings_fields(): array {
        return array(
            'id'          => 'ses_settings',
            'title'       => __( 'Amazon SES', 'nimblymail-smtp' ),
            'description' => __( 'Connect to Amazon Simple Email Service.', 'nimblymail-smtp' ),
            'help_url'    => 'https://console.aws.amazon.com/iam/home#/security_credentials',
            'fields'      => array(
                array(
                    'id'        => 'access_key_id',
                    'group'     => 'ses',
                    'title'     => __( 'Access Key ID', 'nimblymail-smtp' ),
                    'type'      => 'text',
                    'required'  => true,
                    'encrypted' => true,
                ),
                array(
                    'id'        => 'secret_access_key',
                    'group'     => 'ses',
                    'title'     => __( 'Secret Access Key', 'nimblymail-smtp' ),
                    'type'      => 'password',
                    'required'  => true,
                    'encrypted' => true,
                ),
                array(
                    'id'      => 'region',
                    'group'   => 'ses',
                    'title'   => __( 'Region', 'nimblymail-smtp' ),
                    'type'    => 'select',
                    'default' => 'us-east-1',
                    'options' => self::get_region_options(),
                ),
            ),
        );
    }

    /**
     * Get the complete list of AWS regions that support the SES SMTP interface.
     *
     * Region codes map to `email-smtp.{region}.amazonaws.com` endpoints.
     * Regions without SMTP support (Cape Town, Hyderabad, Jakarta, Milan,
     * Zurich, Tel Aviv, Bahrain, UAE, Calgary, Malaysia) are intentionally
     * omitted because they would fail to connect.
     *
     * @since 1.0.0
     *
     * @return array<string, string> Map of region code to human-readable name.
     */
    public static function get_region_options(): array {
        return array(
            'us-east-1'      => __( 'US East (N. Virginia)', 'nimblymail-smtp' ),
            'us-east-2'      => __( 'US East (Ohio)', 'nimblymail-smtp' ),
            'us-west-1'      => __( 'US West (N. California)', 'nimblymail-smtp' ),
            'us-west-2'      => __( 'US West (Oregon)', 'nimblymail-smtp' ),
            'ap-south-1'     => __( 'Asia Pacific (Mumbai)', 'nimblymail-smtp' ),
            'ap-northeast-1' => __( 'Asia Pacific (Tokyo)', 'nimblymail-smtp' ),
            'ap-northeast-2' => __( 'Asia Pacific (Seoul)', 'nimblymail-smtp' ),
            'ap-northeast-3' => __( 'Asia Pacific (Osaka)', 'nimblymail-smtp' ),
            'ap-southeast-1' => __( 'Asia Pacific (Singapore)', 'nimblymail-smtp' ),
            'ap-southeast-2' => __( 'Asia Pacific (Sydney)', 'nimblymail-smtp' ),
            'ca-central-1'   => __( 'Canada (Central)', 'nimblymail-smtp' ),
            'eu-central-1'   => __( 'Europe (Frankfurt)', 'nimblymail-smtp' ),
            'eu-west-1'      => __( 'Europe (Ireland)', 'nimblymail-smtp' ),
            'eu-west-2'      => __( 'Europe (London)', 'nimblymail-smtp' ),
            'eu-west-3'      => __( 'Europe (Paris)', 'nimblymail-smtp' ),
            'eu-north-1'     => __( 'Europe (Stockholm)', 'nimblymail-smtp' ),
            'sa-east-1'      => __( 'South America (São Paulo)', 'nimblymail-smtp' ),
            'us-gov-west-1'  => __( 'AWS GovCloud (US-West)', 'nimblymail-smtp' ),
            'us-gov-east-1'  => __( 'AWS GovCloud (US-East)', 'nimblymail-smtp' ),
        );
    }

    /**
     * Configure the PHPMailer instance for Amazon SES transport.
     *
     * @since 1.0.0
     *
     * @param PHPMailer $phpmailer The PHPMailer instance.
     */
    public function configure( PHPMailer $phpmailer ): void {
        $region = $this->get_option( 'region' );
        if ( empty( $region ) ) {
            $region = 'us-east-1';
        }

        $phpmailer->isSMTP();
        $phpmailer->Host       = "email-smtp.{$region}.amazonaws.com";
        $phpmailer->Port       = 587;
        $phpmailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $phpmailer->SMTPAuth   = true;
        $phpmailer->Username   = $this->get_option( 'access_key_id' );

        $secret = $this->get_option( 'secret_access_key' );
        if ( ! empty( $secret ) ) {
            // get_option() auto-decrypts sensitive fields.
            $phpmailer->Password = $secret;
        }
    }

    /**
     * Get this mailer's deliverability audit requirements.
     *
     * SES DKIM uses three CNAME records pointing at amazonses.com — there
     * is no fixed selector list at the protocol level, so we leave selectors
     * empty (informational) and check only the SPF include.
     *
     * @since 1.0.0
     *
     * @return array{spf_includes: string[], dkim_selectors: string[], docs_url: string}
     */
    public function get_audit_requirements(): array {
        return array(
            'spf_includes'   => array( 'amazonses.com' ),
            'dkim_selectors' => array(),
            'docs_url'       => 'https://docs.aws.amazon.com/ses/latest/dg/send-email-authentication-spf.html',
        );
    }

    /**
     * Get the connectivity endpoints for the Amazon SES SMTP mailer.
     *
     * Returns the regional SMTP host and port to allow the HealthAuditor
     * to perform an outbound socket check.
     *
     * @since 1.0.0
     *
     * @return array<array<string, mixed>>
     */
    public function get_connectivity_endpoints(): array {
        $region = (string) $this->get_option( 'region' );
        if ( '' === $region ) {
            $region = 'us-east-1';
        }

        return array(
            array(
                'type' => 'smtp',
                'host' => "email-smtp.{$region}.amazonaws.com",
                'port' => 587,
            ),
        );
    }
}
