<?php

if (!defined('ABSPATH')) {
    exit;
}

class BSPP_Email_Health {

    public const STATUS_WORKING = 'working';
    public const STATUS_NOT_CONFIGURED = 'not_configured';
    public const STATUS_FAILING = 'failing';

    private const SETTING_STATUS = 'bspp_email_health_status';
    private const SETTING_LAST_ERROR = 'bspp_email_health_last_error';
    private const SETTING_HAS_RUN_ACTIVE_CHECK = 'bspp_email_health_has_run_active_check';

    private const KNOWN_SMTP_PLUGINS = [
        'wp-mail-smtp/wp_mail_smtp.php',
        'easy-wp-smtp/easy-wp-smtp.php',
    ];

    private $settings;

    /** @var bool Whether bspp_send_test_email() is currently in progress. */
    private $bspp_test_send_in_progress = false;

    /** @var WP_Error|null Captured failure during an active test send. */
    private $bspp_test_send_error = null;

    public function __construct() {
        $this->settings = new BSPP_Settings_Repository();
        add_action('wp_mail_failed', [$this, 'bspp_handle_wp_mail_failed']);
        add_action('init', [$this, 'bspp_detect_smtp_plugin']);
    }

    /**
     * Passive check: detect whether a known SMTP plugin is active.
     * Initial default only — never overrides a status confirmed by an active test send.
     */
    public function bspp_detect_smtp_plugin() {
        if ($this->bspp_has_run_active_check()) {
            return;
        }

        if ($this->bspp_get_email_status() !== self::STATUS_NOT_CONFIGURED) {
            return;
        }

        if (!$this->bspp_is_known_smtp_plugin_active()) {
            $this->bspp_set_status(self::STATUS_NOT_CONFIGURED);
            $this->bspp_set_last_error(null);
        }
    }

    /**
     * Active check: send a real test email and update stored status.
     *
     * @param string $to_email Recipient address (typically the logged-in admin's email).
     * @return true|WP_Error True on success, WP_Error on failure.
     */
    public function bspp_send_test_email($to_email) {
        $to_email = sanitize_email($to_email);
        if ($to_email === '' || !is_email($to_email)) {
            return new WP_Error('bspp_invalid_email', 'A valid email address is required.');
        }

        $this->bspp_test_send_in_progress = true;
        $this->bspp_test_send_error = null;

        $subject = 'Bobasoftware Publisher Paywall test email';
        $body = 'This is a test email from Bobasoftware Publisher Paywall. If you received this message, outbound email delivery is working on your site.';

        $sent = wp_mail($to_email, $subject, $body);

        $this->bspp_test_send_in_progress = false;

        if ($this->bspp_test_send_error instanceof WP_Error) {
            $message = $this->bspp_test_send_error->get_error_message();
            $this->bspp_set_status(self::STATUS_FAILING);
            $this->bspp_set_last_error($message);
            $this->bspp_set_has_run_active_check(true);

            return new WP_Error('bspp_test_email_failed', $message, $this->bspp_test_send_error);
        }

        if (!$sent) {
            $message = 'wp_mail() returned false without a detailed error.';
            $this->bspp_set_status(self::STATUS_FAILING);
            $this->bspp_set_last_error($message);
            $this->bspp_set_has_run_active_check(true);

            return new WP_Error('bspp_test_email_failed', $message);
        }

        $this->bspp_set_status(self::STATUS_WORKING);
        $this->bspp_set_last_error(null);
        $this->bspp_set_has_run_active_check(true);

        return true;
    }

    /**
     * Global wp_mail failure monitor (production sends and test sends).
     *
     * @param WP_Error $wp_error Mail failure details from WordPress.
     */
    public function bspp_handle_wp_mail_failed($wp_error) {
        if (!($wp_error instanceof WP_Error)) {
            return;
        }

        if ($this->bspp_test_send_in_progress) {
            $this->bspp_test_send_error = $wp_error;
            return;
        }

        $this->bspp_set_status(self::STATUS_FAILING);
        $this->bspp_set_last_error($wp_error->get_error_message());
    }

    public function bspp_get_email_status() {
        $status = $this->settings->get(self::SETTING_STATUS, self::STATUS_NOT_CONFIGURED);

        if (!in_array($status, [self::STATUS_WORKING, self::STATUS_NOT_CONFIGURED, self::STATUS_FAILING], true)) {
            return self::STATUS_NOT_CONFIGURED;
        }

        return $status;
    }

    public function bspp_get_last_error() {
        $error = $this->settings->get(self::SETTING_LAST_ERROR, null);

        if ($error === null || $error === '') {
            return null;
        }

        return (string) $error;
    }

    public function bspp_has_run_active_check() {
        return (bool) (int) $this->settings->get(self::SETTING_HAS_RUN_ACTIVE_CHECK, 0);
    }

    private function bspp_is_known_smtp_plugin_active() {
        if (!function_exists('is_plugin_active')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        foreach (self::KNOWN_SMTP_PLUGINS as $plugin_file) {
            if (is_plugin_active($plugin_file)) {
                return true;
            }
        }

        return false;
    }

    private function bspp_set_status($status) {
        $this->settings->set(self::SETTING_STATUS, $status);
    }

    private function bspp_set_last_error($error) {
        $this->settings->set(self::SETTING_LAST_ERROR, $error);
    }

    private function bspp_set_has_run_active_check($has_run) {
        $this->settings->set(self::SETTING_HAS_RUN_ACTIVE_CHECK, $has_run ? 1 : 0);
    }
}
