<?php
/**
 * CDN Controller
 *
 * Handles CDN admin hooks, media change events, product sale boundaries,
 * and AJAX handlers for CDN testing and configuration.
 *
 * @package Mamba\Modules\CDN
 * @since   1.0.0
 */

namespace Mamba\Modules\CDN;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use Mamba\Modules\CDN\Services\Manager;
use Mamba\Modules\CDN\Services\CdnMirror;
use Mamba\Modules\CDN\Services\Detectors;

/**
 * Class Controller
 *
 * CDN Controller that handles admin hooks, media integration,
 * product sale events, and AJAX handlers for CDN management.
 *
 * @since 1.0.0
 */
final class Controller {
    public function register(): void {
        // Register admin hooks
        add_action('admin_menu', [__CLASS__, 'addAdminMenu'], 71);
        
        // Register media hooks for CDN purging
        add_action('add_attachment', [__CLASS__, 'onMediaChange']);
        add_action('edit_attachment', [__CLASS__, 'onMediaChange']);
        add_action('delete_attachment', [__CLASS__, 'onMediaChange']);
        
        // Register product hooks for sale boundaries
        add_action('save_post_product', [__CLASS__, 'onProductSave'], 20, 2);
        add_action('woocommerce_update_product', [__CLASS__, 'onProductUpdate'], 20, 1);
        
        // Register sale boundary hooks - use existing system
        add_action('mamba_product_sale_event', [__CLASS__, 'onExistingSaleEvent'], 10, 1);
        
        // Register AJAX handlers
        add_action('wp_ajax_mamba_cdn_test_connection', [__CLASS__, 'ajaxTestConnection']);
        add_action('wp_ajax_mamba_cdn_test_purge', [__CLASS__, 'ajaxTestPurge']);
        add_action('wp_ajax_mamba_cdn_apply_recommended_settings', [__CLASS__, 'ajaxApplyRecommendedSettings']);
    }
    
    /**
     * Add admin menu
     */
    public static function addAdminMenu(): void {
        // This is just for any additional admin functionality
    }
    
