<?php

namespace FleekDash\API\Plugins;

/**
 * Plugin Asset Manager
 *
 * Handles retrieval of plugin assets (thumbnails, icons, banners)
 * from various sources (WordPress.org API, local files, fallbacks)
 *
 * @package FleekDash\API\Plugins
 */
class PluginAssetManager
{
    /**
     * Cache duration for plugin thumbnails (24 hours)
     */
    private const CACHE_DURATION = 24 * HOUR_IN_SECONDS;

    private const DEFAULT_ICON_COLOR = '#6366f1';

    private const DEFAULT_FALLBACK_ICON_COLOR = '#6c757d';

    /**
     * Get plugin thumbnail from multiple sources (with cache)
     *
     * Priority: Cache → update_plugins transient → no_update transient → WordPress.org API → local files → fallback icon
     *
     * @param string $plugin_file Plugin file path
     * @param array $plugin_data Plugin metadata
     * @return array Thumbnail data with type, url, icon, color
     */
    public function getPluginThumbnail($plugin_file, $plugin_data)
    {
        // 🚀 Check cache first (instant return)
        $cache_key = 'fleekdash_plugin_thumb_' . md5($plugin_file . ($plugin_data['Version'] ?? ''));
        $cached = \get_transient($cache_key);

        if ($cached !== false) {
            return $cached;
        }

        // 🔍 Cache miss - perform expensive lookup
        $thumbnail = $this->fetchPluginThumbnail($plugin_file, $plugin_data);

        // 💾 Cache result for 24 hours
        \set_transient($cache_key, $thumbnail, self::CACHE_DURATION);

        return $thumbnail;
    }

    /**
     * Fetch plugin thumbnail (expensive operation - only called on cache miss)
     *
     * @param string $plugin_file Plugin file path
     * @param array $plugin_data Plugin metadata
     * @return array Thumbnail data with type, url, icon, color
     */
    private function fetchPluginThumbnail($plugin_file, $plugin_data)
    {
        $thumbnail = $this->getThumbnailFromUpdateTransients($plugin_file);

        if ($thumbnail === null) {
            $thumbnail = $this->findLocalIconThumbnail($plugin_file);
        }

        if ($thumbnail === null) {
            $icon_data = $this->getPluginIconByName(\strtolower($plugin_data['Name']), $plugin_data);
            $thumbnail = [
                'type' => 'icon',
                'url' => null,
                'icon' => $icon_data['icon'],
                'color' => $icon_data['color'],
            ];
        }

        return $thumbnail;
    }

    /**
     * Try thumbnail from update_plugins transient buckets (response + no_update).
     *
     * @param string $plugin_file Plugin file path
     * @return array<string, mixed>|null
     */
    private function getThumbnailFromUpdateTransients(string $plugin_file): ?array
    {
        $update_plugins = \get_site_transient('update_plugins');
        if (!\is_object($update_plugins)) {
            return null;
        }

        $result = null;
        foreach (['response', 'no_update'] as $bucket) {
            if ($result !== null) {
                break;
            }

            if (!isset($update_plugins->$bucket) || !\is_array($update_plugins->$bucket)) {
                continue;
            }

            $entries = $update_plugins->$bucket;
            if (empty($entries[$plugin_file]->icons)) {
                continue;
            }

            $url = $this->pickIconUrlFromTransient((array) $entries[$plugin_file]->icons);
            if ($url !== null) {
                $result = $this->buildImageThumbnail($url);
            }
        }

        return $result;
    }

    /**
     * Pick best icon URL from WordPress transient icons array.
     *
     * @param array<string, string> $icons
     */
    private function pickIconUrlFromTransient(array $icons): ?string
    {
        $url = null;
        foreach (['2x', '1x', 'default'] as $size) {
            if (!empty($icons[$size])) {
                $url = $icons[$size];
                break;
            }
        }

        return $url;
    }

    /**
     * @return array<string, mixed>
     */
    private function buildImageThumbnail(string $url): array
    {
        return [
            'type' => 'image',
            'url' => $url,
            'icon' => null,
            'color' => self::DEFAULT_ICON_COLOR,
        ];
    }

