<?php
/**
 * Plugin bootstrap.
 *
 * @package StockGuardianPro
 */

declare(strict_types=1);

namespace StockGuardianPro\LowStock;

\defined('ABSPATH') || exit;

use StockGuardianPro\LowStock\Services\AdminPageService;
use StockGuardianPro\LowStock\Services\AssetsService;
use StockGuardianPro\LowStock\Services\EventRepository;
use StockGuardianPro\LowStock\Services\LoggerService;
use StockGuardianPro\LowStock\Services\NotificationService;
use StockGuardianPro\LowStock\Services\ProductThresholdService;
use StockGuardianPro\LowStock\Services\TelegramService;
use StockGuardianPro\LowStock\Services\RestApiService;
use StockGuardianPro\LowStock\Services\StockMonitorService;

\defined('ABSPATH') || exit;

final class Plugin
{
    private const MIN_WC_VERSION = '6.0.0';

    private static ?Plugin $instance = null;

    /** @var array<string, object> */
    private array $services = [];

    private function __construct()
    {
    }

    public static function get_instance(): Plugin
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    public function boot(): void
    {
        add_action('plugins_loaded', [$this, 'init']);
        register_activation_hook(WOOLSN_PLUGIN_FILE, [$this, 'on_activation']);
        register_deactivation_hook(WOOLSN_PLUGIN_FILE, [$this, 'on_deactivation']);
    }

    public function init(): void
    {
        if (! $this->meets_requirements()) {
            // Only show notice if plugin is still active (not deactivated)
            if (is_plugin_active(plugin_basename(WOOLSN_PLUGIN_FILE))) {
                add_action('admin_notices', [$this, 'render_requirements_notice']);
            }
            return;
        }

        add_action('init', [$this, 'load_textdomain']);

        $this->ensure_database_schema();
        $this->register_services();
    }

    public function load_textdomain(): void
    {
        // phpcs:ignore PluginCheck.CodeAnalysis.DiscouragedFunctions.load_plugin_textdomainFound
        load_plugin_textdomain(
            'stock-guardian-pro',
            false,
            dirname(plugin_basename(WOOLSN_PLUGIN_FILE)) . '/languages/'
        );
    }

    public function render_requirements_notice(): void
    {
        if (! current_user_can('activate_plugins')) {
            return;
        }

        $wc_version = defined('WC_VERSION') ? WC_VERSION : __('not installed', 'stock-guardian-pro');
        ?>
        <div class="notice notice-error">
            <p>
                <?php
                printf(
                    /* translators: 1: WooCommerce minimum version, 2: current WooCommerce version */
                    esc_html__(
                        'Stock Guardian Pro requires WooCommerce %1$s or greater. Current version: %2$s.',
                        'stock-guardian-pro'
                    ),
                    esc_html(self::MIN_WC_VERSION),
                    esc_html($wc_version)
                );
                ?>
            </p>
        </div>
        <?php
    }

    public function on_activation(): void
    {
        if (! $this->meets_requirements()) {
            deactivate_plugins(plugin_basename(WOOLSN_PLUGIN_FILE));
            
            // Store transient to show notice after redirect
            set_transient('woolsn_activation_error', true, 30);
            
            // Redirect to plugins page to show the notice instead of white page
            wp_safe_redirect(admin_url('plugins.php?woolsn_activation_error=1'));
            exit;
        }

        $this->ensure_database_schema();
        // Force flush rewrite rules to register support routes
        delete_option('woolsn_support_rules_version');
        flush_rewrite_rules(false);
    }

