<?php

use MemberPress\GroundLevel\Container\Concerns\InjectsDependencies;
use MemberPress\GroundLevel\Mothership\AbstractPluginConnection;
use MemberPress\GroundLevel\Mothership\Credentials;
use MemberPress\GroundLevel\Mothership\Manager\LicenseManager;

if (! defined('ABSPATH')) {
    die('You are not allowed to call this page directly.');
}

/**
 * DRM controller.
 *
 * @property MemberPress\GroundLevel\Mothership\Credentials              $credentials
 * @property MemberPress\GroundLevel\Mothership\Manager\LicenseManager   $license_manager
 * @property MemberPress\GroundLevel\Mothership\AbstractPluginConnection $plugin
 */
class MeprDrmCtrl extends MeprBaseCtrl
{
    use InjectsDependencies;

    /**
     * Defines the dependencies to be injected.
     */
    protected function inject(): array
    {
        return [
            'credentials'     => Credentials::class,
            'license_manager' => LicenseManager::class,
            'plugin'          => AbstractPluginConnection::class,
        ];
    }

    /**
     * Load the hooks for this controller
     */
    public function load_hooks()
    {
        add_action("{$this->plugin->pluginId}_license_activated", [$this, 'drm_license_activated']);
        add_action("{$this->plugin->pluginId}_license_deactivated", [$this, 'drm_license_deactivated']);
        add_action("{$this->plugin->pluginId}_active_license_expired", [$this, 'drm_license_invalid_expired']);
        add_action("{$this->plugin->pluginId}_active_license_invalidated", [$this, 'drm_license_invalid_expired']);
        add_action('wp_ajax_mepr_dismiss_notice_drm', [$this, 'drm_dismiss_notice']);
        add_action('wp_ajax_mepr_drm_activate_license', [$this, 'ajax_drm_activate_license']);
        add_action('admin_menu', [$this, 'drm_init'], 1);
        add_action('admin_init', [$this, 'drm_throttle'], 20);
        add_action('admin_footer', [$this, 'drm_menu_append_alert']);
        add_filter('site_status_tests', ['MeprDrmDebugHelper', 'site_health_debug_status'], 1);
    }

    /**
     * DRM license activated.
     *
     * @return void
     */
    public function drm_license_activated()
    {
        delete_option('mepr_drm_no_license');
        delete_option('mepr_drm_invalid_license');

        // The cached checkout fee percent reflects the previous license
        // state, so drop it — the newly licensed site must not keep stamping
        // the unlicensed rate for up to a day.
        MeprStripeFeeService::clear_cache();

        // Delete DRM notices.
        $notiications = new MeprNotifications();
        $notiications->dismiss_events('mepr-drm');
    }

    /**
     * DRM license deactivated.
     *
     * @return void
     */
    public function drm_license_deactivated()
    {
        // The cached fee percent reflects the previous license state; drop it
        // so the next checkout re-resolves under the new one.
        MeprStripeFeeService::clear_cache();

        $drm_no_license = get_option('mepr_drm_no_license', false);

        if (! $drm_no_license) {
            delete_option('mepr_drm_invalid_license');

            // Set no license.
            update_option('mepr_drm_no_license', true);

            $drm = new MeprDrmNokey();
            $drm->create_event();
        }
    }

    /**
     * DRM license invalid expired.
     *
     * @return void
     */
    public function drm_license_invalid_expired()
    {
        // The cached fee percent reflects the previous license state; drop it
        // so the next checkout re-resolves under the new one.
        MeprStripeFeeService::clear_cache();

        $drm_invalid_license = get_option('mepr_drm_invalid_license', false);

        if (! $drm_invalid_license) {
            delete_option('mepr_drm_no_license');

            // Set invalid license.
            update_option('mepr_drm_invalid_license', true);

            $drm = new MeprDrmInvalid();
            $drm->create_event();
        }
    }

