<?php

declare(strict_types=1);

namespace ReallySimplePlugins\RSS\Core\Features\Pro\Vulnerability\Services;

use PleskX\Api\Exception;
use ReallySimplePlugins\RSS\Core\Services\EmailService;
use ReallySimplePlugins\RSS\Core\Support\Helpers\Storages\UriConfig;
use ReallySimplePlugins\RSS\Core\Support\Helpers\Storages\EnvironmentConfig;

/**
 * Sends vulnerability measure emails (Force Update / Quarantine) using the legacy `rsssl_mailer`.
 *
 * This service is called by the measures workflow when an update/quarantine cycle changes state.
 * Each public `send*()` method represents a single email "event".
 *
 * How to add a new email event:
 * 1) Add a new public `sendXxx(string $componentName, int $count): void` method.
 * 2) Keep the subject/title/message/warning block structure consistent with the existing methods.
 * 3) If the new event needs a new manual URL, add it as a constant for easy reuse.
 *
 * Notes:
 * - `$componentName` is a human-readable component name used when only one item is affected.
 * - `$count` represents the number of *additional* components affected besides `$componentName`.
 *   (When `$count > 0`, the copy switches to a "several components" message.)
 */
final class VulnerabilityMeasuresEmailService extends EmailService
{
    /**
     * Send the "Force Update: Scheduled" email.
     *
     * When `$count === 0`, the message references `$componentName` explicitly.
     * When `$count > 0`, the message switches to a generic "several components" text.
     *
     * @param string $componentName Human-readable component name.
     * @param int    $count         Number of additional affected components.
     */
    public function sendUpdateScheduled(string $componentName, int $count): void
    {
        $mailer = $this->getMailer();
        $mailer->subject = sprintf(__('Update Alert: %s', 'really-simple-ssl'), $this->siteUrl());
        $mailer->title = sprintf(__('%s, Force Update: Scheduled.', 'really-simple-ssl'), $this->date());

        $mailer->message = ($count === 0)
            ? sprintf(__('An automatic update for %s has been scheduled due to the discovery of a vulnerability on %s', 'really-simple-ssl'), $componentName, $this->domain())
            : sprintf(__('Several automatic updates for components have been scheduled due to the discovery of vulnerabilities on %s.', 'really-simple-ssl'), $this->domain());

        $mailer->warning_blocks = [[
            'title' => __('Force Update scheduled', 'really-simple-ssl'),
            'message' => __('We will run automatic update cycles to mitigate available vulnerabilities.', 'really-simple-ssl') . ' ' .
                         __('Please double-check if your website is working as expected.', 'really-simple-ssl') . ' ' .
                         sprintf(__('Get more information from the Really Simple Security dashboard on %s', 'really-simple-ssl'), $this->domain()),
            'url' => $this->uriConfig->getUrl('rsp.vul_updates_manual'),
        ]];
        $mailer->send_mail();
    }

    /**
     * Send the "Force Update: Failed" email.
     *
     * When `$count === 0`, the message references `$componentName` explicitly.
     * When `$count > 0`, the message switches to a generic "several components" text.
     *
     * @param string $componentName Human-readable component name.
     * @param int    $count         Number of additional affected components.
     */
    public function sendUpdateFailed(string $componentName, int $count): void
    {
        $mailer = $this->getMailer();
        $mailer->subject = sprintf(__('Update Alert: %s', 'really-simple-ssl'), $this->siteUrl());
        $mailer->title = sprintf(__('%s, Force Update: Failed', 'really-simple-ssl'), $this->date());

        $mailer->message = ($count === 0)
            ? sprintf(__('An automatic update for %s failed on %s.', 'really-simple-ssl'), $componentName, $this->domain())
            : sprintf(__('Several automatic updates for vulnerable components, scheduled on %s, have failed.', 'really-simple-ssl'), $this->domain());

        $mailer->warning_blocks = [[
            'title' => __('Force Update: failed', 'really-simple-ssl'),
            'message' => __('We will retry automatic updates to mitigate available vulnerabilities.', 'really-simple-ssl') . ' ' .
                         __('Please double-check if your website is working as expected.', 'really-simple-ssl') . ' ' .
                         sprintf(__('Get more information from the Really Simple Security dashboard on %s', 'really-simple-ssl'), $this->domain()),
            'url' => $this->uriConfig->getUrl('rsp.vul_updates_manual'),
        ]];

        $mailer->send_mail();
    }

    /**
     * Send the "Force Update: Successful" email.
     *
     * When `$count === 0`, the message references `$componentName` explicitly.
     * When `$count > 0`, the message switches to a generic "several components" text.
     *
     * @param string $componentName Human-readable component name.
     * @param int    $count         Number of additional affected components.
     */
    public function sendUpdateSuccess(string $componentName, int $count): void
    {
        $mailer = $this->getMailer();
        $mailer->subject = sprintf(__('Update Alert: %s', 'really-simple-ssl'), $this->siteUrl());
        $mailer->title = sprintf(__('%s, Force Update: Successful', 'really-simple-ssl'), $this->date());

        $mailer->message = ($count === 0)
            ? sprintf(__('An automatic update for %s has been successful on %s.', 'really-simple-ssl'), $componentName, $this->domain())
            : sprintf(__('Several automatic updates for vulnerable components, scheduled on %s, have been successful.', 'really-simple-ssl'), $this->domain());

        $mailer->warning_blocks = [[
            'title' => __('Verify your website', 'really-simple-ssl'),
            'message' => __('Please double-check if your website is working as expected.', 'really-simple-ssl') . ' ' .
                         sprintf(__('Get more information from the Really Simple Security dashboard on %s', 'really-simple-ssl'), $this->domain()),
            'url' => $this->uriConfig->getUrl('rsp.vul_updates_manual'),
        ]];

        $mailer->send_mail();
    }

