<?php

use MemberPress\GroundLevel\Container\Concerns\InjectsDependencies;
use MemberPress\GroundLevel\Mothership\AbstractPluginConnection;
use MemberPress\GroundLevel\Mothership\UpdateService;

defined('ABSPATH') || exit;

/**
 * Base controller for feature addons.
 *
 * @property MemberPress\GroundLevel\Mothership\AbstractPluginConnection $plugin
 * @property MemberPress\GroundLevel\Mothership\UpdateService            $update_service
 */
class MeprFeatureAddonCtrl extends MeprBaseCtrl
{
    use InjectsDependencies;

    /**
     * Addon slug.
     *
     * @var string
     */
    protected string $slug = '';

    /**
     * Plugin basename.
     *
     * @var string
     */
    protected string $main_file = '';

    /**
     * Page title.
     *
     * @var string
     */
    protected string $page_title = '';

    /**
     * Menu title if different from page title.
     *
     * @var string
     */
    protected string $menu_title = '';

    /**
     * Sub-menu position.
     *
     * @var integer
     */
    protected int $menu_position = PHP_INT_MAX;

    /**
     * View path passed to MeprView::render().
     *
     * @var string
     */
    protected string $view_path = '';

    /**
     * Base URL the install/activate flow redirects to. Activated arg appended automatically.
     *
     * @var string
     */
    protected string $post_activation_url = '';

    /**
     * Whether to also render as a tab on the main MemberPress options page.
     *
     * @var boolean
     */
    protected bool $show_options_tab = false;

    /**
     * Defines dependencies to be injected.
     *
     * @return array
     */
    protected function inject(): array
    {
        return [
            'plugin'         => AbstractPluginConnection::class,
            'update_service' => UpdateService::class,
        ];
    }

    /**
     * Override in subclass to set properties.
     */
    protected function configure(): void
    {
    }

    /**
     * Load hooks.
     */
    public function load_hooks()
    {
        add_action('init', [$this, 'setup']);
    }

    /**
     * Set up hooks for the addon page.
     */
    public function setup(): void
    {
        $this->configure();

        if ($this->slug === '') {
            return;
        }

        // Register the add-on for updates.
        $this->update_service->plugin($this->slug);

        add_action('admin_notices', [$this, 'render_activation_notice']);

        $addon_key = str_replace(MEPR_PLUGIN_NAME . '-', '', $this->slug);
        if (MeprUtils::is_addon_active($addon_key)) {
            return;
        }

        add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']);
        add_action('mepr_menu', [$this, 'register_submenu']);

        if ($this->show_options_tab) {
            add_action('mepr_display_options_tabs', [$this, 'render_options_tab_link'], 99);
            add_action('mepr_display_options', [$this, 'render_options_tab_pane']);
        }
    }

    /**
     * Registers the addon submenu under the main MemberPress menu.
     */
    public function register_submenu(): void
    {
        add_submenu_page(
            'memberpress',
            $this->page_title,
            $this->menu_title ?: $this->page_title,
            MeprUtils::get_mepr_admin_capability(),
            $this->slug,
            [$this, 'render'],
            $this->menu_position
        );
    }

    /**
     * Renders a success notice if the activated query arg is present in the URL.
     */
    public function render_activation_notice(): void
    {
        $arg = $this->activated_query_arg();

        if (empty($_GET[$arg]) || 'true' !== $_GET[$arg]) {
            return;
        }

        printf(
            '<div class="notice notice-success is-dismissible"><p>%s</p></div>',
            esc_html(sprintf(
                // Translators: %s: feature addon display name (e.g. "MemberPress CoachKit™").
                __('%s has been activated successfully!', 'memberpress'),
                $this->page_title
            ))
        );
    }

    /**
     * Enqueues scripts.
     *
     * @param string $hook The current admin page hook.
     */
    public function enqueue_scripts($hook): void
    {
        $is_addon_page   = (bool) preg_match('/_page_' . preg_quote($this->slug, '/') . '$/', $hook);
        $is_options_page = (bool) preg_match('/_page_memberpress-options$/', $hook);

        if (!$is_addon_page && !$is_options_page) {
            return;
        }

        if ($is_addon_page) {
            // Keep the upsell page free of unrelated admin notices.
            remove_all_actions('admin_notices');
        }

        wp_enqueue_style('mepr-sister-plugin-css', MEPR_CSS_URL . '/admin-sister-plugin.css', [], MEPR_VERSION);
        wp_enqueue_script('mepr-feature-plugin-js', MEPR_JS_URL . '/admin_feature_plugin.js', ['jquery', 'updates'], MEPR_VERSION, true);
        wp_localize_script('mepr-feature-plugin-js', 'mepr_feature_plugin_data', [
            'activate_success' => __('Add-on activated successfully!', 'memberpress'),
            'activate_error'   => __('There was an error activating the add-on. Please try again.', 'memberpress'),
            'install_success'  => __('Add-on installed and activated successfully!', 'memberpress'),
            'install_error'    => __('There was an error installing the add-on. Please try again.', 'memberpress'),
        ]);
    }

    /**
     * Render the addon view.
     */
    public function render(): void
    {
        $main_file    = $this->main_file;
        $name         = $this->page_title;
        $plugin       = $this->slug;
        $is_installed = array_key_exists($main_file, get_plugins());
        $redirect_url = $this->redirect_url();

        MeprView::render($this->view_path, compact('main_file', 'name', 'plugin', 'is_installed', 'redirect_url'));
    }

    /**
     * Render the options page tab link.
     */
    public function render_options_tab_link(): void
    {
        printf(
            '<a class="nav-tab" id="%s" href="#">%s</a>',
            esc_attr($this->slug),
            esc_html($this->menu_title ?: $this->page_title)
        );
    }

    /**
     * Render the options page tab pane.
     */
    public function render_options_tab_pane(): void
    {
        echo '<div id="' . esc_attr($this->slug) . '" class="mepr-options-hidden-pane">';
        $this->render();
        echo '</div>';
    }

    /**
     * Post activate redirect URL with the activated query arg appended.
     */
    protected function redirect_url(): string
    {
        if ($this->post_activation_url === '') {
            return '';
        }

        return add_query_arg($this->activated_query_arg(), 'true', $this->post_activation_url);
    }

    /**
     * Query arg that triggers the post-activation success notice.
     */
    protected function activated_query_arg(): string
    {
        return $this->slug . '_activated';
    }
}
