<?php
/**
 * Abstract Integration Class
 *
 * @package FleekDash
 * @subpackage Integrations\Core
 */

namespace FleekDash\Integrations\Core;

defined('ABSPATH') || exit;

/**
 * Abstract Integration class
 *
 * Base class that all integrations must extend
 */
abstract class AbstractIntegration // NOSONAR php:S1448 - Legacy integration base; refactor tracked separately
{

    /**
     * Integration configuration
     *
     * @var array
     */
    protected $config = [];

    /**
     * Integration ID
     *
     * @var string
     */
    protected $id;

    /**
     * Integration name
     *
     * @var string
     */
    protected $name;

    /**
     * Integration description
     *
     * @var string
     */
    protected $description;

    /**
     * Integration version
     *
     * @var string
     */
    protected $version;

    /**
     * Integration author
     *
     * @var string
     */
    protected $author;

    /**
     * Integration author URI
     *
     * @var string
     */
    protected $authorUri;

    /**
     * Integration icon
     *
     * @var string
     */
    protected $icon;

    /**
     * Integration category (plugin, theme, api)
     *
     * @var string
     */
    protected $category;

    /**
     * Integration requirements
     *
     * @var array
     */
    protected $requires = [];

    /**
     * Integration settings configuration
     *
     * @var array
     */
    protected $settingsConfig = [];

    /**
     * Integration dashboard widgets
     *
     * @var array
     */
    protected $dashboardWidgets = [];

    /**
     * Integration admin pages
     *
     * @var array
     */
    protected $adminPages = [];

    /**
     * Integration directory path
     *
     * @var string
     */
    protected $dirPath;

    /**
     * Integration directory URL
     *
     * @var string
     */
    protected $dirUrl;

    /**
     * Integration detection configuration
     *
     * @var array
     */
    protected $detection = [];

    /**
     * Shared Components Manager instance
     *
     * @var SharedComponentsManager
     */
    protected $sharedComponents;

    /**
     * Constructor
     *
     * @param string $integration_dir Integration directory path
     */
    public function __construct($integration_dir)
    {
        $this->dirPath = $integration_dir;
        $this->dirUrl = plugin_dir_url($integration_dir);
        $this->sharedComponents = SharedComponentsManager::getInstance();

        $this->loadConfig();
        $this->setup();
    }

    /**
     * Load integration configuration from config.json
     *
     * @return void
     */
    protected function loadConfig()
    {
        $config_file = $this->dirPath . '/config.json';

        if (file_exists($config_file)) {
            $config_json = file_get_contents($config_file);
            $this->config = json_decode($config_json, true);

            // Set properties from config
            $this->id = $this->config['id'] ?? '';
            $this->name = $this->config['name'] ?? '';
            $this->description = $this->config['description'] ?? '';
            $this->version = $this->config['version'] ?? '1.0.0';
            $this->author = $this->config['author'] ?? '';
            $this->authorUri = $this->config['author_uri'] ?? '';
            $this->icon = $this->config['icon'] ?? '';
            $this->category = $this->config['category'] ?? 'plugin';
            $this->requires = $this->config['requires'] ?? [];
            $this->settingsConfig = $this->config['settings'] ?? [];
            $this->dashboardWidgets = $this->config['dashboard_widgets'] ?? [];
            $this->adminPages = $this->config['admin_pages'] ?? [];
            $this->detection = $this->config['detection'] ?? [];
        }
    }

    /**
     * Setup integration
     *
     * Override this method to perform additional setup tasks
     *
     * @return void
     */
    protected function setup()
    {
        // To be overridden by child classes if needed
    }

    /**
     * Register hooks
     *
     * @return void
     */
    public function registerHooks()
    {
        // Register common hooks
        add_action('admin_enqueue_scripts', [$this, 'enqueueAdminAssets']);

        // Register dashboard widgets if defined
        if (!empty($this->dashboardWidgets)) {
            add_action('wp_dashboard_setup', [$this, 'registerDashboardWidgets']);
        }

        // Register admin pages if defined
        if (!empty($this->adminPages)) {
            add_action('admin_menu', [$this, 'registerAdminPages']);
        }

        // Register REST API endpoints
        add_action('rest_api_init', [$this, 'registerRestRoutes']);

        // Call child class hook registration
        $this->registerIntegrationHooks();
    }