    /**
     * Send the "Force Update: End Process" email.
     *
     * When `$count === 0`, the message references `$componentName` explicitly.
     * When `$count > 0`, the message switches to a generic "several components" text.
     *
     * @param string $componentName Human-readable component name.
     * @param int    $count         Number of additional affected components.
     */
    public function sendEndProcess(string $componentName, int $count): void
    {
        $mailer = $this->getMailer();
        $mailer->subject = sprintf(__('Update Alert: %s', 'really-simple-ssl'), $this->siteUrl());
        $mailer->title = sprintf(__('%s, Force Update: End Process', 'really-simple-ssl'), $this->date());

        $mailer->message = ($count === 0)
            ? sprintf(__('An automatic update for %s failed on %s.', 'really-simple-ssl'), $componentName, $this->domain())
            : sprintf(__('Several automatic updates for vulnerable components, scheduled on %s, have failed.', 'really-simple-ssl'), $this->domain());

        $mailer->message .= ' ' . __('This is the end of the update cycle, we recommend manually removing vulnerable components.', 'really-simple-ssl');
        $mailer->message .= ' ' . __('You can also use our ‘Quarantine’ option to automate this process in the future.', 'really-simple-ssl');

        $mailer->warning_blocks = [[
            'title' => __('Verify your website', 'really-simple-ssl'),
            'message' => __('Please double-check if your website is working as expected.', 'really-simple-ssl') . ' ' .
                         sprintf(__('Get more information from the Really Simple Security dashboard on %s', 'really-simple-ssl'), $this->domain()),
            'url' => $this->uriConfig->getUrl('rsp.vul_updates_manual'),
        ]];

        $mailer->send_mail();
    }

    /**
     * Send the "Quarantine: Scheduled" email.
     *
     * When `$count === 0`, the message references `$componentName` explicitly.
     * When `$count > 0`, the message switches to a generic "several components" text.
     *
     * @param string $componentName Human-readable component name.
     * @param int    $count         Number of additional affected components.
     */
    public function sendQuarantineScheduled(string $componentName, int $count): void
    {
        $mailer = $this->getMailer();
        $mailer->subject = sprintf(__('Quarantine Alert: %s', 'really-simple-ssl'), $this->siteUrl());
        $mailer->title = sprintf(__('%s, Quarantine: Scheduled', 'really-simple-ssl'), $this->date());

        $mailer->message = ($count === 0)
            ? sprintf(__('A quarantine for %s scheduled on %s.', 'really-simple-ssl'), $componentName, $this->domain())
            : sprintf(__('Several vulnerable components scheduled for update on %s, have failed.', 'really-simple-ssl'), $this->domain());

        $mailer->warning_blocks = [[
            'title' => __('Quarantine scheduled', 'really-simple-ssl'),
            'message' => __('We will initiate a quarantine cycle to mitigate available vulnerabilities.', 'really-simple-ssl') . ' ' .
                         __('Please double-check if your website is working as expected.', 'really-simple-ssl') . ' ' .
                         sprintf(__('Get more information from the Really Simple Security dashboard on %s', 'really-simple-ssl'), $this->domain()),
            'url' => $this->uriConfig->getUrl('rsp.vul_quarantine_manual'),
        ]];

        $mailer->send_mail();
    }

    /**
     * Send the "Quarantine: Successful" email.
     *
     * When `$count === 0`, the message references `$componentName` explicitly.
     * When `$count > 0`, the message switches to a generic "several components" text.
     *
     * @param string $componentName Human-readable component name.
     * @param int    $count         Number of additional affected components.
     */
    public function sendQuarantineSuccess(string $componentName, int $count): void
    {
        $mailer = $this->getMailer();
        $mailer->subject = sprintf(__('Quarantine Alert: %s', 'really-simple-ssl'), $this->siteUrl());
        $mailer->title = sprintf(__('%s, Quarantine: Successful', 'really-simple-ssl'), $this->date());

        $mailer->message = ($count === 0)
            ? sprintf(__('A quarantine for %s has been successful on %s.', 'really-simple-ssl'), $componentName, $this->domain())
            : sprintf(__('Several vulnerable components quarantined on %s.', 'really-simple-ssl'), $this->domain());

        $mailer->warning_blocks = [[
            'title' => __('Verify your website', 'really-simple-ssl'),
            'message' => __('Please double-check if your website is working as expected.', 'really-simple-ssl') . ' ' .
                         sprintf(__('Get more information from the Really Simple Security dashboard on %s', 'really-simple-ssl'), $this->domain()),
            'url' => $this->uriConfig->getUrl('rsp.vul_quarantine_manual'),
        ]];

        $mailer->send_mail();
    }

    /**
     * Get a localized date string for email titles.
     */
    private function date(): string
    {
        return (string) date_i18n(get_option('date_format'));
    }

    /**
     * Render the site URL as a safe clickable link for email templates.
     */
    private function domain(): string
    {
        $url = $this->siteUrl();

        return '<a href="' . esc_url($url) . '" target="_blank" rel="noopener noreferrer">' . esc_html($url) . '</a>';
    }

    /**
     * Get the current site URL using the correct scheme.
     */
    private function siteUrl(): string
    {
        $scheme = (function_exists('is_ssl') && is_ssl()) ? 'https' : 'http';
        return (string) get_site_url(null, '', $scheme);
    }
}
