<?php

/**
 * Main Plugin Bootstrap Class
 *
 * @package _121Digital\Connect
*/

namespace _121Digital\Connect\Core;

use _121Digital\Connect\Admin\Admin;
use _121Digital\Connect\API\RestApi;
use _121Digital\Connect\Authentication\Login;
use _121Digital\Connect\Commands\CommandDispatcher;
use _121Digital\Connect\Comments\Comments;
use _121Digital\Connect\Editor\ClassicEditor\ClassicEditor;
use _121Digital\Connect\Frontend\Frontend;
use _121Digital\Connect\Google\Google;
use _121Digital\Connect\Integration\ContactForms;
use _121Digital\Connect\Integration\ElementsImporter\ElementsImporter;
use _121Digital\Connect\Integration\Matomo;
use _121Digital\Connect\Integration\WordpressSeo\WordpressSeo;
use _121Digital\Connect\Network\Network;
use _121Digital\Connect\Registration\RegistrationManager;
use _121Digital\Connect\Security\KeyManager;
use _121Digital\Connect\User\UserRoles;

/**
 * Main Plugin Class
 *
 * Handles plugin initialization and component registration
 */
class Plugin
{
    /**
     * Plugin version
     */
    public const VERSION = '1.1.0';

    /**
     * Plugin instance
     *
     * @var Plugin|null
     */
    private static ?Plugin $instance = null;

    /**
     * Plugin configuration
     *
     * @var array
     */
    private array $config;

    /**
     * Component instances
     *
     * @var array
     */
    private array $components = [];

    /**
     * Bundled plugin components
     *
     * @var array
     */
    private array $bundledPluginComponents = [];

    /**
     * Private constructor for singleton pattern
     */
    private function __construct()
    {
        $this->config = $this->loadConfig();
    }

    /**
     * Get plugin instance (Singleton)
     *
     * @return Plugin
     */
    public static function getInstance(): Plugin
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Initialize the plugin
     *
     * @return void
     */
    public function init(): void
    {
        $this->defineConstants();
        $this->initializeComponents();
        $this->registerHooks();

        // load the pre auth modules...
        $login = new Login();
        $login->register();
    }

    /**
     * Load plugin configuration
     *
     * @return array
     */
    private function loadConfig(): array
    {
        return [
            'plugin_slug' => '121_connect',
            'plugin_path' => plugin_dir_path(dirname(dirname(__FILE__))),
            'plugin_url' => plugin_dir_url(dirname(dirname(__FILE__))),
            'plugin_file' => plugin_basename(dirname(dirname(__FILE__)) . '/121Connect.php'),
            'remote_api_base' => 'http://localhost:8888/121Domains/api.php',
            'remote_base' => 'http://localhost:8888/121Domains',
            'update_api_base' => 'https://wp-update-service.121domains.co.uk/121connect/',
        ];
    }

    /**
     * Define plugin constants
     *
     * @return void
     */
    private function defineConstants(): void
    {
        if (!defined('SC_PLUGIN_VERSION')) {
            define('SC_PLUGIN_VERSION', self::VERSION);
        }
        if (!defined('SC_PLUGIN_SLUG')) {
            define('SC_PLUGIN_SLUG', $this->config['plugin_slug']);
        }
        if (!defined('SC_PLUGIN_PATH')) {
            define('SC_PLUGIN_PATH', $this->config['plugin_path']);
        }
        if (!defined('SC_PLUGIN_URL')) {
            define('SC_PLUGIN_URL', $this->config['plugin_url']);
        }
        if (!defined('SC_PLUGIN_FILE')) {
            define('SC_PLUGIN_FILE', $this->config['plugin_file']);
        }
        if (!defined('SC_REMOTE_API_BASE')) {
            define('SC_REMOTE_API_BASE', $this->config['remote_api_base']);
        }
        if (!defined('SC_REMOTE_BASE')) {
            define('SC_REMOTE_BASE', $this->config['remote_base']);
        }
        if (!defined('SC_UPDATE_API_BASE')) {
            define('SC_UPDATE_API_BASE', $this->config['update_api_base']);
        }
    }

    /**
     * Initialize plugin components
     *
     * @return void
     */
    private function initializeComponents(): void
    {
        try {
            $this->components['key_manager'] = new KeyManager();
            $this->components['registration'] = new RegistrationManager();
            $this->components['command_dispatcher'] = new CommandDispatcher();
            $this->components['rest_api'] = new RestApi();
            $this->components['matomo'] = new Matomo();
            $this->components['contact_forms'] = new ContactForms();
            $this->components['cron'] = new Cron();
            $this->components['user_roles'] = new UserRoles();
            $this->components['comments'] = new Comments();
            $this->components['node_admin'] = new Network();
            $this->components['admin'] = new Admin();
            $this->components['frontend'] = new Frontend();
            $this->components['google'] = new Google();

            // init 3rd party bundled plugins in the correct order...
            $this->initializeClassicEditor();
            $this->initializeElementsImporter();
            $this->initializeWordpressSeo();
        } catch (\Exception $e) {
            Plugin::die($e->getMessage());
        }
    }

    private function initializeClassicEditor(): void
    {
        $this->bundledPluginComponents['classic_editor'] = new ClassicEditor();
    }

    private function initializeElementsImporter(): void
    {
        $this->bundledPluginComponents['elements_importer'] = new ElementsImporter();
    }

    private function initializeWordpressSeo(): void
    {
        $this->bundledPluginComponents['wordpress_seo'] = new WordpressSeo();
    }

    /**
     * Register WordPress hooks
     *
     * @return void
     */
    private function registerHooks(): void
    {
        try {
            foreach ($this->components as $component) {
                if (method_exists($component, 'register')) {
                    $component->register();
                }
            }

            // load the bundled plugin components...
            foreach ($this->bundledPluginComponents as $component) {
                if (method_exists($component, 'register')) {
                    $component->register();
                }
            }
        } catch (\Exception $e) {
            Plugin::die($e->getMessage());
        }
    }

    /**
     * Get plugin configuration
     *
     * @param string|null $key
     * @return mixed
     */
    public function getConfig(?string $key = null)
    {
        if ($key === null) {
            return $this->config;
        }
        return $this->config[$key] ?? null;
    }

    /**
     * Get component instance
     *
     * @param string $name
     * @return mixed
     */
    public function getComponent(string $name)
    {
        return $this->components[$name] ?? null;
    }

    /**
     * Display error and die
     *
     * @param string $errorMessage
     * @return void
     */
    public static function die(string $errorMessage): void
    {
        $errorHtml = "<h1><img width='250px' src='" . SC_PLUGIN_URL . "/static/brand_logo.svg'></h1><br>";
        $errorHtml .= '<b>An error has been reported:</b> <br>';
        $errorHtml .= '<span>' . esc_html($errorMessage) . '</span>';
        $errorHtml .= '<h1></h1>';

        wp_die($errorHtml);
        exit('');
    }

    /**
     * Check if automatic updates are enabled for the plugin
     *
     * @return bool
     */
    public static function isAutomaticUpdatesEnabled(): bool
    {
        $plugin = SC_PLUGIN_FILE;
        $auto_update_plugins = get_site_option('auto_update_plugins', []);

        return isset($auto_update_plugins[$plugin]) && $auto_update_plugins[$plugin] === true;
    }
}
