<?php

defined('ABSPATH') || exit;
defined('ABSPATH') || exit;
final class GPLVault_Client
{
    protected static $singleton = null;
    protected $version;
    protected $plugin_name;
    protected $plugin_basename;
    protected $emitter;
    public static function instance()
    {
        if (is_null(self::$singleton)) {
            self::$singleton = new self();
        }
        return self::$singleton;
    }
    private function __construct()
    {
        $this->version = GV_UPDATER_VERSION;
        $this->plugin_name = GV_UPDATER_NAME;
        $this->plugin_basename = plugin_basename(GV_UPDATER_FILE);
        do_action('gv_client_loading');
        $this->base_includes();
        $this->set_locale();
        do_action('gv_instantiated');
        do_action('gv_client_loaded');
    }
    public function version()
    {
        return $this->version;
    }
    public function plugin_basename()
    {
        return $this->plugin_basename;
    }
    public function plugin_name()
    {
        return $this->plugin_name;
    }
    private function set_locale()
    {
        add_action('plugins_loaded', array($this, 'load_text_domain'));
    }
    public function load_text_domain()
    {
        load_plugin_textdomain('gplvault', false, GV_UPDATER_PATH . 'languages');
    }
    private function base_includes()
    {
        require_once $this->includes_path('/class-gplvault-helper.php');
        require_once $this->includes_path('/gplvault-helpers.php');
        require_once $this->includes_path('/class-gplvault-ajax.php');
        require_once $this->includes_path('/class-gplvault-hooks.php');
        require_once $this->includes_path('/settings/class-gplvault-settings-manager.php');
        require_once $this->includes_path('/class-gplvault-util.php');
        require_once $this->includes_path('/gplvault-functions.php');
        require_once $this->includes_path('/api/class-gplvault-api-manager.php');
        require_once $this->admin_path('/class-gplvault-admin.php');
        require_once $this->includes_path('/class-gplvault-items.php');
        require_once $this->includes_path('/class-gplvault-updater.php');
        require_once $this->includes_path('/upgrader/class-gplvault-upgrade-manager.php');
    }
    public function run()
    {
        $this->initial_hooks();
        GPLVault_Ajax::instance()->init();
        if (is_admin()) {
            GPLVault_Admin::instance()->init();
        }
        GPLVault_Items::instance()->init();
        GPLVault_Updater::instance()->init();
        GPLVault_Upgrade_Manager::instance()->init();
    }
    public function initial_hooks()
    {
        $gv_util = GPLVault_Util::instance();
        if (gv_settings_manager()->license_is_activated()) {
            add_filter('cron_schedules', array($this, 'cron_schedules'));
            add_action('admin_init', array($gv_util, 'disable_woothemes_notice'));
        } else {
            remove_filter('cron_schedules', array($this, 'cron_schedules'));
            remove_action('admin_init', array($gv_util, 'disable_woothemes_notice'));
        }
        if (defined('GPLVAULT_RENAME_PLUGINS') && GPLVAULT_RENAME_PLUGINS) {
            add_filter('all_plugins', array($gv_util, 'rename_plugins'));
        }
        add_action('gv_api_license_activated', array($this, 'load_initial_schema'));
        if (gv_settings_manager()->license_is_activated()) {
            add_action('init', array($this, 'gv_initialize_cron'));
            add_action('gplvault_six_hours_cron', array($this, 'update_schema'));
            add_action('gv_two_hours_cron', array($this, 'scheduled_license_check'));
            if (!gv_settings_manager()->has_plugins()) {
                $this->load_initial_schema();
            }
            if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
                add_action('init', array($this, 'update_schema'));
            }
        } else {
            remove_action('gplvault_six_hours_cron', array($this, 'update_schema'));
            if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
                remove_action('init', array($this, 'update_schema'));
            }
            wp_clear_scheduled_hook('gplvault_six_hours_cron');
            wp_clear_scheduled_hook('gv_two_hours_cron');
            remove_action('gv_two_hours_cron', array($this, 'scheduled_license_check'));
            remove_action('init', array($this, 'gv_initialize_cron'));
        }
    }
    public function scheduled_license_check()
    {
        $old_checks = gv_settings_manager()->status_checks();
        $status_response = gv_api_manager()->status();
        if (!is_wp_error($status_response)) {
            gv_settings_manager()->remove_status_checks();
            if (isset($status_response['data'])) {
                gv_settings_manager()->save_license_status($status_response['data']);
            }
            return;
        }
        $old_checks[] = time();
        if (count($old_checks) >= 24) {
            gv_settings_manager()->disable_activation_status();
            gv_settings_manager()->clear_api_settings();
            gv_settings_manager()->remove_license_status();
            gv_settings_manager()->save_status_checks();
        } else {
            gv_settings_manager()->save_status_checks($old_checks);
        }
    }
    public function update_schema()
    {
        if (gv_settings_manager()->license_is_activated()) {
            $current_time = current_time('timestamp');
            if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
                $next_run = gv_settings_manager()->get('gplvault_next_fetch_schema', 0);
                if ($next_run > $current_time) {
                    return;
                }
            }
            $schema = gv_api_manager()->schema();
            if (!is_wp_error($schema)) {
                $this->update_plugins($schema);
                $this->update_themes($schema);
                if (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON) {
                    $next_run = $current_time + 6 * HOUR_IN_SECONDS;
                    gv_settings_manager()->update('gplvault_next_fetch_schema', $next_run);
                }
            }
        }
    }
    private function update_plugins($schema)
    {
        $decoded_plugins = $schema['plugins'];
        gv_settings_manager()->update_plugins_catalog($decoded_plugins);
    }
    private function update_themes($schema)
    {
        $decoded_themes = $schema['themes'];
        gv_settings_manager()->update_themes_catalog($decoded_themes);
    }
    public function load_initial_schema()
    {
        $schema = gv_api_manager()->schema();
        if (!is_wp_error($schema)) {
            $this->update_plugins($schema);
            $this->update_themes($schema);
            GPLVault_Admin::gv_update_plugins();
            GPLVault_Admin::gv_update_themes();
        }
    }
    public function cron_schedules($schedules)
    {
        $schedules['gv_thricedaily'] = array('interval' => 8 * HOUR_IN_SECONDS, 'display' => __('Thrice daily', 'gplvault'));
        $schedules['gv_fourtimes'] = array('interval' => 6 * HOUR_IN_SECONDS, 'display' => __('Four times daily', 'gplvault'));
        $schedules['gv_two_hours'] = array('interval' => 2 * HOUR_IN_SECONDS, 'display' => __('Every two hours', 'gplvault'));
        return $schedules;
    }
    public function gv_initialize_cron()
    {
        if (!wp_next_scheduled('gplvault_six_hours_cron')) {
            wp_schedule_event(time(), 'gv_fourtimes', 'gplvault_six_hours_cron');
        }
        if (!wp_next_scheduled('gv_two_hours_cron')) {
            wp_schedule_event(time(), 'gv_two_hours', 'gv_two_hours_cron');
        }
    }
    public function user_subs_pending_notice()
    {
        include GV_UPDATER_STATIC_PATH . 'notices/notice-pending-subscription.php';
    }
    private function dismiss_third_party_notices()
    {
        if (!gv_settings_manager()->license_is_activated()) {
            return;
        }
        add_action('admin_notices', array($this, 'gv_discard_bsf_update_notices'), -10);
        add_action('after_setup_theme', array($this, 'gv_discard_elementor_update_notices'), PHP_INT_MAX);
    }
    public function gv_discard_bsf_update_notices()
    {
        define('BSF_PRODUCTS_NOTICES', false);
    }
    public function gv_discard_elementor_update_notices()
    {
        if (class_exists('\\ElementorPro\\Plugin', false)) {
            remove_action('admin_notices', array(\ElementorPro\Plugin::instance()->license_admin, 'admin_license_details'), 20);
        }
    }
    public function path($tail = '')
    {
        return untrailingslashit(dirname(GV_UPDATER_FILE)) . $tail;
    }
    public function admin_path($tail = '')
    {
        return $this->path('/admin' . $tail);
    }
    public function includes_path($tail = '')
    {
        return $this->path('/includes' . $tail);
    }
    public function url($tail = '')
    {
        return untrailingslashit(plugin_dir_url($this->plugin_basename)) . $tail;
    }
    public function admin_assets_url($tail = '')
    {
        return $this->url('/admin/assets' . $tail);
    }
}