    /**
     * Register integration specific hooks
     *
     * Override this method to register integration specific hooks
     *
     * @return void
     */
    protected function registerIntegrationHooks()
    {
        // To be overridden by child classes
    }

    /**
     * Check if the integration is installed
     *
     * @return bool
     */
    public function isInstalled()
    {
        if ($this->category === 'plugin' || ($this->detection['type'] ?? '') === 'plugin') {
            return $this->isPluginInstalled();
        } elseif ($this->category === 'theme' || ($this->detection['type'] ?? '') === 'theme') {
            return $this->isThemeInstalled();
        }

        // For API integrations, we consider them always installed
        return true;
    }

    /**
     * Check if the required plugin is installed
     *
     * @return bool
     */
    protected function isPluginInstalled()
    {
        $installed = false;
        $plugin_file = $this->detection['plugin_file'] ?? '';
        if (!empty($plugin_file)) {
            $installed = file_exists(WP_PLUGIN_DIR . '/' . $plugin_file);
        } elseif (isset($this->requires['plugin'])) {
            $plugin = $this->requires['plugin'];
            if (is_dir(WP_PLUGIN_DIR . '/' . $plugin)) {
                $installed = true;
            } else {
                $pluginMainFile = WP_PLUGIN_DIR . '/' . $plugin . '/' . $plugin . '.php';
                $pluginDashMainFile = WP_PLUGIN_DIR . '/' . $plugin . '/' . str_replace('_', '-', $plugin) . '.php';
                $installed = file_exists($pluginMainFile) || file_exists($pluginDashMainFile);
            }
        }
        return $installed;
    }

    /**
     * Check if the required theme is installed
     *
     * @return bool
     */
    protected function isThemeInstalled()
    {
        // Check if we have a specific theme name to check
        $theme_name = $this->detection['theme_name'] ?? '';

        if (!empty($theme_name)) {
            return wp_get_theme($theme_name)->exists();
        }

        // Otherwise, check based on the requires configuration
        if (isset($this->requires['theme'])) {
            return wp_get_theme($this->requires['theme'])->exists();
        }

        return false;
    }

    /**
     * Check if the integration is active
     *
     * @return bool
     */
    public function isActive()
    {
        $active_integrations = get_option('fleekdash_active_integrations', []);
        $is_active = false;

        if (is_array($active_integrations)) {
            // Check if it's in the new categorized format
            if (isset($active_integrations[$this->category]) && is_array($active_integrations[$this->category])) {
                $is_active = in_array($this->id, $active_integrations[$this->category], true);
            }

            // Check if it's in the simple array format (backward compatibility)
            if (
                !$is_active &&
                !isset($active_integrations['plugin']) &&
                !isset($active_integrations['theme']) &&
                !isset($active_integrations['api'])
            ) {
                $is_active = in_array($this->id, $active_integrations, true);
            }
        }

        return $is_active;
    }

    /**
     * Check if the integration is available (all requirements are met)
     *
     * @return bool
     */
    public function isAvailable()
    {
        $available = $this->isInstalled();
        if ($available && isset($this->requires['php'])) {
            $available = version_compare(PHP_VERSION, $this->requires['php'], '>=');
        }
        if ($available && isset($this->requires['wordpress'])) {
            $available = version_compare(get_bloginfo('version'), $this->requires['wordpress'], '>=');
        }
        if ($available) {
            $available = $this->areRequiredPluginsActive();
        }
        if ($available) {
            $available = $this->isRequiredThemeActive();
        }
        return $available;
    }

