<?php
namespace RSSSL\Security\WordPress\Two_Fa\Services;

use rsssl_mailer;
use RSSSL\Security\WordPress\Two_Fa\Rsssl_Two_Factor_Settings;
use RSSSL\Security\WordPress\Two_Fa\Contracts\Rsssl_Two_Fa_User_Repository_Interface;
use RSSSL\Security\WordPress\Two_Fa\Models\Rsssl_Two_FA_Data_Parameters;
use RSSSL\Security\WordPress\Two_Fa\Models\Rsssl_Two_Fa_User_Collection;
use RSSSL\Security\WordPress\Two_Fa\Repositories\Rsssl_Two_Fa_User_Repository;

class Rsssl_Two_Fa_Reminder_Service {

    private Rsssl_Two_Fa_User_Repository_Interface $userRepository;

    /**
     * Constructor.
     *
     * Here we hook our process method to a custom WP action.
     */
    public function __construct() {
        $this->userRepository = new Rsssl_Two_Fa_User_Repository();
        add_action('rsssl_process_two_fa_reminders', [$this, 'processReminders']);
    }

    /**
     * Kick off the reminder e‑mail process.
     *
     * Checks whether forced roles are set and then schedules a WP event
     * to process the reminder emails in a separate request.
     *
     * @return bool
     */
    public function maybeSendReminderEmails(array $forcedRoles):bool
    {
        // If no forced roles have been defined, there is nothing to do.
        if (empty($forcedRoles)) {
            update_option('rsssl_two_fa_reminder_pending', false, false);
            return false;
        }

        // Checking if there are users within the grace period who have not yet configured 2FA.
        $params = new Rsssl_Two_FA_Data_Parameters([
            'filter_column' => 'user_role',
            'filter_value'  => 'all',
        ]);
        $users = $this->userRepository->getForcedTwoFaUsersWithOpenStatus($params);

        $this->processReminders($users);

        // no further processing is pending. So we return true.
        return true;
    }

    /**
     * Process and send reminder emails to users who have not yet configured 2FA.
     *
     * This method is hooked to a WP action and is executed via a scheduled event.
     *
     * @return void
     */
    public function processReminders(Rsssl_Two_Fa_User_Collection $collection ): void
    {
        // if the collection has no users, there is nothing to do.
        if ($collection->getTotalRecords() === 0) {
            return;
        }

        $usersToRemind = $collection->getUsersToRemind();

        // if the collection has no users to remind, there is nothing to do.
        if (count($usersToRemind) === 0) {
            return;
        }

        // Preparing the reminder e‑mail.
        // Load the mailer class if it hasn't been loaded yet.
        if (!class_exists('rsssl_mailer')) {
            require_once rsssl_path . 'mailer/class-mail.php';
        }

        // Build the e‑mail subject.
        $subject = __("Important security notice", "really-simple-ssl");

        // Determine the login URL – use the custom login URL if one is set.
        $login_url = wp_login_url();
        if (function_exists('rsssl_get_option') && rsssl_get_option('change_login_url_enabled') !== false && !empty(rsssl_get_option('change_login_url'))) {
            $login_url = trailingslashit(site_url()) . rsssl_get_option('change_login_url');
        }

        // Build a login link.
        $login_link = sprintf(
            '<a href="%s">%s</a>',
            esc_url($login_url),
            __('Please login', 'really-simple-ssl')
        );

        $message = sprintf(
        /* translators:
        1: Site URL.
        */
            __("You are receiving this email because you have an account registered at %s.", "really-simple-ssl"),
            site_url(),
        );
        $message .= "<br><br>";
        $message .= sprintf(
        /* translators:
        1: Login link with the text "Please login".
        2: Opening <strong> tag to emphasize the "within three days" text.
        3: Closing </strong> tag for "within three days".
        4: Opening <strong> tag to emphasize "you will be unable to login".
        5 Closing </strong> tag for "you will be unable to login".
        */

            __("The site's security policy requires you to configure Two-Factor Authentication to protect against account theft. %1\$s and configure Two-Factor authentication %2\$swithin three days%3\$s. If you haven't performed the configuration by then, %4\$syou will be unable to login%5\$s.", "really-simple-ssl"),
            $login_link,
            '<strong>',
            '</strong>',
            '<strong>',
            '</strong>'
        );

        $mailer                    = new rsssl_mailer();
        $mailer->subject           = $subject;
        $mailer->branded           = false;
        $mailer->sent_by_text      = "<b>".sprintf( __( 'Notification by %s', 'really-simple-ssl' ), site_url() )."</b>";
        $mailer->message           = $message;


        // Process each user in the grace period who still needs to set up 2FA.
        foreach ($usersToRemind as $user) {
            if ( ! Rsssl_Two_Factor_Settings::is_user_forced_to_use_2fa( $user->getId() ) ) {
                continue;
            }

            // Skip if the reminder has already been sent.
            $two_fa_reminder_sent = get_user_meta($user->getId(), 'rsssl_two_fa_reminder_sent', true);
            if ($two_fa_reminder_sent) {
                continue;
            }

            $email = get_userdata($user->getId())->user_email;
            $first_name = get_userdata($user->getId())->first_name;
            $last_name = get_userdata($user->getId())->last_name;

            // Prepare and send the e‑mail.
            $mailer->template_filename = apply_filters('rsssl_email_template', rsssl_path . '/mailer/templates/email-unbranded.html');
            $mailer->to = $email;
            $mailer->title = sprintf(
                /* translators:
                   %s: First name.
                   %s: Last name.
                */
                    __('Hi %s %s', 'really-simple-ssl'),
                    trim($first_name),
                    trim($last_name)
                ) . ',';
            $mailer->message = $message;
            $mailer->send_mail();

            // Mark that the reminder e‑mail has been sent for this user.
            update_user_meta($user->getId(), 'rsssl_two_fa_reminder_sent', true);
        }

        // Optionally, update a flag to indicate that no further processing is pending.
        update_option('rsssl_two_fa_reminder_pending', false, false);
    }
}