    /**
     * Resolve absolute plugin directory from plugin file path.
     */
    private function resolvePluginDirectory(string $plugin_file): string
    {
        $plugin_dir_relative = \dirname($plugin_file);
        if ($plugin_dir_relative === '.' || $plugin_dir_relative === '') {
            return WP_PLUGIN_DIR;
        }

        return WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin_dir_relative;
    }

    /**
     * @return list<string>
     */
    private function buildLocalIconSearchPaths(string $plugin_dir): array
    {
        $ds = DIRECTORY_SEPARATOR;

        return [
            $plugin_dir . $ds . 'assets' . $ds . 'icon-256x256.png',
            $plugin_dir . $ds . 'assets' . $ds . 'icon-256x256.jpg',
            $plugin_dir . $ds . 'assets' . $ds . 'icon-128x128.png',
            $plugin_dir . $ds . 'assets' . $ds . 'icon-128x128.jpg',
            $plugin_dir . $ds . 'assets' . $ds . 'icon.png',
            $plugin_dir . $ds . 'assets' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon.png',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-128x128.png',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-256x256.png',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-128x128.jpg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-256x256.jpg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-128x128.svg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-256x256.svg',
            $plugin_dir . $ds . 'public' . $ds . 'images' . $ds . 'icon-128x128.webp',
            $plugin_dir . $ds . 'icon-256x256.png',
            $plugin_dir . $ds . 'icon-128x128.png',
            $plugin_dir . $ds . 'icon.png',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'icon-256x256.png',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'icon-128x128.png',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'icon.png',
            $plugin_dir . $ds . 'assets' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'assets' . $ds . 'img' . $ds . 'icon.png',
            $plugin_dir . $ds . 'assets' . $ds . 'img' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'assets' . $ds . 'img' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'logo.png',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'logo.jpg',
            $plugin_dir . $ds . 'assets' . $ds . 'images' . $ds . 'logo.svg',
            $plugin_dir . $ds . 'img' . $ds . 'icon.png',
            $plugin_dir . $ds . 'img' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'img' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'images' . $ds . 'icon.png',
            $plugin_dir . $ds . 'images' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'images' . $ds . 'logo.png',
            $plugin_dir . $ds . 'img' . $ds . 'logo.png',
            $plugin_dir . $ds . 'img' . $ds . 'logo.jpg',
            $plugin_dir . $ds . 'img' . $ds . 'logo.svg',
            $plugin_dir . $ds . 'admin' . $ds . 'img' . $ds . 'icon.png',
            $plugin_dir . $ds . 'admin' . $ds . 'img' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'admin' . $ds . 'img' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'admin' . $ds . 'images' . $ds . 'icon.png',
            $plugin_dir . $ds . 'admin' . $ds . 'images' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'admin' . $ds . 'images' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'admin' . $ds . 'assets' . $ds . 'img' . $ds . 'icon.png',
            $plugin_dir . $ds . 'admin' . $ds . 'assets' . $ds . 'img' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'admin' . $ds . 'assets' . $ds . 'img' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'admin' . $ds . 'assets' . $ds . 'images' . $ds . 'icon.png',
            $plugin_dir . $ds . 'admin' . $ds . 'assets' . $ds . 'images' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'admin' . $ds . 'assets' . $ds . 'images' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'assets' . $ds . 'admin' . $ds . 'img' . $ds . 'icon.png',
            $plugin_dir . $ds . 'assets' . $ds . 'admin' . $ds . 'img' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'assets' . $ds . 'admin' . $ds . 'img' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'assets' . $ds . 'admin' . $ds . 'images' . $ds . 'icon.png',
            $plugin_dir . $ds . 'assets' . $ds . 'admin' . $ds . 'images' . $ds . 'icon.jpg',
            $plugin_dir . $ds . 'assets' . $ds . 'admin' . $ds . 'images' . $ds . 'icon.svg',
            $plugin_dir . $ds . 'icon.svg',
            $plugin_dir . $ds . 'logo.png',
            $plugin_dir . $ds . 'logo.jpg',
            $plugin_dir . $ds . 'logo.svg',
        ];
    }

