<?php

/**
 * Schema AI Enhancer
 *
 * Uses AI to automatically enhance and generate missing schema data.
 *
 * @package ProRank\SEO\Core\Schema
 * @since   2.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\Schema;

use ProRank\SEO\Plugin;
use ProRank\SEO\AI\Manager as AIManager;

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


/**
 * SchemaAIEnhancer class
 *
 * Provides AI-powered schema enhancements for products
 */


class SchemaAIEnhancer {
    
    /**
     * AI Manager instance
     *
     * @var AIManager|null
     */
    private ?AIManager $ai_manager = null;
    
    /**
     * Cache instance
     *
     * @var SchemaEnhancementCache
     */
    private SchemaEnhancementCache $cache;
    
    /**
     * Constructor
     */
    public function __construct() {
        $plugin = Plugin::get_instance();
        if (method_exists($plugin, 'ai')) {
            $this->ai_manager = $plugin->ai();
        }
        
        // Initialize cache
        $this->cache = new SchemaEnhancementCache();
    }
    
    /**
     * Enhance product schema with AI
     *
     * @param array       $schema  Current schema.
     * @param \WC_Product $product Product object.
     * @return array Enhanced schema.
     */
    public function enhance_product_schema(array $schema, \WC_Product $product): array {
        // Check cache first
        $product_id = $product->get_id();
        $cached_enhancements = $this->cache->get($product_id);
        
        if ($cached_enhancements !== null) {
            // Merge cached enhancements with current schema
            return array_merge($schema, $cached_enhancements);
        }
        
        // Store original schema to calculate what was enhanced
        $original_schema = $schema;
        // Auto-detect brand from various sources
        if (!isset($schema['brand']) && get_option('prorank_seo_ai_detect_brand', true)) {
            $brand = $this->detect_brand($product);
            if ($brand) {
                $schema['brand'] = [
                    '@type' => 'Brand',
                    'name' => $brand
                ];
            }
        }
        
        // Generate description if missing
        if ((!isset($schema['description']) || empty($schema['description'])) 
            && get_option('prorank_seo_ai_generate_descriptions', true)) {
            $description = $this->generate_product_description($product);
            if ($description) {
                $schema['description'] = $description;
            }
        }
        
        // Extract features from product content
        if (get_option('prorank_seo_ai_extract_features', true)) {
            $features = $this->extract_product_features($product);
            if (!empty($features)) {
                $schema['additionalProperty'] = $features;
            }
        }
        
        // Detect product category mapping to Google Product Category
        $google_category = $this->map_to_google_category($product);
        if ($google_category) {
            $schema['googleProductCategory'] = $google_category;
        }
        
        // Add intelligent offer enhancements
        if (isset($schema['offers'])) {
            $schema['offers'] = $this->enhance_offers($schema['offers'], $product);
        }
        
        // Add FAQ schema from product Q&A or comments
        if (get_option('prorank_seo_ai_generate_faq', true)) {
            $faq = $this->generate_faq_schema($product);
            if ($faq) {
                $schema['mainEntity'] = $faq;
            }
        }
        
        // Add energy efficiency for applicable products
        if (get_option('prorank_seo_ai_detect_energy', true)) {
            $energy_info = $this->detect_energy_efficiency($product);
            if ($energy_info) {
                $schema['hasEnergyConsumptionDetails'] = $energy_info;
            }
        }
        
        // Add sustainability information
        if (get_option('prorank_seo_ai_detect_sustainability', true)) {
            $sustainability = $this->detect_sustainability_info($product);
            if ($sustainability) {
                if (!isset($schema['additionalProperty'])) {
                    $schema['additionalProperty'] = [];
                }
                $schema['additionalProperty'][] = [
                    '@type' => 'PropertyValue',
                    'name' => 'Sustainability',
                    'value' => $sustainability
                ];
            }
        }
        
        // Calculate what was enhanced and cache it
        $enhancements = array_diff_key($schema, $original_schema);
        if (!empty($enhancements)) {
            $this->cache->set($product_id, $enhancements);
        }
        
        return $schema;
    }
    
