<?php
/**
 * Product Recommender
 *
 * Smart product recommendations based on context and user intent.
 *
 * @package BoostBot
 * @since 1.0.0
 */

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

/**
 * Class BoostBot_Product_Recommender
 *
 * Provides intelligent product recommendations.
 */
class BoostBot_Product_Recommender {

    /**
     * WooCommerce service instance.
     *
     * @var BoostBot_WooCommerce_Service
     */
    private $wc_service;

    /**
     * Constructor.
     */
    public function __construct() {
        $this->wc_service = new BoostBot_WooCommerce_Service();
    }

    /**
     * Get recommendations based on context.
     *
     * @param array       $context  Context data.
     * @param string|null $language Language code for filtering.
     * @return array Recommended products.
     */
    public function get_recommendations( array $context = array(), ?string $language = null ): array {
        $language = $language ?: ( $context['lang'] ?? null );
        $recommendations = array();

        // Based on current product page
        if ( ! empty( $context['current_product_id'] ) ) {
            $related = $this->wc_service->get_related_products( $context['current_product_id'], 3, $language );
            foreach ( $related as $product ) {
                $product['recommendation_type'] = 'related';
                $recommendations[]              = $product;
            }
        }

        // Based on conversation keywords
        if ( ! empty( $context['keywords'] ) ) {
            $keyword_products = $this->get_by_keywords( $context['keywords'], $language );
            foreach ( $keyword_products as $product ) {
                $product['recommendation_type'] = 'keyword_match';
                $recommendations[]              = $product;
            }
        }

        // Based on category
        if ( ! empty( $context['category'] ) ) {
            $category_products = $this->wc_service->get_products_by_category( $context['category'], 3, $language );
            foreach ( $category_products as $product ) {
                $product['recommendation_type'] = 'category';
                $recommendations[]              = $product;
            }
        }

        // Based on price range
        if ( ! empty( $context['price_range'] ) ) {
            $price_products = $this->get_by_price_range( $context['price_range'], $language );
            foreach ( $price_products as $product ) {
                $product['recommendation_type'] = 'price_match';
                $recommendations[]              = $product;
            }
        }

        // Fill with featured/best sellers if not enough
        if ( count( $recommendations ) < 3 ) {
            $featured = $this->wc_service->get_featured_products( 3, $language );
            foreach ( $featured as $product ) {
                $product['recommendation_type'] = 'featured';
                $recommendations[]              = $product;
            }
        }

        // Remove duplicates and limit
        return array_slice( $this->unique_by_id( $recommendations ), 0, 5 );
    }

    /**
     * Analyze user message for product intent.
     *
     * @param string $message User message.
     * @return array Intent analysis.
     */
    public function analyze_user_intent( string $message ): array {
        $intent = array(
            'looking_for_product' => false,
            'price_sensitive'     => false,
            'wants_recommendation'=> false,
            'category'            => null,
            'price_range'         => null,
            'keywords'            => array(),
        );

        $message_lower = mb_strtolower( $message );

        // Price sensitivity
        $price_patterns = array(
            'מחיר',
            'עלות',
            'כמה עולה',
            'זול',
            'יקר',
            'תקציב',
            'משתלם',
            'הנחה',
            'מבצע',
        );

        foreach ( $price_patterns as $pattern ) {
            if ( mb_strpos( $message_lower, $pattern ) !== false ) {
                $intent['price_sensitive'] = true;
                break;
            }
        }

        // Extract price range
        if ( preg_match( '/עד\s*(\d+)/', $message, $matches ) ) {
            $intent['price_range'] = array(
                'min' => 0,
                'max' => intval( $matches[1] ),
            );
        } elseif ( preg_match( '/בין\s*(\d+)\s*ל-?\s*(\d+)/', $message, $matches ) ) {
            $intent['price_range'] = array(
                'min' => intval( $matches[1] ),
                'max' => intval( $matches[2] ),
            );
        }

        // Category detection
        $categories = $this->wc_service->get_categories();
        foreach ( $categories as $category ) {
            if ( mb_stripos( $message_lower, mb_strtolower( $category['name'] ) ) !== false ) {
                $intent['category']            = $category['slug'];
                $intent['looking_for_product'] = true;
                break;
            }
        }

        // Product search intent
        $search_patterns = array(
            'מחפש',
            'רוצה',
            'צריך',
            'יש לכם',
            'אני מעוניין',
            'תראה לי',
            'מה יש',
            'אפשר להמליץ',
            'מה כדאי',
            'מומלץ',
        );

        foreach ( $search_patterns as $pattern ) {
            if ( mb_strpos( $message_lower, $pattern ) !== false ) {
                $intent['looking_for_product']  = true;
                $intent['wants_recommendation'] = true;
                break;
            }
        }

        // Extract keywords
        $intent['keywords'] = $this->extract_keywords( $message );

        return $intent;
    }