    /**
     * Convert a local icon file path to a public plugin URL.
     */
    private function filePathToPluginIconUrl(string $plugin_dir, string $path, string $plugin_file): string
    {
        $plugin_dir_normalized = \str_replace('\\', '/', $plugin_dir);
        $path_normalized = \str_replace('\\', '/', $path);
        $relative_path = \str_replace($plugin_dir_normalized . '/', '', $path_normalized);
        $plugin_main_file = \str_replace('\\', '/', WP_PLUGIN_DIR . '/' . $plugin_file);
        $plugin_url = \plugin_dir_url($plugin_main_file);
        $relative_path = \str_replace('\\', '/', $relative_path);

        return $plugin_url . $relative_path;
    }

    /**
     * @return array<string, mixed>|null
     */
    private function findLocalIconThumbnail(string $plugin_file): ?array
    {
        $plugin_dir = $this->resolvePluginDirectory($plugin_file);
        $icon_paths = $this->buildLocalIconSearchPaths($plugin_dir);
        $result = null;

        foreach ($icon_paths as $path) {
            if (!\file_exists($path)) {
                continue;
            }

            $url = $this->filePathToPluginIconUrl($plugin_dir, $path, $plugin_file);
            $result = $this->buildImageThumbnail($url);
            break;
        }

        return $result;
    }

    /**
     * Get plugin icon based on plugin name and characteristics
     *
     * @param string $plugin_name Plugin name (lowercase)
     * @param array $plugin_data Plugin metadata
     * @return array Icon name and color
     */
    public function getPluginIconByName($plugin_name, $plugin_data)
    {
        $known_plugins = $this->getKnownPluginIcons();
        $result = $this->matchKnownPluginIcon($plugin_name, $known_plugins);

        if ($result === null) {
            $description = \strtolower($plugin_data['Description'] ?? '');
            $result = $this->matchKnownPluginIcon($description, $known_plugins);
        }

        if ($result === null && \strpos($plugin_name, 'fleek') !== false) {
            $result = ['icon' => 'mdi:lightning-bolt', 'color' => self::DEFAULT_ICON_COLOR];
        }

        if ($result === null) {
            $result = ['icon' => 'mdi:puzzle', 'color' => self::DEFAULT_FALLBACK_ICON_COLOR];
        }

        return $result;
    }

    /**
     * @return array<string, array{icon: string, color: string}>
     */
    private function getKnownPluginIcons(): array
    {
        return [
            'woocommerce' => ['icon' => 'mdi:shopping', 'color' => '#96588a'],
            'elementor' => ['icon' => 'mdi:view-dashboard', 'color' => '#d63384'],
            'yoast seo' => ['icon' => 'mdi:search-web', 'color' => '#a4286a'],
            'akismet' => ['icon' => 'mdi:shield-check', 'color' => '#0073aa'],
            'jetpack' => ['icon' => 'mdi:rocket', 'color' => '#00be28'],
            'contact form 7' => ['icon' => 'mdi:email', 'color' => '#0085ba'],
            'wordfence' => ['icon' => 'mdi:security', 'color' => '#00709e'],
            'wpml' => ['icon' => 'mdi:translate', 'color' => '#7854a1'],
            'advanced custom fields' => ['icon' => 'mdi:form-textbox', 'color' => '#00d4aa'],
            'gravity forms' => ['icon' => 'mdi:clipboard-text', 'color' => '#99cc33'],
            'mailchimp' => ['icon' => 'mdi:mailbox', 'color' => '#ffe01b'],
            'google analytics' => ['icon' => 'mdi:chart-line', 'color' => '#4285f4'],
            'backup' => ['icon' => 'mdi:backup-restore', 'color' => '#00a0d2'],
            'cache' => ['icon' => 'mdi:cached', 'color' => '#32cd32'],
            'security' => ['icon' => 'mdi:shield', 'color' => '#dc3545'],
            'seo' => ['icon' => 'mdi:search-web', 'color' => '#28a745'],
            'social' => ['icon' => 'mdi:share-variant', 'color' => '#17a2b8'],
            'ecommerce' => ['icon' => 'mdi:shopping', 'color' => '#fd7e14'],
            'analytics' => ['icon' => 'mdi:chart-bar', 'color' => '#6f42c1'],
            'form' => ['icon' => 'mdi:clipboard-text', 'color' => '#20c997'],
            'gallery' => ['icon' => 'mdi:image-multiple', 'color' => '#e83e8c'],
            'slider' => ['icon' => 'mdi:view-carousel', 'color' => '#fd7e14'],
            'page builder' => ['icon' => 'mdi:view-dashboard', 'color' => '#6610f2'],
            'membership' => ['icon' => 'mdi:account-group', 'color' => '#20c997'],
            'booking' => ['icon' => 'mdi:calendar', 'color' => '#17a2b8'],
            'payment' => ['icon' => 'mdi:credit-card', 'color' => '#28a745'],
            'newsletter' => ['icon' => 'mdi:email-newsletter', 'color' => '#0d6efd'],
        ];
    }