    /**
     * Handle media changes for CDN purging
     */
    public static function onMediaChange(int $attachmentId): void {
        if (!Manager::isEnabled()) return;
        
        $provider = Manager::getProvider();
        if (!$provider) return;
        
        // Get all variant URLs for the attachment
        $urls = self::getMediaVariantUrls($attachmentId);
        if (empty($urls)) return;
        
        // Get header combinations for APO if needed
        $headerCombos = [];
        if (Manager::getProviderName() === 'cloudflare') {
            $headerCombos = Detectors::generateCloudflareHeaderCombos();
        }
        
        // Trigger CDN purge
        do_action('mamba_purge_urls', $urls, $headerCombos);
        
        // Handle media family purging for Bunny
        if (Manager::getProviderName() === 'bunny' && $provider instanceof \Mamba\Modules\CDN\Services\BunnyAdapter) {
            try {
                $provider->purgeMediaFamily($attachmentId);
            } catch (\Exception $e) {
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    error_log('Mamba CDN: Media family purge failed: ' . $e->getMessage());
                }
            }
        }
    }
    
    /**
     * Get all variant URLs for a media attachment
     */
    private static function getMediaVariantUrls(int $attachmentId): array {
        $urls = [];
        
        // Get the main file URL
        $mainUrl = wp_get_attachment_url($attachmentId);
        if ($mainUrl) {
            $urls[] = $mainUrl;
        }
        
        // Get all image sizes
        $sizes = get_intermediate_image_sizes();
        foreach ($sizes as $size) {
            $imageData = wp_get_attachment_image_src($attachmentId, $size);
            if ($imageData && isset($imageData[0])) {
                $urls[] = $imageData[0];
            }
        }
        
        // Get WebP variants if they exist
        $webpVariants = self::getWebPVariants($attachmentId);
        $urls = array_merge($urls, $webpVariants);
        
        return array_unique($urls);
    }
    
    /**
     * Get WebP variants for an attachment
     */
    private static function getWebPVariants(int $attachmentId): array {
        $urls = [];
        
        // Check if WebP conversion is enabled
        if (!get_option('mamba_enable_webp_conversion', false)) {
            return $urls;
        }
        
        $mainUrl = wp_get_attachment_url($attachmentId);
        if (!$mainUrl) return $urls;
        
        // Check if WebP version exists
        $webpUrl = preg_replace('/\.(jpg|jpeg|png)$/i', '.webp', $mainUrl);
        if ($webpUrl !== $mainUrl) {
            $webpPath = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $webpUrl);
            if (file_exists($webpPath)) {
                $urls[] = $webpUrl;
            }
        }
        
        // Check WebP variants for different sizes
        $sizes = get_intermediate_image_sizes();
        foreach ($sizes as $size) {
            $imageData = wp_get_attachment_image_src($attachmentId, $size);
            if ($imageData && isset($imageData[0])) {
                $webpUrl = preg_replace('/\.(jpg|jpeg|png)$/i', '.webp', $imageData[0]);
                if ($webpUrl !== $imageData[0]) {
                    $webpPath = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $webpUrl);
                    if (file_exists($webpPath)) {
                        $urls[] = $webpUrl;
                    }
                }
            }
        }
        
        return $urls;
    }
    
    /**
     * Handle product saves for sale boundary scheduling
     */
    public static function onProductSave(int $postId, \WP_Post $post): void {
        if ($post->post_type !== 'product') return;
        
        $product = wc_get_product($postId);
        if (!$product) return;
        
        // Use existing sale boundary scheduling system
        \Mamba\Modules\Caching\Services\Invalidation::scheduleSaleEventsForProduct($product->get_id());
    }
    
    /**
     * Handle product updates for sale boundary scheduling
     */
    public static function onProductUpdate($product): void {
        // Handle both WC_Product object and product ID
        $productId = 0;
        
        if ($product instanceof \WC_Product) {
            $productId = $product->get_id();
        } elseif (is_numeric($product)) {
            $productId = (int) $product;
        } else {
            return; // Invalid parameter
        }
        
        if ($productId <= 0) return;
        
        // Use existing sale boundary scheduling system
        \Mamba\Modules\Caching\Services\Invalidation::scheduleSaleEventsForProduct($productId);
    }
    
    /**
     * Handle existing sale boundary events
     */
    public static function onExistingSaleEvent($args): void {
        $pid = 0;
        $type = '';
        if (is_array($args)) {
            $pid = (int)($args['product_id'] ?? 0);
            $type = $args['type'] ?? '';
        }
        
        if ($pid <= 0) return;
        
        $product = wc_get_product($pid);
        if (!$product) return;
        
        // Generate tags for the product and its terms
        $tags = self::generateProductTags($product);
        
        // Add Store API tags
        $tags[] = 'store_api_products';
        $tags[] = 'store_api_catalog';
        
        // Trigger tag purge
        do_action('mamba_purge_tags', $tags);
        
        // Trigger warmup for critical URLs
        self::warmupCriticalUrls($product);
    }
    
    /**
     * Generate tags for a product
     */
    private static function generateProductTags($product): array {
        $tags = [];
        
        // Ensure we have a valid product object
        if (!$product || !is_object($product) || !method_exists($product, 'get_id')) {
            return $tags;
        }
        
        $productId = $product->get_id();
        if ($productId <= 0) return $tags;
        
        $tags[] = 'product_' . $productId;
        
        // Add category tags
        $categories = get_the_terms($productId, 'product_cat');
        if ($categories && !is_wp_error($categories)) {
            foreach ($categories as $category) {
                $tags[] = 'category_' . $category->term_id;
            }
        }
        
        // Add tag tags
        $productTags = get_the_terms($productId, 'product_tag');
        if ($productTags && !is_wp_error($productTags)) {
            foreach ($productTags as $tag) {
                $tags[] = 'tag_' . $tag->term_id;
            }
        }
        
        return array_unique($tags);
    }
    
    /**
     * Warmup critical URLs for a product
     */
    private static function warmupCriticalUrls($product): void {
        $urls = [];
        
        // Ensure we have a valid product object
        if (!$product || !is_object($product) || !method_exists($product, 'get_id')) {
            return;
        }
        
        $productId = $product->get_id();
        if ($productId <= 0) return;
        
        // Product page
        $productLink = get_permalink($productId);
        if ($productLink && filter_var($productLink, FILTER_VALIDATE_URL)) {
            $urls[] = $productLink;
        }
        
        // Shop page
        $shopUrl = wc_get_page_permalink('shop');
        if ($shopUrl && filter_var($shopUrl, FILTER_VALIDATE_URL)) {
            $urls[] = $shopUrl;
        }
        
        // Category pages
        $categories = get_the_terms($productId, 'product_cat');
        if ($categories && !is_wp_error($categories)) {
            foreach ($categories as $category) {
                $catLink = get_term_link($category);
                if (!is_wp_error($catLink) && $catLink && filter_var($catLink, FILTER_VALIDATE_URL)) {
                    $urls[] = $catLink;
                }
            }
        }
        
        // Trigger warmup (targeted) using existing API
        if (!empty($urls)) {
            $urls = array_values(array_unique(array_filter($urls)));
            foreach ($urls as $u) {
                \Mamba\Modules\Caching\Services\Preload\Preloader::warmOne($u);
            }
        }
    }
    
    /**
     * AJAX handler for testing CDN connection
     */
    public static function ajaxTestConnection(): void {
        check_ajax_referer('mamba_cdn_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized');
        }
        
        $provider = Manager::getProvider();
        if (!$provider) {
            wp_send_json_error('No CDN provider configured');
        }
        
        $result = $provider->testConnection();
        
        if ($result->isSuccess()) {
            wp_send_json_success($result->getMessage());
        } else {
            wp_send_json_error($result->getMessage());
        }
    }
    
    /**
     * AJAX handler for testing CDN purge
     */
    public static function ajaxTestPurge(): void {
        check_ajax_referer('mamba_cdn_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized');
        }
        
        $provider = Manager::getProvider();
        if (!$provider) {
            wp_send_json_error('No CDN provider configured');
        }
        
        $type = sanitize_text_field(wp_unslash($_POST['type'] ?? 'url'));
        $testUrl = home_url('/');
        
        if ($type === 'tag') {
            $result = $provider->purgeTags(['test_tag']);
        } else {
            $result = $provider->purgeUrls([$testUrl]);
        }
        
        if ($result->isSuccess()) {
            wp_send_json_success($result->getMessage());
        } else {
            wp_send_json_error($result->getMessage());
        }
    }
    
    /**
     * AJAX handler for applying recommended settings
     */
    public static function ajaxApplyRecommendedSettings(): void {
        check_ajax_referer('mamba_cdn_nonce', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_die('Unauthorized');
        }
        
        $provider = Manager::getProvider();
        if (!$provider) {
            wp_send_json_error('No CDN provider configured');
        }
        
        $result = $provider->applyRecommendedSettings();
        
        if ($result->isSuccess()) {
            wp_send_json_success($result->getMessage());
        } else {
            wp_send_json_error($result->getMessage());
        }
    }
}
