<?php

namespace FleekDash\Integrations\Core;

defined('ABSPATH') || exit;

/**
 * Widget Manager for FleekDash Dashboard
 *
 * Manages dynamic widgets from integrations
 */
class WidgetManager
{
    private Container $container;
    private Cache $cache;
    private array $widgets = [];
    private array $categories = [];

    public function __construct(Container $container, Cache $cache)
    {
        $this->container = $container;
        $this->cache = $cache;
        $this->initializeCategories();
        $this->registerHooks();
    }

    /**
     * Initialize default categories
     */
    private function initializeCategories(): void
    {
        $this->categories = [
            'analytics' => [
                'name' => 'Analytics',
                'icon' => 'chart-bar',
                'color' => '#3858e9'
            ],
            'content' => [
                'name' => 'Content',
                'icon' => 'document-text',
                'color' => '#00a32a'
            ],
            'ecommerce' => [
                'name' => 'E-commerce',
                'icon' => 'shopping-cart',
                'color' => '#f59e0b'
            ],
            'social' => [
                'name' => 'Social Media',
                'icon' => 'share',
                'color' => '#ef4444'
            ],
            'system' => [
                'name' => 'System',
                'icon' => 'cog',
                'color' => '#6b7280'
            ]
        ];
    }

    /**
     * Register WordPress hooks
     */
    private function registerHooks(): void
    {
        add_action('rest_api_init', [$this, 'registerRestRoutes']);
        add_action('fleekdash_dashboard_widgets', [$this, 'loadWidgets']);
    }

    /**
     * Register a new widget
     */
    public function registerWidget(string $id, array $config): void
    {
        $defaults = [
            'title' => '',
            'component' => '',
            'size' => 'medium',
            'category' => 'system',
            'permissions' => 'read',
            'refresh' => 300, // 5 minutes
            'position' => 999,
            'settings' => [],
            'data_source' => null,
            'cache_ttl' => 300
        ];

        $this->widgets[$id] = array_merge($defaults, $config);
        $this->widgets[$id]['id'] = $id;
    }

    /**
     * Register a widget category
     */
    public function registerCategory(string $id, array $config): void
    {
        $this->categories[$id] = $config;
    }

    /**
     * Get all registered widgets
     */
    public function getWidgets(bool $includeData = false): array
    {
        $widgets = $this->widgets;

        // Filter by user permissions
        $widgets = array_filter($widgets, function ($widget) {
            return $this->userCanViewWidget($widget);
        });

        // Include data if requested
        if ($includeData) {
            foreach ($widgets as $id => &$widget) {
                $widget['data'] = $this->getWidgetData($id);
            }
        }

        return $widgets;
    }

    /**
     * Get single widget with data
     */
    public function getWidget(string $id, bool $includeData = true): ?array
    {
        if (!isset($this->widgets[$id])) {
            return null;
        }

        $widget = $this->widgets[$id];

        if (!$this->userCanViewWidget($widget)) {
            return null;
        }

        if ($includeData) {
            $widget['data'] = $this->getWidgetData($id);
        }

        return $widget;
    }

    /**
     * Get widget data with caching
     */
    public function getWidgetData(string $id): array
    {
        if (!isset($this->widgets[$id])) {
            return [];
        }

        $widget = $this->widgets[$id];
        $cacheKey = "widget_data_{$id}";

        return $this->cache->remember($cacheKey, function () use ($widget) {
            if ($widget['data_source'] && is_callable($widget['data_source'])) {
                try {
                    return call_user_func($widget['data_source']);
                } catch (\Exception $e) {
                    error_log("Widget data error for {$widget['id']}: " . $e->getMessage());
                    return ['error' => 'Failed to load widget data'];
                }
            }
            return [];
        }, $widget['cache_ttl']);
    }

    /**
     * Check if user can view widget
     */
    private function userCanViewWidget(array $widget): bool
    {
        $permission = $widget['permissions'] ?? 'read';

        switch ($permission) {
            case 'manage':
                return current_user_can('manage_options');
            case 'edit':
                return current_user_can('edit_posts');
            case 'read':
            default:
                return is_user_logged_in();
        }
    }

