<?php

namespace FleekDash\Integrations\Core;

defined('ABSPATH') || exit;

/**
 * Optimized Asset Manager for Integrations
 *
 * Handles efficient loading of CSS and JS assets
 */
class AssetManager
{
    private array $scripts = [];
    private array $styles = [];
    private array $inlineScripts = [];
    private array $inlineStyles = [];
    private array $conditionalAssets = [];
    private bool $assetsEnqueued = false;

    public function __construct()
    {
        add_action('wp_enqueue_scripts', [$this, 'enqueueAssets'], 999);
        add_action('admin_enqueue_scripts', [$this, 'enqueueAssets'], 999);
    }

    /**
     * Register a script for conditional loading
     */
    public function registerScript(string $handle, string $src, array $deps = [], ?string $version = null): void
    {
        $this->scripts[$handle] = [
            'src' => $src,
            'deps' => $deps,
            'version' => $version ?: filemtime($this->getAssetPath($src)),
            'footer' => true
        ];
    }

    /**
     * Register a style for conditional loading
     */
    public function registerStyle(string $handle, string $src, array $deps = [], ?string $version = null): void
    {
        $this->styles[$handle] = [
            'src' => $src,
            'deps' => $deps,
            'version' => $version ?: filemtime($this->getAssetPath($src)),
            'media' => 'all'
        ];
    }

    /**
     * Add inline script
     */
    public function addInlineScript(string $handle, string $data, string $position = 'after'): void
    {
        $this->inlineScripts[$handle][$position] = $data;
    }

    /**
     * Add inline style
     */
    public function addInlineStyle(string $handle, string $data): void
    {
        $this->inlineStyles[$handle] = $data;
    }

    /**
     * Register conditional asset loading based on page/context
     */
    public function loadOnPage(string $handle, $pages): void
    {
        if (!is_array($pages)) {
            $pages = [$pages];
        }

        $this->conditionalAssets[$handle] = function () use ($pages) {
            global $pagenow;

            // Check admin pages
            if (is_admin()) {
                return in_array($pagenow, $pages) ||
                    (isset($_GET['page']) && in_array($_GET['page'], $pages));
            }

            // Check frontend pages
            foreach ($pages as $page) {
                if (is_callable($page)) {
                    if ($page())
                        return true;
                } elseif (is_string($page)) {
                    if (is_page($page) || is_single($page))
                        return true;
                }
            }

            return false;
        };
    }

    /**
     * Load assets only when specific conditions are met
     */
    public function loadWhen(string $handle, callable $condition): void
    {
        $this->conditionalAssets[$handle] = $condition;
    }

    /**
     * Enqueue all registered assets based on conditions
     */
    public function enqueueAssets(): void
    {
        if ($this->assetsEnqueued) {
            return;
        }

        // Enqueue scripts
        foreach ($this->scripts as $handle => $script) {
            if ($this->shouldLoadAsset($handle)) {
                wp_enqueue_script($handle, $script['src'], $script['deps'], $script['version'], $script['footer']);

                // Add inline scripts
                if (isset($this->inlineScripts[$handle])) {
                    foreach ($this->inlineScripts[$handle] as $position => $data) {
                        wp_add_inline_script($handle, $data, $position);
                    }
                }
            }
        }

        // Enqueue styles
        foreach ($this->styles as $handle => $style) {
            if ($this->shouldLoadAsset($handle)) {
                wp_enqueue_style($handle, $style['src'], $style['deps'], $style['version'], $style['media']);

                // Add inline styles
                if (isset($this->inlineStyles[$handle])) {
                    wp_add_inline_style($handle, $this->inlineStyles[$handle]);
                }
            }
        }

        $this->assetsEnqueued = true;
    }

    /**
     * Check if an asset should be loaded
     */
    private function shouldLoadAsset(string $handle): bool
    {
        if (isset($this->conditionalAssets[$handle])) {
            $result = call_user_func($this->conditionalAssets[$handle]);
            return (bool) $result;
        }
        return true;
    }

    /**
     * Get asset file path for version checking
     */
    private function getAssetPath(string $src): string
    {
        if (strpos($src, FLEEKDASH_PLUGIN_URL) === 0) {
            return str_replace(FLEEKDASH_PLUGIN_URL, FLEEKDASH_PLUGIN_DIR, $src);
        }
        return $src;
    }

    /**
     * Preload critical assets
     */
    public function preloadCritical(array $assets): void
    {
        add_action('wp_head', function () use ($assets) {
            foreach ($assets as $asset) {
                if (isset($asset['href'])) {
                    echo '<link rel="preload" href="' . esc_url($asset['href']) . '" as="' . esc_attr($asset['as']) . '">';
                }
            }
        }, 1);
    }

    /**
     * Defer non-critical JavaScript
     */
    public function deferScript(string $handle): void
    {
        add_filter('script_loader_tag', function ($tag, $scriptHandle) use ($handle) {
            if ($scriptHandle === $handle) {
                return str_replace('<script ', '<script defer ', $tag);
            }
            return $tag;
        }, 10, 2);
    }

    /**
     * Async load non-critical JavaScript
     */
    public function asyncScript(string $handle): void
    {
        add_filter('script_loader_tag', function ($tag, $scriptHandle) use ($handle) {
            if ($scriptHandle === $handle) {
                return str_replace('<script ', '<script async ', $tag);
            }
            return $tag;
        }, 10, 2);
    }

    /**
     * Create a resource hints for better performance
     */
    public function addResourceHints(): void
    {
        add_action('wp_head', function () {
            // DNS prefetch for external resources
            echo '<link rel="dns-prefetch" href="//fonts.googleapis.com">';
            echo '<link rel="dns-prefetch" href="//api.openai.com">';

            // Preconnect for critical external resources
            echo '<link rel="preconnect" href="//fonts.gstatic.com" crossorigin>';
        }, 1);
    }

    /**
     * Get asset loading statistics
     */
    public function getStats(): array
    {
        return [
            'registered_scripts' => count($this->scripts),
            'registered_styles' => count($this->styles),
            'conditional_assets' => count($this->conditionalAssets),
            'inline_scripts' => count($this->inlineScripts),
            'inline_styles' => count($this->inlineStyles),
            'assets_enqueued' => $this->assetsEnqueued
        ];
    }
}