    /**
     * DRM dismiss notice.
     *
     * @return void
     */
    public static function drm_dismiss_notice()
    {
        if (check_ajax_referer('mepr_dismiss_notice', false, false) && isset($_POST['notice']) && is_string($_POST['notice'])) {
            $notice       = sanitize_key($_POST['notice'] ?? '');
            $secret       = sanitize_key($_POST['secret'] ?? '');
            $secret_parts = explode('-', $secret);
            $notice_hash  = $secret_parts[0];
            $event_hash   = $secret_parts[1];
            $notice_key   = MeprDrmHelper::prepare_dismissable_notice_key($notice);

            if ($notice_hash === sha1($notice)) {
                $event = null;
                if (sha1(MeprDrmHelper::NO_LICENSE_EVENT) === $event_hash) {
                    $event = MeprEvent::latest(MeprDrmHelper::NO_LICENSE_EVENT);
                } elseif (sha1(MeprDrmHelper::INVALID_LICENSE_EVENT) === $event_hash) {
                    $event = MeprEvent::latest(MeprDrmHelper::INVALID_LICENSE_EVENT);
                }

                if ($event && is_object($event)) {
                    if ($event->rec->id > 0) {
                        $event_data                = MeprDrmHelper::parse_event_args($event->args);
                        $event_data[ $notice_key ] = time();
                        $event->args               = json_encode($event_data);
                        $event->store();
                    }
                }
            }
        }

        wp_send_json_success();
    }

    /**
     * DRM init.
     *
     * @return void
     */
    public function drm_init()
    {
        if (! MeprDrmHelper::is_drm_enabled()) {
            return;
        }

        if (MeprDrmHelper::is_valid()) {
            return; // Bail.
        }

        $drm_no_license      = get_option('mepr_drm_no_license', false);
        $drm_invalid_license = get_option('mepr_drm_invalid_license', false);

        if ($drm_no_license) {
            $drm = new MeprDrmNokey();
            $drm->run();
        } elseif ($drm_invalid_license) {
            $drm = new MeprDrmInvalid();
            $drm->run();
        }
    }

    /**
     * DRM throttle.
     *
     * @return void
     */
    public function drm_throttle()
    {
        if (! MeprDrmHelper::is_drm_enabled()) {
            return;
        }

        if (wp_doing_ajax()) {
            return;
        }

        if (MeprDrmHelper::is_locked()) {
            $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification

            if ('memberpress-members' === $page) {
                $action = isset($_GET['action']) ? sanitize_text_field(wp_unslash($_GET['action'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification

                if ('new' === $action) {
                    wp_die(__('Sorry, you are not allowed to access this page.', 'memberpress')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                }

                if (MeprUtils::is_post_request() && 'create' === $action) {
                    wp_die(__('Sorry, you are not allowed to access this page.', 'memberpress')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
                }
            }
        }
    }

    /**
     * AJAX DRM activate license.
     *
     * @return void
     */
    public function ajax_drm_activate_license()
    {
        if (! MeprUtils::is_post_request() || ! isset($_POST['key']) || ! is_string($_POST['key'])) {
            wp_send_json_error(sprintf(
                // Translators: %s: error message.
                __('An error occurred during activation: %s', 'memberpress'),
                __('Bad request.', 'memberpress')
            ));
        }

        if (! MeprUtils::is_logged_in_and_an_admin()) {
            wp_send_json_error(__('Sorry, you don\'t have permission to do this.', 'memberpress'));
        }

        if (! check_ajax_referer('mepr_drm_activate_license', false, false)) {
            wp_send_json_error(sprintf(
                // Translators: %s: error message.
                __('An error occurred during activation: %s', 'memberpress'),
                __('Security check failed.', 'memberpress')
            ));
        }

        $license_key = sanitize_text_field(wp_unslash($_POST['key']));
        $domain      = $this->credentials->getDomain();
        $result      = $this->license_manager->activateLicense($license_key, $domain);

        if ($result->isSuccess()) {
            $output = esc_html($result->getMessage());
            wp_send_json_success($output);
        } else {
            wp_send_json_error($result->getMessage());
        }
    }

    /**
     * DRM menu append alert.
     *
     * @return void
     */
    public function drm_menu_append_alert()
    {
        if (! MeprDrmHelper::is_locked()) {
            return;
        }
        ?>
        <script>
        jQuery(function ($) {
            $('li.toplevel_page_memberpress-drm .wp-menu-name').append('<span class="awaiting-mod"><span class="pending-count" id="meprDrmAdminMenuUnreadCount" aria-hidden="true">!</span></span>');
        });
        </script>
        <?php
    }
}
