<?php

namespace WPD_Platform;

use WPD_Platform\Factories\ExternalHost;
use WPD_Platform\Factories\InternalHost;
use WPD_Platform\Services\LogService;
use WPD_Platform\Services\ErrorLogService;
use WPD_Platform\Services\ActivityTrackerService;

use \WP_CLI;

if ( ! defined('ABSPATH') ) {
    exit(); // Exit if accessed directly.
}

/**
 * Main Plugin class that handles core functionality and initialization.
 *
 * @package WPD_Platform
 * @since 1.0.0
 */
final class Plugin
{
    /** @var mixed The host instance */
    private $host;

    /** @var string The plugin file path */
    private $file;

    /** @var string The plugin basename */
    private $basename;

    /** @var string The plugin directory path */
    private $plugin_dir;

    /** @var string The plugin URL */
    private $plugin_url;

    /** @var string The includes directory path */
    private $includes_dir;

    /** @var string The includes URL */
    private $includes_url;

    /** @var \stdClass Object for extending functionality */
    private $extend;

    /**
     * Setup and return the singleton pattern.
     *
     * @since 1.0.0
     * @return Plugin The plugin instance
     */
    public static function instance()
    {
        // Store instance locally.
        static $instance = null;

        if (null === $instance) {
            $instance = new self();
            $instance->setup_globals();
            $instance->includes();
            
            $instance->setup_actions();

            $instance->load_log_service();
        }

        return $instance;
    }

    /**
     * Prevent the plugin class from being loaded more than once.
     *
     * @since 1.0.0
     */
    private function __construct()
    {

        new Hooks();
    }

    /**
     * Setup default class globals.
     *
     * @since 1.0.0
     * @return void
     */
    private function setup_globals()
    {
        /* Versions **********************************************************/


        /* Paths *************************************************************/

        // Setup some base path and URL information
        $this->file = __FILE__;
        $this->basename = PLATFORM_PLUGIN_SLUG;
        $this->plugin_dir = PLATFORM_PLUGIN_DIR;
        $this->plugin_url = PLATFORM_PLUGIN_URL;

        // Includes
        $this->includes_dir = PLATFORM_PLUGIN_DIR . 'includes';
        $this->includes_url = PLATFORM_PLUGIN_URL . 'includes';

        /* Misc **************************************************************/

        $this->extend = new \stdClass();
    }

    /**
     * Include the required files.
     *
     * @since 1.0.0
     * @return void
     */
    private function includes()
    {
        // Set up the host
        $this->get_host();

        // Load all integrations
        IntegrationLoader::instance()->load();

        // If WP-CLI is available, load the CLI commands and bail out
        if (defined('WP_CLI') && WP_CLI) {
            WP_CLI::add_command('dollie', '\WPD_Platform\CLI');
            return;
        }

        //Load Error Logger before anything else.
        new ErrorLogService();

        // Set up Functionality.
        require $this->plugin_dir . 'setup/platform.php';
        require $this->plugin_dir . 'setup/misc.php';

        new Authentication();

    }

    private function load_log_service()
    {
        // Instantiate the LogService class
        LogService::instance();

        // Defer ActivityTrackerService to 'init' — it needs is_user_logged_in()
        // which isn't available until WordPress has determined the current user.
        add_action('init', function () {
            ActivityTrackerService::instance();
        });
    }

    private function setup_actions()
    {
        $this->load_early_dependencies();

        add_action('plugins_loaded', function() {

            // Load textdomain.
            add_action( 'admin_enqueue_scripts', [$this, 'enqueue_scripts']);
            add_action( 'delete_db_export', array('\WPD_Platform\Services\RemoteService', 'delete_db_export'));
            add_action( 'upgrade_call_async', array( \WPD_Platform\Services\RemoteService::instance(), 'upgrade_call_async' ), 10, 2 );
            add_action( 'install_call_async', array( \WPD_Platform\Services\RemoteService::instance(), 'install_call_async' ), 10, 2 );

            // Store the action ID
            add_action( 'action_scheduler_before_execute', function( $action_id ) {
                global $as_current_action_id;
                $as_current_action_id = $action_id;
            }, 10);
            add_action( 'action_scheduler_after_execute', function( $action_id ) {
                global $as_current_action_id;
                $as_current_action_id = null;
            }, 10);
        });

    }


