<?php

namespace FleekDash\Controllers;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use FleekDash\Services\DataSourcePluginService;
use FleekDash\Core\AuthMiddleware;

/**
 * Data Source Plugins Controller
 *
 * Handles REST API endpoints for managing data source plugins
 * in the DashboardBuilder system.
 */
class DataSourcePluginsController
{
    /**
     * Plugin service instance
     */
    private $plugin_service;

    public function __construct()
    {
        $this->plugin_service = new DataSourcePluginService();
    }

    /**
     * Check authentication
     */
    private function check_auth($required_level = 'authenticated')
    {
        try {
            $auth_check = AuthMiddleware::check($required_level);
            if (!$auth_check['authenticated']) {
                return [
                    'authenticated' => false,
                    'user_id' => 0,
                    'fallback' => true,
                    'reason' => $auth_check['reason']
                ];
            }

            return [
                'authenticated' => true,
                'user_id' => $auth_check['user_id'],
                'fallback' => false
            ];

        } catch (\Exception $e) {
            return [
                'authenticated' => false,
                'user_id' => 0,
                'fallback' => true,
                'reason' => 'auth_middleware_error'
            ];
        }
    }

    /**
     * Get all data source plugins
     */
    public function get_plugins(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');

            $plugins = $this->plugin_service->get_plugins();

            // Filter plugins based on query parameters
            $filter = $request->get_param('filter');
            if ($filter) {
                $plugins = $this->filter_plugins($plugins, $filter);
            }

            return new WP_REST_Response([
                'success' => true,
                'plugins' => $plugins,
                'meta' => [
                    'total' => count($plugins),
                    'enabled' => count(array_filter($plugins, fn($p) => $p['enabled'])),
                    'disabled' => count(array_filter($plugins, fn($p) => !$p['enabled']))
                ],
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('plugins_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Get plugin by ID
     */
    public function get_plugin(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');
            $plugin_id = $request->get_param('plugin_id');

            $plugin = $this->plugin_service->get_plugin($plugin_id);

            if (!$plugin) {
                return new WP_Error('plugin_not_found', 'Plugin not found', ['status' => 404]);
            }

            return new WP_REST_Response([
                'success' => true,
                'plugin' => $plugin,
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('plugin_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Get all data source types
     */
    public function get_data_source_types(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');

            $types = $this->plugin_service->get_data_source_types();

            // Filter by plugin if specified
            $plugin_id = $request->get_param('plugin_id');
            if ($plugin_id) {
                $types = array_filter($types, fn($type) => $type['plugin'] === $plugin_id);
            }

            return new WP_REST_Response([
                'success' => true,
                'types' => $types,
                'meta' => [
                    'total' => count($types),
                    'plugins' => array_unique(array_column($types, 'plugin'))
                ],
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('types_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Get data source type configuration
     */
    public function get_data_source_type(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');
            $type = $request->get_param('type');

            $type_config = $this->plugin_service->get_data_source_type($type);

            if (!$type_config) {
                return new WP_Error('type_not_found', 'Data source type not found', ['status' => 404]);
            }

            return new WP_REST_Response([
                'success' => true,
                'type' => $type_config,
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('type_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Update plugin status (enable/disable)
     */
    public function update_plugin_status(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');
            $plugin_id = $request->get_param('plugin_id');
            $enabled = $request->get_param('enabled');

            if (!\current_user_can('manage_options')) {
                return new WP_Error('insufficient_permissions', 'Insufficient permissions', ['status' => 403]);
            }

            $plugin = $this->plugin_service->get_plugin($plugin_id);
            if (!$plugin) {
                return new WP_Error('plugin_not_found', 'Plugin not found', ['status' => 404]);
            }

            $this->plugin_service->set_plugin_status($plugin_id, (bool) $enabled);

            return new WP_REST_Response([
                'success' => true,
                'message' => sprintf('Plugin %s %s successfully', $plugin_id, $enabled ? 'enabled' : 'disabled'),
                'plugin' => $this->plugin_service->get_plugin($plugin_id),
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('update_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Install a new plugin
     */
    public function install_plugin(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');

            if (!\current_user_can('manage_options')) {
                return new WP_Error('insufficient_permissions', 'Insufficient permissions', ['status' => 403]);
            }

            $plugin_data = $request->get_json_params();

            if (!$plugin_data || !isset($plugin_data['id'])) {
                return new WP_Error('invalid_data', 'Invalid plugin data', ['status' => 400]);
            }

            // Validate plugin data
            $validation = $this->validate_plugin_data($plugin_data);
            if (!$validation['valid']) {
                return new WP_Error('validation_error', $validation['message'], ['status' => 400]);
            }

            // Register the plugin
            $this->plugin_service->register_plugin($plugin_data['id'], $plugin_data);

            return new WP_REST_Response([
                'success' => true,
                'message' => 'Plugin installed successfully',
                'plugin' => $this->plugin_service->get_plugin($plugin_data['id']),
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 201);

        } catch (\Exception $e) {
            return new WP_Error('install_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Uninstall a plugin
     */
    public function uninstall_plugin(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');
            $plugin_id = $request->get_param('plugin_id');

            if (!\current_user_can('manage_options')) {
                return new WP_Error('insufficient_permissions', 'Insufficient permissions', ['status' => 403]);
            }

            $plugin = $this->plugin_service->get_plugin($plugin_id);
            if (!$plugin) {
                return new WP_Error('plugin_not_found', 'Plugin not found', ['status' => 404]);
            }

            // Check if plugin is a core plugin
            if ($plugin['plugin'] === 'core') {
                return new WP_Error('core_plugin', 'Cannot uninstall core plugins', ['status' => 400]);
            }

            // Uninstall plugin (this would need to be implemented in the service)
            // $this->plugin_service->uninstall_plugin($plugin_id);

            return new WP_REST_Response([
                'success' => true,
                'message' => 'Plugin uninstalled successfully',
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('uninstall_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Get plugin statistics
     */
    public function get_plugin_stats(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');

            $plugins = $this->plugin_service->get_plugins();
            $types = $this->plugin_service->get_data_source_types();

            $stats = [
                'total_plugins' => count($plugins),
                'enabled_plugins' => count(array_filter($plugins, fn($p) => $p['enabled'])),
                'disabled_plugins' => count(array_filter($plugins, fn($p) => !$p['enabled'])),
                'total_data_sources' => count($types),
                'plugins_by_author' => $this->group_plugins_by_author($plugins),
                'data_sources_by_plugin' => $this->group_data_sources_by_plugin($types),
                'recent_activity' => $this->get_recent_plugin_activity()
            ];

            return new WP_REST_Response([
                'success' => true,
                'stats' => $stats,
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('stats_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Test plugin functionality
     */
    public function test_plugin(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth('authenticated');
            $plugin_id = $request->get_param('plugin_id');

            $plugin = $this->plugin_service->get_plugin($plugin_id);
            if (!$plugin) {
                return new WP_Error('plugin_not_found', 'Plugin not found', ['status' => 404]);
            }

            // Test plugin functionality
            $test_results = $this->test_plugin_functionality($plugin);

            return new WP_REST_Response([
                'success' => true,
                'test_results' => $test_results,
                'auth_status' => [
                    'authenticated' => $auth['authenticated'],
                    'fallback' => $auth['fallback']
                ]
            ], 200);

        } catch (\Exception $e) {
            return new WP_Error('test_error', $e->getMessage(), ['status' => 500]);
        }
    }

    /**
     * Filter plugins based on criteria
     */
    private function filter_plugins($plugins, $filter)
    {
        switch ($filter) {
            case 'enabled':
                return array_filter($plugins, fn($p) => $p['enabled']);
            case 'disabled':
                return array_filter($plugins, fn($p) => !$p['enabled']);
            case 'core':
                return array_filter($plugins, fn($p) => $p['plugin'] === 'core');
            case 'third_party':
                return array_filter($plugins, fn($p) => $p['plugin'] !== 'core');
            default:
                return $plugins;
        }
    }

    /**
     * Validate plugin data
     */
    private function validate_plugin_data($data)
    {
        $required_fields = ['id', 'name', 'version'];

        foreach ($required_fields as $field) {
            if (!isset($data[$field]) || empty($data[$field])) {
                return [
                    'valid' => false,
                    'message' => "Missing required field: {$field}"
                ];
            }
        }

        // Validate version format
        if (!preg_match('/^\d+\.\d+\.\d+$/', $data['version'])) {
            return [
                'valid' => false,
                'message' => 'Invalid version format. Use semantic versioning (e.g., 1.0.0)'
            ];
        }

        return ['valid' => true];
    }

    /**
     * Group plugins by author
     */
    private function group_plugins_by_author($plugins)
    {
        $grouped = [];

        foreach ($plugins as $plugin) {
            $author = $plugin['author'] ?? 'Unknown';
            if (!isset($grouped[$author])) {
                $grouped[$author] = [];
            }
            $grouped[$author][] = $plugin;
        }

        return $grouped;
    }

    /**
     * Group data sources by plugin
     */
    private function group_data_sources_by_plugin($types)
    {
        $grouped = [];

        foreach ($types as $type => $config) {
            $plugin = $config['plugin'] ?? 'core';
            if (!isset($grouped[$plugin])) {
                $grouped[$plugin] = [];
            }
            $grouped[$plugin][] = $type;
        }

        return $grouped;
    }

    /**
     * Get recent plugin activity
     */
    private function get_recent_plugin_activity()
    {
        // This would typically come from a log or activity table
        // For now, return sample data
        return [
            [
                'action' => 'plugin_enabled',
                'plugin_id' => 'analytics-plugin',
                'timestamp' => \current_time('mysql'),
                'user_id' => \get_current_user_id()
            ],
            [
                'action' => 'plugin_installed',
                'plugin_id' => 'social-media-plugin',
                'timestamp' => \current_time('mysql', -3600), // 1 hour ago
                'user_id' => \get_current_user_id()
            ]
        ];
    }

    /**
     * Test plugin functionality
     */
    private function test_plugin_functionality($plugin)
    {
        $results = [
            'plugin_id' => $plugin['id'],
            'tests' => [],
            'overall_status' => 'unknown'
        ];

        // Test if plugin is enabled
        $results['tests']['enabled'] = [
            'status' => $plugin['enabled'] ? 'pass' : 'fail',
            'message' => $plugin['enabled'] ? 'Plugin is enabled' : 'Plugin is disabled'
        ];

        // Test dependencies
        if (!empty($plugin['dependencies'])) {
            $missing_deps = [];
            foreach ($plugin['dependencies'] as $dep) {
                if (!$this->plugin_service->get_plugin($dep)) {
                    $missing_deps[] = $dep;
                }
            }

            $results['tests']['dependencies'] = [
                'status' => empty($missing_deps) ? 'pass' : 'fail',
                'message' => empty($missing_deps) ? 'All dependencies satisfied' : 'Missing dependencies: ' . implode(', ', $missing_deps)
            ];
        }

        // Test data sources
        if (!empty($plugin['data_sources'])) {
            $valid_sources = 0;
            foreach ($plugin['data_sources'] as $source_type => $config) {
                if ($this->plugin_service->get_data_source_type($source_type)) {
                    $valid_sources++;
                }
            }

            $results['tests']['data_sources'] = [
                'status' => $valid_sources === count($plugin['data_sources']) ? 'pass' : 'fail',
                'message' => "{$valid_sources}/" . count($plugin['data_sources']) . " data sources registered"
            ];
        }

        // Calculate overall status
        $pass_count = count(array_filter($results['tests'], fn($t) => $t['status'] === 'pass'));
        $total_tests = count($results['tests']);

        if ($total_tests === 0) {
            $results['overall_status'] = 'unknown';
        } elseif ($pass_count === $total_tests) {
            $results['overall_status'] = 'pass';
        } elseif ($pass_count > 0) {
            $results['overall_status'] = 'partial';
        } else {
            $results['overall_status'] = 'fail';
        }

        return $results;
    }
}
