<?php
/**
 * Price Information Extractor
 *
 * Extracts price information from content and WooCommerce products.
 *
 * @package BoostBot
 * @since   1.0.0
 */

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class BoostBot_Price_Extractor
 *
 * Extracts prices from page content and WooCommerce products.
 */
class BoostBot_Price_Extractor {

    /**
     * Currency symbols to detect.
     *
     * @var array
     */
    private $currency_symbols = array( '₪', '$', '€', '£', '¥' );

    /**
     * Currency names in Hebrew.
     *
     * @var array
     */
    private $currency_names = array( 'שקל', 'שקלים', 'דולר', 'יורו', 'אירו' );

    /**
     * Extract price info.
     *
     * @param int    $post_id Post ID.
     * @param string $content Content for fallback.
     * @return array|null Price info or null.
     */
    public function extract( int $post_id, string $content = '' ): ?array {
        $post_type = get_post_type( $post_id );

        // WooCommerce products - get full price info.
        if ( 'product' === $post_type && class_exists( 'WooCommerce' ) ) {
            return $this->extract_woocommerce_price( $post_id );
        }

        // Generic price extraction from content.
        return $this->extract_from_content( $content );
    }

    /**
     * Extract WooCommerce product prices.
     *
     * @param int $post_id Product ID.
     * @return array|null Price info.
     */
    private function extract_woocommerce_price( int $post_id ): ?array {
        if ( ! function_exists( 'wc_get_product' ) ) {
            return null;
        }

        $product = wc_get_product( $post_id );

        if ( ! $product ) {
            return null;
        }

        // Resolve currency for the product's language via direct term-meta lookup.
        $product_lang = function_exists( 'pll_get_post_language' )
            ? pll_get_post_language( $post_id )
            : '';
        $currency_override = $product_lang
            ? BoostBot_Polylang_Context::override_currency_for_language( $product_lang )
            : null;

        $resolved = $product_lang
            ? BoostBot_Polylang_Context::get_currency_for_language( $product_lang )
            : array(
                'symbol' => html_entity_decode( get_woocommerce_currency_symbol(), ENT_QUOTES, 'UTF-8' ),
                'code'   => get_woocommerce_currency(),
            );

        $price_info = array(
            'currency'      => $resolved['symbol'],
            'currency_code' => $resolved['code'],
        );

        if ( $product->is_type( 'variable' ) ) {
            $price_info['type']      = 'variable';
            $price_info['min_price'] = (float) $product->get_variation_price( 'min', true );
            $price_info['max_price'] = (float) $product->get_variation_price( 'max', true );

            if ( $price_info['min_price'] === $price_info['max_price'] ) {
                $price_info['display'] = wc_price( $price_info['min_price'] );
            } else {
                $price_info['display'] = sprintf(
                    '%s - %s',
                    wc_price( $price_info['min_price'] ),
                    wc_price( $price_info['max_price'] )
                );
            }
        } else {
            $price_info['type']          = 'simple';
            $price_info['regular_price'] = (float) $product->get_regular_price();
            $price_info['sale_price']    = (float) $product->get_sale_price();
            $price_info['current_price'] = (float) $product->get_price();
            $price_info['on_sale']       = $product->is_on_sale();

            if ( $price_info['on_sale'] && $price_info['regular_price'] > 0 ) {
                $price_info['discount_percentage'] = round(
                    ( ( $price_info['regular_price'] - $price_info['sale_price'] ) / $price_info['regular_price'] ) * 100
                );
                $price_info['display'] = sprintf(
                    '%s (במקום %s - %d%% הנחה!)',
                    wc_price( $price_info['sale_price'] ),
                    wc_price( $price_info['regular_price'] ),
                    $price_info['discount_percentage']
                );
            } else {
                $price_info['display'] = wc_price( $price_info['current_price'] );
            }
        }

        // Stock info.
        $price_info['in_stock']     = $product->is_in_stock();
        $price_info['stock_status'] = $product->get_stock_status();
        $price_info['stock_text']   = $price_info['in_stock'] ? 'במלאי' : 'אזל מהמלאי';

        // Clean display - remove HTML.
        $price_info['display_text'] = wp_strip_all_tags( $price_info['display'] );

        BoostBot_Polylang_Context::restore_currency( $currency_override );

        return $price_info;
    }