    /**
	 * Load early dependencies
	 */
	public function load_early_dependencies() {

        $this->create_wpd_data_table();

		require_once PLATFORM_PLUGIN_DIR . 'includes/action-scheduler/action-scheduler.php';
	}

    /**
     * Enqueue admin scripts.
     *
     * Only registers styles/scripts globally. Actual enqueuing happens
     * on plugin pages via Admin::enqueue_assets().
     *
     * @since 1.0.0
     */
    public function enqueue_scripts()
    {
        // Register only — enqueued on plugin admin pages via Admin::enqueue_assets().
        wp_register_script( 'dollie-sweetalert', PLATFORM_PLUGIN_URL . 'assets/js/sweetalert.min.js', [], PLATFORM_VERSION, true );
        wp_register_style( 'dollie-sweetalert-style', PLATFORM_PLUGIN_URL . 'assets/css/sweetalert.css', [], PLATFORM_VERSION );
    }


    /**
     * Decide if we should load platform email overrides. Checks for installed SMTP plugins
     *
     * @return bool
     */
    public function should_load_email_overrides()
    {
        global $wp_filter;

        $exceptions = ['LogEmailsPlugin', 'wp_staticize_emoji_for_email'];
        $load_email_overrides = true;

        if ( defined( 'DOL_DISABLE_FALLBACK_EMAIL' ) ) { $load_email_overrides = false; }

        foreach ($wp_filter as $key => $val) {
            if (false !== strpos($key, 'phpmailer_init') || false !== strpos($key, 'wp_mail')) {
                foreach ($val->callbacks as $callback) {
                    foreach ($callback as $item) {
                        // We have a class.
                        if (is_array($item['function'])) {
                            $name = get_class($item['function'][0]);
                        } else {
                            $name = $item['function'];
                        }

                        if (is_string($name) && in_array($name, $exceptions, true)) {
                            continue;
                        }

                        // We have a plugin to handle email delivery.
                        $load_email_overrides = false;
                    }
                }
            }
        }

        return $load_email_overrides;
    }

    
    public function get_host()
    {
        if (!empty($this->host)) {
            return $this->host;
        }

        if (defined('S5_APP_ID')) {
            $this->host = new InternalHost();
        } else {
            $this->host = new ExternalHost();
        }

        return $this->host;
    }



    /**
     * If it is a regular plugin or a must-use plugin.
     *
     * @return bool
     */
    public function is_wpmu()
    {
        return defined('WPD_PLATFORM_IS_MU') && WPD_PLATFORM_IS_MU;
    }

    /**
     * @return void
     */
    public function activate_plugin()
    {
        // if ($this->is_wpmu()) {
        //     return;
        // }

        $this->get_host()->register_site();

        $this->register_as_mu();
    }

    public static function uninstall_plugin() {

        $loaderName = '0-platform.php';
        try {
            $mustUsePluginDir = rtrim(WPMU_PLUGIN_DIR, '/');
            $loaderPath       = $mustUsePluginDir.'/'.$loaderName;

            if (!file_exists($loaderPath)) {
                return;
            }

            $removed = @unlink($loaderPath);

            if (!$removed) {
                $error = error_get_last();
                throw new \Exception(sprintf('Unable to remove loader: %s', $error['message']));
            }
        } catch (\Exception $e) {
            error_log( $e->getMessage() );
        }

    }