    /**
     * Detect brand from various sources
     *
     * @param \WC_Product $product Product object.
     * @return string|null
     */
    private function detect_brand(\WC_Product $product): ?string {
        // Priority 1: Check brand taxonomies
        $brand_taxonomies = ['product_brand', 'brand', 'pa_brand', 'pwb-brand', 'manufacturer'];
        foreach ($brand_taxonomies as $taxonomy) {
            if (taxonomy_exists($taxonomy)) {
                $terms = get_the_terms($product->get_id(), $taxonomy);
                if ($terms && !is_wp_error($terms) && !empty($terms)) {
                    return $terms[0]->name;
                }
            }
        }
        
        // Priority 2: Check attributes
        $brand_attributes = ['brand', 'manufacturer', 'made_by', 'vendor'];
        foreach ($brand_attributes as $attr) {
            $value = $product->get_attribute($attr);
            if ($value) {
                return $value;
            }
        }
        
        // Priority 3: Check meta fields
        $brand_meta_keys = ['_brand', '_manufacturer', '_product_brand', 'brand_name'];
        foreach ($brand_meta_keys as $meta_key) {
            $value = get_post_meta($product->get_id(), $meta_key, true);
            if ($value) {
                return $value;
            }
        }
        
        // Priority 4: Extract from title using AI/patterns
        $title = $product->get_name();
        $brand = $this->extract_brand_from_title($title);
        if ($brand) {
            return $brand;
        }
        
        // Priority 5: Use store name as fallback for own-brand products
        $categories = wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'names']);
        if (in_array('Own Brand', $categories) || in_array('Store Brand', $categories)) {
            return get_bloginfo('name');
        }
        
        return null;
    }
    
    /**
     * Extract brand from product title
     *
     * @param string $title Product title.
     * @return string|null
     */
    private function extract_brand_from_title(string $title): ?string {
        // Common patterns: "Brand - Product Name", "Product by Brand", etc.
        $patterns = [
            '/^([A-Z][A-Za-z0-9&\s]+)\s*[-–]\s*/', // Brand - Product
            '/\sby\s+([A-Z][A-Za-z0-9&\s]+)$/i',    // Product by Brand
            '/^([A-Z]{2,}[A-Za-z0-9]*)\s+/',        // BRAND Product (all caps brand)
        ];
        
        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $title, $matches)) {
                return trim($matches[1]);
            }
        }
        
        // Check against known brand database
        $known_brands = $this->get_known_brands();
        $title_words = explode(' ', $title);
        
        foreach ($title_words as $word) {
            if (in_array(strtolower($word), $known_brands)) {
                return $word;
            }
        }
        
        return null;
    }
    
    /**
     * Get known brands list
     *
     * @return array
     */
    private function get_known_brands(): array {
        // This would ideally be loaded from a database or API
        // For now, a sample list of common brands
        return [
            'nike', 'adidas', 'apple', 'samsung', 'sony', 'lg', 'dell', 'hp',
            'lenovo', 'asus', 'microsoft', 'google', 'amazon', 'panasonic',
            'philips', 'bosch', 'siemens', 'whirlpool', 'dyson', 'canon'
        ];
    }
    
    /**
     * Generate product description using AI
     *
     * @param \WC_Product $product Product object.
     * @return string|null
     */
    private function generate_product_description(\WC_Product $product): ?string {
        if (!$this->ai_manager) {
            // Fallback: Create basic description from available data
            return $this->generate_basic_description($product);
        }
        
        // Prepare context for AI
        $context = [
            'name' => $product->get_name(),
            'categories' => wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'names']),
            'attributes' => $product->get_attributes(),
            'price' => $product->get_price(),
            'sku' => $product->get_sku()
        ];
        
        $prompt = "Generate a concise, SEO-friendly product description (max 160 characters) for: " 
                . json_encode($context) 
                . ". Focus on key benefits and features.";
        
        try {
            $response = $this->ai_manager->generate($prompt, ['max_tokens' => 50]);
            return trim($response);
        } catch (\Exception $e) {
            return $this->generate_basic_description($product);
        }
    }
    
    /**
     * Generate basic description without AI
     *
     * @param \WC_Product $product Product object.
     * @return string
     */
    private function generate_basic_description(\WC_Product $product): string {
        $parts = [];
        
        // Add product type
        $categories = wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'names']);
        if (!empty($categories)) {
            $parts[] = 'High-quality ' . $categories[0];
        }
        
        // Add key attributes
        $attributes = $product->get_attributes();
        $key_attrs = [];
        foreach ($attributes as $attr) {
            if ($attr->get_visible() && count($key_attrs) < 2) {
                $key_attrs[] = implode(', ', $attr->get_options());
            }
        }
        if (!empty($key_attrs)) {
            $parts[] = 'featuring ' . implode(' and ', $key_attrs);
        }
        
        // Add availability
        if ($product->is_in_stock()) {
            $parts[] = 'available now';
        }
        
        $description = ucfirst(implode(', ', $parts)) . '.';
        
        // Ensure it's not too long
        if (strlen($description) > 160) {
            $description = substr($description, 0, 157) . '...';
        }
        
        return $description;
    }
    
    /**
     * Extract product features
     *
     * @param \WC_Product $product Product object.
     * @return array
     */
    private function extract_product_features(\WC_Product $product): array {
        $features = [];
        
        // Extract from attributes
        $attributes = $product->get_attributes();
        foreach ($attributes as $attribute) {
            if (!$attribute->get_visible()) {
                continue;
            }
            
            $features[] = [
                '@type' => 'PropertyValue',
                'name' => $attribute->get_name(),
                'value' => implode(', ', $attribute->get_options())
            ];
        }
        
        // Extract dimensions if available
        if ($product->has_dimensions()) {
            $features[] = [
                '@type' => 'PropertyValue',
                'name' => 'Dimensions',
                'value' => $product->get_dimensions(false)
            ];
        }
        
        // Extract weight if available
        if ($product->has_weight()) {
            $features[] = [
                '@type' => 'PropertyValue',
                'name' => 'Weight',
                'value' => $product->get_weight() . ' ' . get_option('woocommerce_weight_unit')
            ];
        }
        
        return $features;
    }
    
    /**
     * Map to Google Product Category
     *
     * @param \WC_Product $product Product object.
     * @return string|null
     */
    private function map_to_google_category(\WC_Product $product): ?string {
        // Get WooCommerce categories
        $categories = wp_get_post_terms($product->get_id(), 'product_cat');
        if (empty($categories)) {
            return null;
        }
        
        // Basic mapping (would be more comprehensive in production)
        $mapping = [
            'electronics' => 'Electronics',
            'clothing' => 'Apparel & Accessories',
            'shoes' => 'Apparel & Accessories > Shoes',
            'books' => 'Media > Books',
            'toys' => 'Toys & Games',
            'furniture' => 'Furniture',
            'food' => 'Food, Beverages & Tobacco',
            'beauty' => 'Health & Beauty',
            'sports' => 'Sporting Goods',
            'automotive' => 'Vehicles & Parts'
        ];
        
        foreach ($categories as $category) {
            $cat_slug = strtolower($category->slug);
            foreach ($mapping as $key => $google_cat) {
                if (strpos($cat_slug, $key) !== false) {
                    return $google_cat;
                }
            }
        }
        
        return null;
    }
    
    /**
     * Enhance offers with AI insights
     *
     * @param array       $offers  Current offers.
     * @param \WC_Product $product Product object.
     * @return array
     */
    private function enhance_offers(array $offers, \WC_Product $product): array {
        // Add shipping details if not present
        if (!isset($offers['shippingDetails'])) {
            $shipping = $this->generate_shipping_details($product);
            if ($shipping) {
                $offers['shippingDetails'] = $shipping;
            }
        }
        
        // Add return policy
        if (!isset($offers['hasMerchantReturnPolicy'])) {
            $offers['hasMerchantReturnPolicy'] = [
                '@type' => 'MerchantReturnPolicy',
                'applicableCountry' => WC()->countries->get_base_country(),
                'returnPolicyCategory' => 'https://schema.org/MerchantReturnFiniteReturnWindow',
                'merchantReturnDays' => get_option('woocommerce_return_days', 30),
                'returnMethod' => 'https://schema.org/ReturnByMail',
                'returnFees' => 'https://schema.org/FreeReturn',
                'returnPolicyCountry' => WC()->countries->get_base_country()
            ];
        }
        
        // Add warranty if applicable
        if (get_option('prorank_seo_ai_detect_warranty', true)) {
            $warranty = $this->detect_warranty($product);
            if ($warranty && !isset($offers['warranty'])) {
                $offers['warranty'] = $warranty;
            }
        }
        
        return $offers;
    }
    
    /**
     * Generate shipping details
     *
     * @param \WC_Product $product Product object.
     * @return array|null
     */
    private function generate_shipping_details(\WC_Product $product): ?array {
        if ($product->get_virtual()) {
            return null;
        }
        
        $shipping_class = $product->get_shipping_class();
        $shipping_details = [
            '@type' => 'OfferShippingDetails',
            'shippingDestination' => [
                '@type' => 'DefinedRegion',
                'addressCountry' => WC()->countries->get_base_country()
            ]
        ];
        
        // Add delivery time estimate
        $processing_time = get_option('woocommerce_processing_time', 1);
        $shipping_time = get_option('woocommerce_shipping_time', 3);
        $total_days = $processing_time + $shipping_time;
        
        $shipping_details['deliveryTime'] = [
            '@type' => 'ShippingDeliveryTime',
            'handlingTime' => [
                '@type' => 'QuantitativeValue',
                'minValue' => $processing_time,
                'maxValue' => $processing_time,
                'unitCode' => 'DAY'
            ],
            'transitTime' => [
                '@type' => 'QuantitativeValue',
                'minValue' => $shipping_time,
                'maxValue' => $shipping_time + 2,
                'unitCode' => 'DAY'
            ]
        ];
        
        return $shipping_details;
    }
    
    /**
     * Detect warranty information
     *
     * @param \WC_Product $product Product object.
     * @return array|null
     */
    private function detect_warranty(\WC_Product $product): ?array {
        // Check meta and attributes
        $warranty_period = get_post_meta($product->get_id(), '_warranty_period', true);
        if (!$warranty_period) {
            $warranty_period = $product->get_attribute('warranty');
        }
        
        if (!$warranty_period) {
            return null;
        }
        
        return [
            '@type' => 'WarrantyPromise',
            'durationOfWarranty' => [
                '@type' => 'QuantitativeValue',
                'value' => $warranty_period,
                'unitCode' => 'MON' // Months
            ],
            'warrantyScope' => 'https://schema.org/Worldwide'
        ];
    }
    
    /**
     * Generate FAQ schema from comments/Q&A
     *
     * @param \WC_Product $product Product object.
     * @return array|null
     */
    private function generate_faq_schema(\WC_Product $product): ?array {
        // Get product reviews that look like questions
        $comments = get_comments([
            'post_id' => $product->get_id(),
            'status' => 'approve',
            'type' => 'review'
        ]);
        
        if (empty($comments)) {
            return null;
        }
        
        $faqs = [];
        foreach ($comments as $comment) {
            // Look for questions in reviews
            if (strpos($comment->comment_content, '?') !== false) {
                // Check if there's a reply
                $replies = get_comments([
                    'parent' => $comment->comment_ID,
                    'status' => 'approve'
                ]);
                
                if (!empty($replies)) {
                    $faqs[] = [
                        '@type' => 'Question',
                        'name' => wp_strip_all_tags($comment->comment_content),
                        'acceptedAnswer' => [
                            '@type' => 'Answer',
                            'text' => wp_strip_all_tags($replies[0]->comment_content)
                        ]
                    ];
                }
            }
        }
        
        if (empty($faqs)) {
            return null;
        }
        
        return [
            '@type' => 'FAQPage',
            'mainEntity' => $faqs
        ];
    }
    
    /**
     * Detect energy efficiency information
     *
     * @param \WC_Product $product Product object.
     * @return array|null
     */
    private function detect_energy_efficiency(\WC_Product $product): ?array {
        // Check if product is in applicable categories
        $categories = wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'slugs']);
        $energy_categories = ['appliances', 'electronics', 'lighting', 'hvac', 'refrigerators'];
        
        $is_applicable = false;
        foreach ($categories as $cat) {
            if (in_array($cat, $energy_categories)) {
                $is_applicable = true;
                break;
            }
        }
        
        if (!$is_applicable) {
            return null;
        }
        
        // Check for energy rating
        $energy_rating = get_post_meta($product->get_id(), '_energy_rating', true);
        if (!$energy_rating) {
            $energy_rating = $product->get_attribute('energy_rating');
        }
        
        if (!$energy_rating) {
            return null;
        }
        
        return [
            '@type' => 'EnergyConsumptionDetails',
            'hasEnergyEfficiencyCategory' => 'https://schema.org/EUEnergyEfficiencyCategory' . strtoupper($energy_rating),
            'energyEfficiencyScaleMin' => 'https://schema.org/EUEnergyEfficiencyCategoryG',
            'energyEfficiencyScaleMax' => 'https://schema.org/EUEnergyEfficiencyCategoryA'
        ];
    }
    
    /**
     * Detect sustainability information
     *
     * @param \WC_Product $product Product object.
     * @return string|null
     */
    private function detect_sustainability_info(\WC_Product $product): ?string {
        $sustainability_terms = [
            'eco-friendly', 'sustainable', 'recycled', 'organic', 'biodegradable',
            'carbon-neutral', 'fair-trade', 'renewable', 'green'
        ];
        
        // Check product title and description
        $content = strtolower($product->get_name() . ' ' . $product->get_description());
        
        $found_terms = [];
        foreach ($sustainability_terms as $term) {
            if (strpos($content, $term) !== false) {
                $found_terms[] = $term;
            }
        }
        
        // Check attributes
        $eco_attr = $product->get_attribute('eco_friendly');
        if ($eco_attr) {
            $found_terms[] = 'eco-certified';
        }
        
        if (empty($found_terms)) {
            return null;
        }
        
        return implode(', ', array_unique($found_terms));
    }
}