    /**
     * Get widgets by category
     */
    public function getWidgetsByCategory(string $category): array
    {
        return array_filter($this->widgets, function ($widget) use ($category) {
            return $widget['category'] === $category;
        });
    }

    /**
     * Get all categories
     */
    public function getCategories(): array
    {
        return $this->categories;
    }

    /**
     * Load widgets from integrations
     */
    public function loadWidgets(): void
    {
        // This is called by integrations to register their widgets
        do_action('fleekdash_register_widgets', $this);
    }

    /**
     * Register REST API routes
     */
    public function registerRestRoutes(): void
    {
        // Get all widgets
        register_rest_route('fleekdash/v1', '/widgets', [
            'methods' => 'GET',
            'callback' => [$this, 'restGetWidgets'],
            'permission_callback' => function () {
                return is_user_logged_in();
            }
        ]);

        // Get single widget
        register_rest_route('fleekdash/v1', '/widgets/(?P<id>[a-zA-Z0-9-_]+)', [
            'methods' => 'GET',
            'callback' => [$this, 'restGetWidget'],
            'permission_callback' => function () {
                return is_user_logged_in();
            }
        ]);

        // Refresh widget data
        register_rest_route('fleekdash/v1', '/widgets/(?P<id>[a-zA-Z0-9-_]+)/refresh', [
            'methods' => 'POST',
            'callback' => [$this, 'restRefreshWidget'],
            'permission_callback' => function () {
                return current_user_can('edit_posts');
            }
        ]);

        // Get widget categories
        register_rest_route('fleekdash/v1', '/widgets/categories', [
            'methods' => 'GET',
            'callback' => [$this, 'restGetCategories'],
            'permission_callback' => function () {
                return is_user_logged_in();
            }
        ]);
    }

    /**
     * REST: Get all widgets
     */
    public function restGetWidgets(\WP_REST_Request $request): \WP_REST_Response
    {
        $includeData = $request->get_param('include_data') === 'true';
        $category = $request->get_param('category');

        $widgets = $this->getWidgets($includeData);

        if ($category) {
            $widgets = array_filter($widgets, function ($widget) use ($category) {
                return $widget['category'] === $category;
            });
        }

        return rest_ensure_response([
            'success' => true,
            'data' => array_values($widgets)
        ]);
    }

    /**
     * REST: Get single widget
     */
    public function restGetWidget(\WP_REST_Request $request): \WP_REST_Response|\WP_Error
    {
        $id = $request->get_param('id');
        $widget = $this->getWidget($id);

        if (!$widget) {
            return new \WP_Error('widget_not_found', 'Widget not found', ['status' => 404]);
        }

        return rest_ensure_response([
            'success' => true,
            'data' => $widget
        ]);
    }

    /**
     * REST: Refresh widget data
     */
    public function restRefreshWidget(\WP_REST_Request $request): \WP_REST_Response|\WP_Error
    {
        $id = $request->get_param('id');

        if (!isset($this->widgets[$id])) {
            return new \WP_Error('widget_not_found', 'Widget not found', ['status' => 404]);
        }

        // Clear cache
        $this->cache->delete("widget_data_{$id}");

        // Get fresh data
        $data = $this->getWidgetData($id);

        return rest_ensure_response([
            'success' => true,
            'data' => $data
        ]);
    }

    /**
     * REST: Get categories
     */
    public function restGetCategories(): \WP_REST_Response
    {
        return rest_ensure_response([
            'success' => true,
            'data' => $this->categories
        ]);
    }

    /**
     * Get user widget preferences
     */
    public function getUserPreferences(): array
    {
        $userId = get_current_user_id();
        return get_user_meta($userId, 'fleekdash_widget_preferences', true) ?: [];
    }

    /**
     * Save user widget preferences
     */
    public function saveUserPreferences(array $preferences): bool
    {
        $userId = get_current_user_id();
        return update_user_meta($userId, 'fleekdash_widget_preferences', $preferences);
    }
}