    private function register_as_mu() {
        $loader_name = '0-platform.php';
        $loader_content = $this->get_loader_content();

        $mu_plugin_dir = rtrim(WPMU_PLUGIN_DIR, '/');
        $loader_path       = $mu_plugin_dir . '/' . $loader_name;

        if ( file_exists( $loader_path ) && md5( $loader_content ) === md5_file($loader_path) ) {
            return;
        }

        try {
            if ( ! is_dir( $mu_plugin_dir ) ) {
                $dir_made = @mkdir($mu_plugin_dir);

                if (! $dir_made) {
                    $error = error_get_last();
                    throw new \Exception(sprintf('Unable to create loader directory: %s', $error['message']));
                }
            }

            if ( ! is_writable( $mu_plugin_dir ) ) {
                throw new \Exception('MU-plugin directory is not writable.');
            }

            $loader_written = @file_put_contents( $loader_path, $loader_content );

            if ( ! $loader_written ) {
                $error = error_get_last();
                throw new \Exception(sprintf('Unable to write platform loader: %s', $error['message']));
            }
        } catch(\Exception $e) {
            error_log( $e->getMessage() );
        }

    }

    private function get_loader_content() {
        $loader = <<<EOF
<?php
/**
 * Plugin Name: Dollie AI - Connect
 * Description: Connect your WordPress site to Dollie — your Agency HQ for the AI Era.
 * Version:     7.0.0
 * Author:      Dollie AI
 * Text Domain: dollie
 * Domain Path: /languages/
 * Network: true
 */

if ( ! function_exists( 'untrailingslashit' ) || ! defined( 'WP_PLUGIN_DIR' ) ) {
    // WordPress is probably not bootstrapped.
    exit;
}

if ( file_exists( untrailingslashit( WP_PLUGIN_DIR ) . '/platform/platform.php' ) ) {
    if ( in_array( 'platform/platform.php', (array) get_option( 'active_plugins' ) ) ||
            ( function_exists( 'get_site_option' ) && array_key_exists( 'platform/platform.php', (array) get_site_option( 'active_sitewide_plugins' ) ) ) ) {
        define( 'WPD_PLATFORM_IS_AS_MU', true );
        include_once untrailingslashit( WP_PLUGIN_DIR ) . '/platform/platform.php';
    }
}

EOF;

        return $loader;
    }


    /**
     * Set data in the wpd_data table
     *
     * @param string $name
     * @param string $value
     */
    function set_data( $name, $value ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'wpd_data';

        if (is_array($value)) {
            $value = json_encode($value);
        }

        // Check if the name already exists
        $exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE name = %s", $name ) );

        if ( $exists ) {
            $wpdb->update(
                $table_name,
                array( 'value' => $value ),
                array( 'name' => $name )
            );
        } else {
            $wpdb->insert(
                $table_name,
                array(
                    'name' => $name,
                    'value' => $value
                )
            );
        }
    }

    /**
     * Get data from the wpd_data table
     *
     * @param string $name
     * @param mixed $default
     * @return mixed
     */
    function get_data( $name, $default = '' ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'wpd_data';

        // Fetch the value for the given name
        $value = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM $table_name WHERE name = %s", $name ) );

        if ( $value !== null ) {

            try {
                $value = json_decode( $value, true );
            } catch (\Exception $e) {}

            return $value;
        }

        return $default;
    }

    /**
     * Create the wpd_data table
     */
    private function create_wpd_data_table() {

        $current_version = "1.0";
        if ( version_compare( get_option('wpd_data_created', '0.0'), $current_version, '>=' ) ) {
            return;
        }

        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
        global $wpdb;

        $table_name = $wpdb->prefix . 'wpd_data';
        $charset_collate = $wpdb->get_charset_collate();

        $sql = "CREATE TABLE $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            name tinytext NOT NULL,
            value text NOT NULL,
            PRIMARY KEY  (id)
        ) $charset_collate;";

        dbDelta( $sql );

        update_option( 'wpd_data_created', $current_version );
    }
}
