<?php namespace Tussendoor\Reloadify;

use Tussendoor\Reloadify\Helpers\Log;
use Tussendoor\Reloadify\Helpers\Notice;
use Tussendoor\Reloadify\Models\Database;

class App
{
    /**
     * The number of times the class has been instantiated
     *
     * @var integer
     */
    private $count = 0;

    /**
     * Check if WooCommerce plugin is active.
     * If so; startup.
     * If not; shutdown.
     */
    public function boot()
    {
        $activePlugins = apply_filters('active_plugins', get_option('active_plugins'));
        if (
            in_array('woocommerce/woocommerce.php', $activePlugins) ||
            (
                function_exists('is_plugin_active_for_network') &&
                is_plugin_active_for_network('woocommerce/woocommerce.php')
            )
        ){
            return $this->startup();
        }

        return $this->shutdown();
    }

    /**
     * Deactivate plugin when WooCommerce is not active
     */
    public function shutdown()
    {
        unset($_GET['activate']);

        add_action('admin_notices', function () {
            echo '<div id="message" class="message error"><p><strong>WARNING:</strong> The <strong>Reloadify</strong> plugin cannot function without the <strong>WooCommerce</strong> plugin.</p></div>';
        });

        add_action('admin_init', function () {
            deactivate_plugins(Plugin::config('plugin.basefile'));
        });
    }

    /**
     * Startup the plugin
     */
    public function startup()
    {
        register_activation_hook(Plugin::config('plugin.basefile'), 'Tussendoor\Reloadify\Models\Database::migrate');
        register_uninstall_hook(Plugin::config('plugin.basefile'), 'Tussendoor\Reloadify\App::uninstall');
        add_action('plugins_loaded', [$this, 'init'], 10);

        // Initialize the database :)
        Database::setup();
    }

    /**
     * Initialise the plugin
     */
    public function init()
    {
        $this->addActions();
        $this->addFilters();
        $this->setLocale();
    }

    /**
     * Drop database tables when the plugin is uninstalled / deleted
     *
     * @since 1.5.4 Disabled to mitigate risk of abandoned cart data loss without explicit user consent.
     *
     * @return void
     */
    public static function uninstall()
    {
        // TODO: Implement proper function to take care of this such as an admin/options page asking for permission to drop tables.
//        Database::drop();
    }

    /**
     * Set plugin locale
     *
     * @return void
     */
    public function setLocale()
    {
        setlocale(LC_TIME, get_locale());
    }

    /**
     * Add plugin actions
     *
     * @return void
     */
    public function addActions()
    {
        add_action('init', [$this, 'loadTranslations']);
        add_action('init', [$this, 'loadHelpers']);
        add_action('admin_init', [$this, 'updateDatabase'], 20);
        add_action('init', [$this, 'registerControllers'], 30);
        add_action('init', [new Notice, 'display'], 99);
        add_action('before_woocommerce_init', [$this, 'declareCompatibility']);
    }

    /**
     * Declare addon compatibility with WooCommerce HPOS
     */
    public function declareCompatibility()
    {
        if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
            \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', Plugin::config('plugin.basefile'), true);
        }
    }

    /**
     * Update the database tables if needed
     *
     * @since 1.5.4 We introduced a check for a database version in the wp_options table (option: reloadify_plugin_db_version) before trying to migrate, this ensures we are not endlessly trying to run our db updates.
     * Hook for triggering the updateDatabase function was also changed to admin_init instead of init to prevent it from running on the frontend
     * and we also check for permissions/AJAX requests.
     *
     * @return void
     */
    public function updateDatabase()
    {
        if (!is_admin() || wp_doing_ajax()) {
            return; // geen updates in frontend of AJAX
        }

        $currentVersion = Plugin::config('plugin.version');
        $savedVersion   = get_option('reloadify_plugin_db_version');

        // 1) Eerste installatie?
        if (! $savedVersion) {
            Database::migrate();
            update_option('reloadify_plugin_db_version', $currentVersion);
            return;
        }

        // 1b) Upgraden vanaf een versie onder 1.8.6? Dan migreren we eerst
        if (version_compare($savedVersion, '1.8.6', '<')) {
            Database::migrate();
            // Also run update to ensure column types are updated for existing tables
            Database::update();
        }

        // 2) Algemene versie-upgrade (alle wijzigingen ná 1.8.6)
        if (version_compare($savedVersion, $currentVersion, '<')) {
            Database::update();
        }

        // 3) Save de nieuwe versie in de options
        update_option('reloadify_plugin_db_version', $currentVersion);
    }

    /**
     * Add plugin filters
     *
     * @return void
     */
    public function addFilters()
    {
        add_filter('wp_kses_allowed_html', [$this, 'allowSvgInHTML']);
        add_filter('plugin_action_links', [$this, 'addLinkToSettings'], 10, 2);
    }

    /**
     * Add link towards the Reloadify settings tab
     *
     * @param  array $actions
     * @param  string $plugin_file
     * @return string
     */
    public function addLinkToSettings(array $actions, string $plugin_file)
    {
        $settings_url   = Plugin::config('plugin.settings_url');
        $new_actions    = [];

        if ($plugin_file === Plugin::config('plugin.basefile')) {
            $new_actions['reloadify_settings'] = sprintf(
                '<a href="%s">' . esc_html__('Settings') . '</a>',
                $settings_url
            );
        }

        return array_merge($new_actions, $actions);
    }

    /**
     * We add svg's in our shortcodes and widget
     * When escaping we accept the SVG's here
     *
     * @param  mixed $tags
     * @return array
     */
    public function allowSvgInHTML($tags)
    {
        $tags['svg'] = array(
            'class'             => true,
            'xmlns'             => true,
            'fill'              => true,
            'viewbox'           => true,
            'role'              => true,
            'aria-hidden'       => true,
            'aria-labelledby'   => true,
            'focusable'         => true,
            'width'             => true,
            'height'            => true,
        );
        $tags['path'] = array(
            'd'     => true,
            'fill'  => true,
        );
        $tags['g'] = array(
            'fill'  => true,
        );
        $tags['title'] = array(
            'title'  => true,
        );
        return $tags;
    }

    /**
     * Load plugin translations.
     */
    public function loadTranslations()
    {
        load_plugin_textdomain('tsd-reloadify', false, Plugin::config('plugin.lang'));
    }

    /**
     * Load plugin helpers.
     */
    public function loadHelpers()
    {
        $log = new Log;
        $log->boot();
    }

    /**
     * Register plugin controllers
     *
     * @return void
     */
    public function registerControllers()
    {
        (new Controllers\PublicController)->register();
        (new Controllers\ScheduleController)->register();
        (new Controllers\AdminBarController)->register();

        (new Controllers\AbandonedCart\AbandonedCartController)->register();

        (new Controllers\WooCommerce\CartController)->register();
        (new Controllers\WooCommerce\CheckoutController)->register();
        (new Controllers\WooCommerce\SettingsController)->register();

        (new Http\Endpoints\Server)->register();
    }
}