    public function render_activation_error_notice(): void
    {
        // Only show if activation error transient exists
        if (! get_transient('woolsn_activation_error')) {
            return;
        }
        
        if (! current_user_can('activate_plugins')) {
            return;
        }
        
        // Delete transient after showing once
        delete_transient('woolsn_activation_error');
        
        // Check if WooCommerce is installed
        // Use direct check since plugin might be deactivated
        $is_wc_active = false;
        if (function_exists('is_plugin_active')) {
            if (is_multisite()) {
                $is_wc_active = is_plugin_active_for_network('woocommerce/woocommerce.php');
            }
            if (! $is_wc_active) {
                $is_wc_active = is_plugin_active('woocommerce/woocommerce.php');
            }
        }
        
        if (! $is_wc_active) {
            ?>
            <div class="notice notice-error is-dismissible">
                <p>
                    <strong><?php esc_html_e('Stock Guardian Pro', 'stock-guardian-pro'); ?></strong>: 
                    <?php
                    esc_html_e(
                        'This plugin requires WooCommerce to be installed and activated. Please install WooCommerce and try again.',
                        'stock-guardian-pro'
                    );
                    ?>
                </p>
            </div>
            <?php
        } else {
            // WooCommerce is installed but version is too old
            $wc_version = defined('WC_VERSION') ? WC_VERSION : __('unknown', 'stock-guardian-pro');
            ?>
            <div class="notice notice-error is-dismissible">
                <p>
                    <strong><?php esc_html_e('Stock Guardian Pro', 'stock-guardian-pro'); ?></strong>: 
                    <?php
                    printf(
                        /* translators: 1: WooCommerce minimum version, 2: current WooCommerce version */
                        esc_html__(
                            'This plugin requires WooCommerce %1$s or greater. Current version: %2$s. Please update WooCommerce.',
                            'stock-guardian-pro'
                        ),
                        esc_html(self::MIN_WC_VERSION),
                        esc_html($wc_version)
                    );
                    ?>
                </p>
            </div>
            <?php
        }
    }

    public function on_deactivation(): void
    {
        flush_rewrite_rules();
    }

    private function meets_requirements(): bool
    {
        if (! $this->is_woocommerce_active()) {
            return false;
        }

        if (! defined('WC_VERSION')) {
            return false;
        }

        return version_compare(WC_VERSION, self::MIN_WC_VERSION, '>=');
    }

    private function is_woocommerce_active(): bool
    {
        include_once ABSPATH . 'wp-admin/includes/plugin.php';

        if (is_multisite()) {
            if (is_plugin_active_for_network('woocommerce/woocommerce.php')) {
                return true;
            }
        }

        return is_plugin_active('woocommerce/woocommerce.php');
    }

    private function register_services(): void
    {
        // Core services (always required)
        $core_services = [
            OptimizationService::class,
            EventRepository::class,
            AssetsService::class,
            LoggerService::class,
            NotificationService::class,
            TelegramService::class,
            ProductThresholdService::class,
            StockMonitorService::class,
            AdminPageService::class,
            RestApiService::class,
        ];

        // Optional services (only available in Xtreme Code site version)
        // Using FQCN instead of imports to avoid fatal errors if classes don't exist
        $optional_services = [
            // Support System (Client side + Admin dashboard)
        ];

        // Build final services list - check existence only once
        $services = [];
        foreach ($core_services as $service) {
            if (class_exists($service)) {
                $services[] = $service;
            }
        }

        // Add optional services only if classes exist
        foreach ($optional_services as $service) {
            if (class_exists($service)) {
                $services[] = $service;
            }
        }

        // Register all services
        foreach ($services as $service) {
            try {
                $instance = new $service($this);
                if (method_exists($instance, 'register')) {
                    $instance->register();
                }

                $this->services[$service] = $instance;
            } catch (\Throwable $e) {
                // Log error but don't break plugin initialization
                if (function_exists('do_action')) {
                    do_action('woolsn_service_error', $service, $e->getMessage());
                }
                continue;
            }
        }

        add_filter(
            'option_page_capability_woolsn_settings',
            static function () {
                return 'manage_woocommerce';
            }
        );
    }

    /**
     * @template T
     *
     * @param class-string<T> $service
     *
     * @return T|null
     */
    public function service(string $service)
    {
        return $this->services[$service] ?? null;
    }

    private function ensure_database_schema(): void
    {
        (new Installations\SchemaMigrator())->migrate();
    }
}