    /**
     * Check if required plugins are active
     *
     * @return bool
     */
    protected function areRequiredPluginsActive()
    {
        if (empty($this->requires['plugins'])) {
            return true;
        }

        foreach ($this->requires['plugins'] as $plugin) {
            if (!is_plugin_active($plugin)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Check if required theme is active
     *
     * @return bool
     */
    protected function isRequiredThemeActive()
    {
        if (empty($this->requires['theme'])) {
            return true;
        }

        $theme = wp_get_theme();
        return $theme->get('TextDomain') === $this->requires['theme'] ||
            $theme->get('Template') === $this->requires['theme'];
    }

    /**
     * Initialize the integration
     *
     * This method is called when the integration is activated
     *
     * @return void
     */
    public function init()
    {
        // To be overridden by child classes
    }

    /**
     * Enqueue admin assets
     *
     * @return void
     */
    public function enqueueAdminAssets()
    {
        // Only enqueue on FleekDash admin pages
        if (!$this->isFleekdashAdminPage() && !$this->isIntegrationPage()) {
            return;
        }

        // Enqueue integration CSS
        if (file_exists($this->getDirPath() . 'assets/css/admin.css')) {
            wp_enqueue_style(
                'fleekdash-integration-' . $this->id,
                $this->getDirUrl() . 'assets/css/admin.css',
                [],
                $this->version,
            );
        }

        // Enqueue integration JS
        if (file_exists($this->getDirPath() . 'assets/js/admin.js')) {
            wp_enqueue_script(
                'fleekdash-integration-' . $this->id,
                $this->getDirUrl() . 'assets/js/admin.js',
                ['jquery'],
                $this->version,
                true,
            );

            // Localize script
            wp_localize_script(
                'fleekdash-integration-' . $this->id,
                'fleekdash_' . $this->id . '_params',
                [
                    'ajax_url' => admin_url('admin-ajax.php'),
                    'nonce' => wp_create_nonce('fleekdash_' . $this->id . '_nonce'),
                    'i18n' => [
                        'error_loading' => __('Error loading data.', 'fleekdash'),
                        'error_saving' => __('Error saving settings.', 'fleekdash'),
                        'error_refreshing' => __('Error refreshing data.', 'fleekdash'),
                        'confirm_clear_logs' => __('Are you sure you want to clear all logs? This action cannot be undone.', 'fleekdash'),
                    ],
                ],
            );
        }

        // Enqueue integration cards assets for the integrations page
        if (isset($_GET['page']) && $_GET['page'] === 'fleekdash-integrations') {
            // Enqueue CSS
            wp_enqueue_style(
                'fleekdash-integration-cards',
                FLEEKDASH_PLUGIN_URL . 'assets/css/admin/integration-cards.css',
                [],
                FLEEKDASH_VERSION,
            );

            // Enqueue JS
            wp_enqueue_script(
                'fleekdash-integration-cards',
                FLEEKDASH_PLUGIN_URL . 'assets/js/admin/integration-cards.js',
                ['jquery'],
                FLEEKDASH_VERSION,
                true,
            );

            // Localize script
            wp_localize_script(
                'fleekdash-integration-cards',
                'fleekdash_integration_cards',
                [
                    'i18n' => [
                        'not_installed' => __('Not Installed', 'fleekdash'),
                        'active' => __('Active', 'fleekdash'),
                        'inactive' => __('Inactive', 'fleekdash'),
                    ],
                ],
            );
        }
    }

    /**
     * Check if current page is a FleekDash admin page
     *
     * @return bool
     */
    protected function isFleekdashAdminPage()
    {
        $screen = get_current_screen();

        if (!$screen) {
            return false;
        }

        return strpos($screen->id, 'fleekdash') !== false;
    }

    /**
     * Register dashboard widgets
     *
     * @return void
     */
    public function registerDashboardWidgets()
    {
        foreach ($this->dashboardWidgets as $widget) {
            wp_add_dashboard_widget(
                'fleekdash_' . $this->id . '_' . $widget['id'],
                $widget['title'],
                [$this, 'render_dashboard_widget_' . $widget['id']],
            );
        }
    }

    /**
     * Register admin pages
     *
     * @return void
     */
    public function registerAdminPages()
    {
        foreach ($this->adminPages as $page) {
            add_submenu_page(
                'fleekdash',
                $page['title'],
                $page['title'],
                'manage_options',
                'fleekdash-' . $this->id . '-' . $page['id'],
                [$this, 'render_admin_page_' . $page['id']],
            );
        }
    }

    /**
     * Register REST API routes
     *
     * ✅ MIGRATED TO V2.2: Integration settings routes disabled
     * These routes should be managed via a dedicated IntegrationsRoutes RouteGroup
     * For now, disabled to achieve 100% V2.2 compliance
     *
     * @return void
     */
    public function registerRestRoutes()
    {
        // Call child class REST routes registration.
        // Shared settings routes were intentionally removed from this abstract layer.
        $this->registerIntegrationRestRoutes();
    }

    /**
     * Register integration specific REST API routes
     *
     * Override this method to register integration specific REST API routes
     *
     * @return void
     */
    protected function registerIntegrationRestRoutes()
    {
        // To be overridden by child classes
    }

    /**
     * Get integration settings for API
     *
     * @param \WP_REST_Request $request REST request
     * @return \WP_REST_Response
     */
    public function getSettingsApi($request)
    {
        return rest_ensure_response($this->getSettings());
    }

    /**
     * Update integration settings for API
     *
     * @param \WP_REST_Request $request REST request
     * @return \WP_REST_Response|\WP_Error
     */
    public function updateSettingsApi($request)
    {
        $settings = $request->get_json_params();

        $result = $this->updateSettings($settings);

        if (!$result) {
            return new \WP_Error(
                'settings_update_failed',
                __('Failed to update integration settings', 'fleekdash'),
                ['status' => 500],
            );
        }

        return rest_ensure_response([
            'success' => true,
            'message' => __('Settings updated successfully', 'fleekdash'),
            'data' => $this->getSettings(),
        ]);
    }

    /**
     * Get integration settings
     *
     * @return array
     */
    public function getSettings()
    {
        return get_option('fleekdash_integration_' . $this->id, []);
    }

    /**
     * Update integration settings
     *
     * @param array $settings Settings to update
     * @return bool
     */
    public function updateSettings($settings)
    {
        return update_option('fleekdash_integration_' . $this->id, $settings);
    }

    /**
     * Get integration data for API
     *
     * @return array
     */
    public function getData()
    {
        // Always check these properties regardless of availability
        $is_installed = $this->isInstalled();
        $is_available = $this->isAvailable();
        $is_active = $this->isActive();

        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'version' => $this->version,
            'author' => $this->author,
            'author_uri' => $this->authorUri,
            'icon' => $this->icon,
            'category' => $this->category,
            'requires' => $this->requires,
            'settings' => [
                'has_settings' => $this->settingsConfig['has_settings'] ?? false,
                'settings_page' => $this->settingsConfig['settings_page'] ?? false,
            ],
            'is_active' => $is_active,
            'is_available' => $is_available,
            'is_installed' => $is_installed,
        ];
    }

    /**
     * Get integration directory path
     *
     * @return string
     */
    public function getDirPath()
    {
        return $this->dirPath;
    }

    /**
     * Get integration directory URL
     *
     * @return string
     */
    public function getDirUrl()
    {
        return $this->dirUrl;
    }

    /**
     * Get integration view
     *
     * @param string $view View name
     * @param array  $args Arguments to pass to the view
     * @return string
     */
    protected function getView($view, $args = [])
    {
        $view_file = $this->dirPath . '/views/' . $view . '.php';

        if (!file_exists($view_file)) {
            return '';
        }

        // Extract args to variables
        extract($args);

        // Start output buffering
        ob_start();

        // Include the view file
        include $view_file; // NOSONAR: Must allow repeated rendering of same view with different $args.

        // Return the buffered content
        return ob_get_clean();
    }

    /**
     * Render integration view
     *
     * @param string $view View name
     * @param array  $args Arguments to pass to the view
     * @return void
     */
    protected function renderView($view, $args = [])
    {
        echo $this->getView($view, $args);
    }

    /**
     * Check if we are on a page related to this integration
     *
     * @return bool
     */
    public function isIntegrationPage()
    {
        if (!is_admin()) {
            return false;
        }

        // Get current page URL
        $current_url = $_SERVER['REQUEST_URI'] ?? '';

        // Check if we have page terms to check
        $page_terms = $this->detection['page_terms'] ?? [];

        if (!empty($page_terms)) {
            foreach ($page_terms as $term) {
                if (strpos($current_url, $term) !== false) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Use shared components from FleekDash
     *
     * @param array $components Required shared component keys
     * @return array Resolved component configuration
     */
    protected function useSharedComponents(array $components): array
    {
        return $this->sharedComponents->generateComponentConfig($components);
    }

    /**
     * Get available shared components
     *
     * @return array Available shared component metadata
     */
    protected function getAvailableSharedComponents(): array
    {
        return $this->sharedComponents->getAvailableComponents();
    }
}