    /**
     * Get products by keywords.
     *
     * @param array       $keywords Keywords to search.
     * @param string|null $language Language code.
     * @return array Products.
     */
    public function get_by_keywords( array $keywords, ?string $language = null ): array {
        if ( empty( $keywords ) ) {
            return array();
        }

        $query   = implode( ' ', $keywords );
        $options = array( 'limit' => 3 );
        if ( $language ) {
            $options['lang'] = $language;
        }
        return $this->wc_service->search_products( $query, $options );
    }

    /**
     * Get products by price range.
     *
     * @param array       $range    Price range with min/max.
     * @param string|null $language Language code.
     * @return array Products.
     */
    public function get_by_price_range( array $range, ?string $language = null ): array {
        $options = array(
            'min_price' => $range['min'] ?? 0,
            'max_price' => $range['max'] ?? 999999,
            'limit'     => 3,
        );
        if ( $language ) {
            $options['lang'] = $language;
        }
        return $this->wc_service->search_products( '', $options );
    }

    /**
     * Extract keywords from message.
     *
     * @param string $message User message.
     * @return array Keywords.
     */
    private function extract_keywords( string $message ): array {
        // Remove common Hebrew words
        $stopwords = array(
            'אני', 'את', 'של', 'על', 'עם', 'זה', 'הוא', 'היא', 'הם', 'הן',
            'לי', 'לך', 'לו', 'לה', 'מה', 'איך', 'למה', 'מתי', 'איפה', 'כמה',
            'יש', 'אין', 'רוצה', 'צריך', 'מחפש', 'אפשר', 'כדאי', 'טוב', 'יותר',
            'הכי', 'מאוד', 'קצת', 'הרבה', 'כל', 'עוד', 'גם', 'רק', 'אבל', 'או',
        );

        // Clean and split
        $words = preg_split( '/\s+/', $message );
        $keywords = array();

        foreach ( $words as $word ) {
            $clean_word = preg_replace( '/[^\p{Hebrew}a-zA-Z0-9]/u', '', $word );
            
            if ( mb_strlen( $clean_word ) >= 2 && ! in_array( mb_strtolower( $clean_word ), $stopwords, true ) ) {
                $keywords[] = $clean_word;
            }
        }

        return array_slice( $keywords, 0, 5 );
    }

    /**
     * Remove duplicate products by ID.
     *
     * @param array $products Products array.
     * @return array Unique products.
     */
    private function unique_by_id( array $products ): array {
        $seen = array();
        $unique = array();

        foreach ( $products as $product ) {
            if ( ! isset( $seen[ $product['id'] ] ) ) {
                $seen[ $product['id'] ] = true;
                $unique[]               = $product;
            }
        }

        return $unique;
    }

    /**
     * Generate AI-friendly product recommendations text.
     *
     * @param array       $context  Context data.
     * @param string|null $language Language code.
     * @return string Formatted recommendations for AI.
     */
    public function get_recommendations_for_ai( array $context = array(), ?string $language = null ): string {
        $products = $this->get_recommendations( $context, $language );

        if ( empty( $products ) ) {
            return '';
        }

        $lang = $language ?: ( $context['lang'] ?? 'he' );
        $ps   = BoostBot_Prompt_Strings::get( $lang );

        $text = $ps['recommended_products_header'] . ":\n";
        
        foreach ( $products as $index => $product ) {
            $text .= sprintf(
                "%d. %s - %s%s%s\n",
                $index + 1,
                $product['name'],
                $product['currency'],
                $product['price'],
                $product['is_on_sale'] ? ' ' . $ps['on_sale_badge'] : ''
            );
        }

        return $text;
    }

    /**
     * Get smart response based on intent.
     *
     * @param string      $message  User message.
     * @param string|null $language Language code.
     * @return array|null Response data or null.
     */
    public function get_smart_response( string $message, ?string $language = null ): ?array {
        $intent = $this->analyze_user_intent( $message );

        if ( ! $intent['looking_for_product'] && ! $intent['wants_recommendation'] ) {
            return null;
        }

        $context = array();

        if ( $intent['category'] ) {
            $context['category'] = $intent['category'];
        }

        if ( $intent['price_range'] ) {
            $context['price_range'] = $intent['price_range'];
        }

        if ( ! empty( $intent['keywords'] ) ) {
            $context['keywords'] = $intent['keywords'];
        }

        $products = $this->get_recommendations( $context, $language );

        if ( empty( $products ) ) {
            return null;
        }

        return array(
            'intent'   => $intent,
            'products' => $products,
            'widget'   => array(
                'type' => 'product_carousel',
                'data' => array(
                    'products' => array_slice( $products, 0, 3 ),
                    'title'    => $this->get_carousel_title( $intent ),
                ),
            ),
        );
    }

    /**
     * Get carousel title based on intent.
     *
     * @param array $intent User intent.
     * @return string Title.
     */
    private function get_carousel_title( array $intent ): string {
        if ( $intent['category'] ) {
            return sprintf( __( 'מוצרים בקטגוריה', 'boostbot' ) );
        }

        if ( $intent['price_sensitive'] ) {
            return __( 'מוצרים מומלצים בטווח המחיר', 'boostbot' );
        }

        return __( 'מוצרים מומלצים עבורך', 'boostbot' );
    }
}








