<?php

use MemberPress\GroundLevel\Container\Concerns\InjectsDependencies;
use MemberPress\GroundLevel\Mothership\AbstractPluginConnection;
use MemberPress\GroundLevel\Mothership\Api\Request\Products;
use MemberPress\GroundLevel\Mothership\Manager\LicenseManager;

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

/**
 * Add-on updates.
 *
 * @property MemberPress\GroundLevel\Mothership\AbstractPluginConnection $plugin
 * @property MemberPress\GroundLevel\Mothership\Api\Request\Products     $products
 * @property MemberPress\GroundLevel\Mothership\Manager\LicenseManager   $license_manager
 */
class MeprAddonUpdates
{
    use InjectsDependencies;

    /**
     * Indicates if the MemberPress plugin is active.
     *
     * @var boolean
     */
    public $memberpress_active;

    /**
     * The plugin slug.
     *
     * @var string
     */
    public $slug;

    /**
     * The main plugin file path.
     *
     * @var string
     */
    public $main_file;

    /**
     * The options key for storing license information.
     *
     * @var string
     */
    public $options_key;

    /**
     * The plugin title.
     *
     * @var string
     */
    public $title;

    /**
     * The plugin description.
     *
     * @var string
     */
    public $desc;

    /**
     * The plugin installation path.
     *
     * @var string
     */
    public $path;

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

    /**
     * Constructor.
     *
     * @param  string $slug        The slug.
     * @param  string $main_file   The main file.
     * @param  string $options_key The options key.
     * @param  string $title       The title.
     * @param  string $desc        The description.
     * @return void
     */
    public function __construct($slug, $main_file, $options_key = '', $title = '', $desc = '')
    {
        $this->slug        = $slug;
        $this->main_file   = $main_file;
        $this->options_key = $options_key;
        $this->title       = $title;
        $this->desc        = $desc;
        $this->path        = WP_PLUGIN_DIR . '/' . $slug;

        add_action('after_setup_theme', [$this, 'load_language']);
        add_filter('pre_set_site_transient_update_plugins', [$this, 'queue_update']);
        add_action("in_plugin_update_message-$main_file", [$this, 'check_incorrect_edition']);
        add_action("{$this->plugin->pluginId}_edition_changed", [$this, 'clear_update_transient']);
        add_action("{$this->plugin->pluginId}_license_activated", [$this, 'clear_update_transient']);
        add_action("{$this->plugin->pluginId}_license_deactivated", [$this, 'clear_update_transient']);

        include_once(ABSPATH . 'wp-admin/includes/plugin.php');
        $this->memberpress_active = is_plugin_active('memberpress/memberpress.php');
    }

    /**
     * Queue update.
     *
     * @param  object  $transient          The transient.
     * @param  boolean $first_time_install The first time install.
     * @return object
     */
    public function queue_update($transient, $first_time_install = false)
    {
        if (!$first_time_install && empty($transient->checked)) {
            return $transient;
        }

        /**
         * Add-ons controller.
         *
         * @var MeprAddonsCtrl $addons_ctrl
         */
        $addons_ctrl       = MeprCtrlFactory::fetch('addons');
        $plugin_info       = $addons_ctrl->curr_plugin_info($this->main_file);
        $installed_version = (!$first_time_install && isset($plugin_info['Version'])) ? $plugin_info['Version'] : '0.0.0';
        $update_info       = get_site_transient('mepr_update_info_' . $this->slug);

        if (!is_array($update_info)) {
            $check = $this->products->getVersionCheck(
                $this->slug,
                [
                    'prerelease' => $this->plugin->allowPrereleaseVersions(),
                    '_embed'     => 'version',
                ]
            );

            if ($check->isError()) {
                if (isset($transient->response[$this->main_file])) {
                    unset($transient->response[$this->main_file]);
                }

                return $transient;
            }

            $version      = $check->getEmbed('version');
            $curr_version = $check->getData('number', $installed_version);
            $download_url = $version->url ?? '';

            if ($this->license_manager->isIncorrectEditionInstalled()) {
                $download_url = '';
            }

            set_site_transient(
                'mepr_update_info_' . $this->slug,
                compact('curr_version', 'download_url'),
                MeprUtils::hours(12)
            );
        } else {
            $curr_version = isset($update_info['curr_version']) ? $update_info['curr_version'] : $installed_version;
            $download_url = isset($update_info['download_url']) ? $update_info['download_url'] : '';
        }

        if (isset($curr_version) && version_compare($curr_version, $installed_version, '>')) {
            $transient->response[$this->main_file] = (object)[
                'id'          => $this->slug,
                'slug'        => $this->slug,
                'plugin'      => $this->main_file,
                'new_version' => $curr_version,
                'url'         => MeprUtils::get_link_url('home'),
                'package'     => $download_url,
            ];
        } else {
            unset($transient->response[$this->main_file]);
        }

        return $transient;
    }

    /**
     * Load the add-on's translated strings.
     *
     * For backwards-compatibility only. It is recommended to add the .mo file into the /wp-content/languages/plugins
     * directory instead.
     */
    public function load_language()
    {
        if (is_dir(WP_PLUGIN_DIR . '/mepr-i18n')) {
            load_plugin_textdomain($this->slug, false, 'mepr-i18n');
        }
    }

    /**
     * Check incorrect edition.
     *
     * @return void
     */
    public function check_incorrect_edition()
    {
        if (false !== $this->license_manager->isIncorrectEditionInstalled()) {
            printf(
                // Translators: %1$s: open link tag, %2$s: close link tag.
                ' <strong>' . esc_html__('To restore automatic updates, %1$sinstall the correct edition%2$s of MemberPress.', 'memberpress') . '</strong>',
                sprintf('<a href="%s">', esc_url(admin_url('admin.php?page=memberpress-options#mepr-license'))),
                '</a>'
            );
        }
    }

    /**
     * Clear update transient.
     *
     * @return void
     */
    public function clear_update_transient()
    {
        delete_site_transient('mepr_update_info_' . $this->slug);
    }
}