    /**
     * Extract prices from generic content.
     *
     * @param string $content Page content.
     * @return array|null Extracted prices.
     */
    private function extract_from_content( string $content ): ?array {
        $prices = array();

        // Build pattern for price detection.
        $symbol_pattern = implode( '|', array_map( 'preg_quote', $this->currency_symbols ) );
        $name_pattern   = implode( '|', $this->currency_names );

        // Pattern: Currency symbol before or after number.
        $patterns = array(
            // ₪100, $50, €30.
            '/(' . $symbol_pattern . ')\s*([0-9,]+(?:\.[0-9]{1,2})?)/u',
            // 100₪, 50$, 30€.
            '/([0-9,]+(?:\.[0-9]{1,2})?)\s*(' . $symbol_pattern . ')/u',
            // מחיר: 100, עלות: 50.
            '/(?:מחיר|price|עלות|cost)[\s:]+([0-9,]+(?:\.[0-9]{1,2})?)\s*(' . $symbol_pattern . ')?/iu',
            // 100 שקלים, 50 דולר.
            '/([0-9,]+(?:\.[0-9]{1,2})?)\s+(' . $name_pattern . ')/u',
        );

        foreach ( $patterns as $pattern ) {
            if ( preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER ) ) {
                foreach ( $matches as $match ) {
                    // Determine currency and amount based on pattern.
                    $currency = '₪'; // Default.
                    $amount   = 0;

                    if ( count( $match ) >= 3 ) {
                        // Check which group is the number.
                        if ( is_numeric( str_replace( ',', '', $match[1] ) ) ) {
                            $amount   = (float) str_replace( ',', '', $match[1] );
                            $currency = $match[2] ?? '₪';
                        } else {
                            $currency = $match[1];
                            $amount   = (float) str_replace( ',', '', $match[2] );
                        }
                    } elseif ( count( $match ) >= 2 ) {
                        $amount = (float) str_replace( ',', '', $match[1] );
                    }

                    // Normalize currency names.
                    if ( in_array( $currency, array( 'שקל', 'שקלים' ), true ) ) {
                        $currency = '₪';
                    } elseif ( $currency === 'דולר' ) {
                        $currency = '$';
                    } elseif ( in_array( $currency, array( 'יורו', 'אירו' ), true ) ) {
                        $currency = '€';
                    }

                    if ( $amount > 0 && $amount < 1000000 ) { // Sanity check.
                        $prices[] = array(
                            'currency' => $currency,
                            'amount'   => $amount,
                            'display'  => $currency . number_format( $amount, 2 ),
                        );
                    }
                }
            }
        }

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

        // Dedupe by amount.
        $unique_prices = array();
        foreach ( $prices as $price ) {
            $key = $price['amount'] . $price['currency'];
            if ( ! isset( $unique_prices[ $key ] ) ) {
                $unique_prices[ $key ] = $price;
            }
        }
        $prices = array_values( $unique_prices );

        // Return single price or range.
        if ( count( $prices ) === 1 ) {
            return array(
                'type'    => 'single',
                'price'   => $prices[0]['amount'],
                'display' => $prices[0]['display'],
            );
        }

        $amounts = array_column( $prices, 'amount' );
        return array(
            'type'      => 'range',
            'min_price' => min( $amounts ),
            'max_price' => max( $amounts ),
            'prices'    => $prices,
            'display'   => sprintf( '%s - %s', min( $amounts ), max( $amounts ) ),
        );
    }

    /**
     * Format price info for display.
     *
     * @param array $price_info Price info array.
     * @return string Formatted price text.
     */
    public function format_for_display( ?array $price_info ): string {
        if ( empty( $price_info ) ) {
            return '';
        }

        $lines = array( '## מחיר:' );

        if ( isset( $price_info['display_text'] ) ) {
            $lines[] = $price_info['display_text'];
        } elseif ( isset( $price_info['display'] ) ) {
            $lines[] = wp_strip_all_tags( $price_info['display'] );
        }

        if ( ! empty( $price_info['on_sale'] ) ) {
            $lines[] = '🔥 במבצע!';
        }

        if ( isset( $price_info['stock_text'] ) ) {
            $lines[] = $price_info['stock_text'];
        }

        return implode( "\n", $lines );
    }
}