    /**
     * @param array<string, array{icon: string, color: string}> $known_plugins
     * @return array{icon: string, color: string}|null
     */
    private function matchKnownPluginIcon(string $haystack, array $known_plugins): ?array
    {
        $result = null;
        foreach ($known_plugins as $name => $data) {
            if (\strpos($haystack, $name) !== false) {
                $result = $data;
                break;
            }
        }

        return $result;
    }

    /**
     * Get author profile URL (optimized - no external API calls)
     *
     * @param array $plugin_data Plugin data array
     * @return string Author profile URL
     */
    public function getAuthorProfileUrl(array $plugin_data): string
    {
        return $plugin_data['AuthorURI'] ?: '';
    }

    /**
     * Get plugin banner using WordPress.org API (with cache)
     *
     * @param string $plugin_file Plugin file path
     * @param array $plugin_data Plugin metadata
     * @return array Banner data with URL
     */
    public function getPluginBanner($plugin_file, $plugin_data)
    {
        // 🚀 Check cache first (instant return)
        $cache_key = 'fleekdash_plugin_banner_' . md5($plugin_file . ($plugin_data['Version'] ?? ''));
        $cached = \get_transient($cache_key);

        if ($cached !== false) {
            return $cached;
        }

        // 🔍 Cache miss - perform expensive lookup
        $banner = $this->fetchPluginBanner($plugin_file);

        // 💾 Cache result for 24 hours
        \set_transient($cache_key, $banner, self::CACHE_DURATION);

        return $banner;
    }

    /**
     * Fetch plugin banner (expensive operation - only called on cache miss)
     *
     * @param string $plugin_file Plugin file path
     * @return array Banner data with URL
     */
    private function fetchPluginBanner(string $plugin_file): array
    {
        $banner = $this->getBannerFromUpdateTransients($plugin_file);

        if ($banner === null) {
            $banner = [
                'type' => 'none',
                'url' => null,
            ];
        }

        return $banner;
    }

    /**
     * @return array<string, mixed>|null
     */
    private function getBannerFromUpdateTransients(string $plugin_file): ?array
    {
        $update_plugins = \get_site_transient('update_plugins');
        if (!\is_object($update_plugins)) {
            return null;
        }

        $result = null;
        foreach (['response', 'no_update'] as $bucket) {
            if ($result !== null) {
                break;
            }

            if (!isset($update_plugins->$bucket) || !\is_array($update_plugins->$bucket)) {
                continue;
            }

            $entries = $update_plugins->$bucket;
            if (empty($entries[$plugin_file]->banners)) {
                continue;
            }

            $url = $this->pickBannerUrlFromTransient((array) $entries[$plugin_file]->banners);
            if ($url !== null) {
                $result = [
                    'type' => 'image',
                    'url' => $url,
                ];
            }
        }

        return $result;
    }

    /**
     * @param array<string, string> $banners
     */
    private function pickBannerUrlFromTransient(array $banners): ?string
    {
        $url = null;
        foreach (['2x', '1x'] as $size) {
            if (!empty($banners[$size])) {
                $url = $banners[$size];
                break;
            }
        }

        return $url;
    }
}
