<?php

namespace FleekDash\Services\GrowthAchievements;

if (!\function_exists('fleekdash_log_debug')) {
    require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/debug-helpers.php';
}

/**
 * Growth Achievements Calculator
 *
 * Handles all monthly value calculations for different event types
 * Includes caching for performance optimization
 *
 * @package FleekDash\Services\GrowthAchievements
 * @since V2.2
 */
class GrowthAchievementsCalculator
{
    /**
     * Cache for monthly calculations to improve performance
     */
    private static $monthlyCache = [];

    /**
     * Maximum cache age in seconds (5 minutes)
     */
    private const CACHE_TTL = 300;

    /**
     * Calculate monthly value for specific event and configuration
     * With caching for performance
     *
     * @param string $event_type Event type
     * @param array $event_config Event configuration
     * @param string $month_start Start of month (YYYY-MM-DD HH:MM:SS)
     * @param string $month_end End of month (YYYY-MM-DD HH:MM:SS)
     * @return int Monthly count for this event+config
     */
    public static function calculateMonthlyValue($event_type, $event_config, $month_start, $month_end)
    {
        // Create cache key
        $cache_key = md5($event_type . '|' . json_encode($event_config) . '|' . $month_start);

        // Check cache first
        if (isset(self::$monthlyCache[$cache_key])) {
            $cached = self::$monthlyCache[$cache_key];
            if ((time() - $cached['timestamp']) < self::CACHE_TTL) {
                return $cached['value'];
            }
        }

        $value = 0;

        try {
            switch ($event_type) {
                case 'new_post':
                    $value = self::calculateMonthlyPosts($event_config, $month_start, $month_end);
                    break;

                case 'new_user':
                    $value = self::calculateMonthlyUsers($month_start, $month_end);
                    break;

                case 'new_comment':
                    $value = self::calculateMonthlyComments($month_start, $month_end);
                    break;

                case 'new_order':
                    $value = self::calculateMonthlyOrders($month_start, $month_end);
                    break;

                case 'new_product':
                    $value = self::calculateMonthlyProducts($month_start, $month_end);
                    break;

                case 'product_review':
                    $value = self::calculateMonthlyReviews($month_start, $month_end);
                    break;

                default:
                    // Custom events - no reliable monthly source without event logs
                    $value = 0;
                    break;
            }

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash: Error calculating monthly value for {$event_type}: " . $e->getMessage());
            $value = 0;
        }

        // Cache the result
        self::$monthlyCache[$cache_key] = [
            'value' => $value,
            'timestamp' => time()
        ];

        return $value;
    }

    /**
     * Calculate monthly posts for specific configuration
     *
     * @param array $event_config Event configuration
     * @param string $month_start Start of month
     * @param string $month_end End of month
     * @return int Count of posts
     */
    private static function calculateMonthlyPosts($event_config, $month_start, $month_end)
    {
        global $wpdb;

        $post_type = $event_config['post_type'] ?? null;

        if ($post_type) {
            // Specific post type
            $sql = "SELECT COUNT(*) FROM {$wpdb->posts}
                    WHERE post_type = %s
                    AND post_status = 'publish'
                    AND post_date >= %s AND post_date <= %s";
            return (int) $wpdb->get_var($wpdb->prepare($sql, $post_type, $month_start, $month_end));
        } else {
            // All allowed post types
            $excluded_types = ['page', 'profile'];
            $post_types = \get_post_types(['public' => true], 'names');
            $allowed_types = array_values(array_diff($post_types, $excluded_types));

            if (empty($allowed_types)) {
                return 0;
            }

            $placeholders = implode(',', array_fill(0, count($allowed_types), '%s'));
            $query = "SELECT COUNT(*) FROM {$wpdb->posts}
                      WHERE post_type IN ({$placeholders})
                      AND post_status = 'publish'
                      AND post_date >= %s AND post_date <= %s";

            $params = array_merge($allowed_types, [$month_start, $month_end]);
            return (int) $wpdb->get_var($wpdb->prepare($query, $params));
        }
    }

    /**
     * Calculate monthly users
     *
     * @param string $month_start Start of month
     * @param string $month_end End of month
     * @return int Count of users
     */
    private static function calculateMonthlyUsers($month_start, $month_end)
    {
        global $wpdb;

        $sql = "SELECT COUNT(*) FROM {$wpdb->users}
                WHERE user_registered >= %s AND user_registered <= %s";

        return (int) $wpdb->get_var($wpdb->prepare($sql, $month_start, $month_end));
    }

    /**
     * Calculate monthly comments
     *
     * @param string $month_start Start of month
     * @param string $month_end End of month
     * @return int Count of comments
     */
    private static function calculateMonthlyComments($month_start, $month_end)
    {
        global $wpdb;

        $sql = "SELECT COUNT(*) FROM {$wpdb->comments}
                WHERE comment_approved = '1'
                AND comment_date >= %s AND comment_date <= %s";

        return (int) $wpdb->get_var($wpdb->prepare($sql, $month_start, $month_end));
    }

    /**
     * Calculate monthly orders (WooCommerce)
     *
     * @param string $month_start Start of month
     * @param string $month_end End of month
     * @return int Count of orders
     */
    private static function calculateMonthlyOrders($month_start, $month_end)
    {
        if (!class_exists('WooCommerce')) {
            return 0;
        }

        global $wpdb;

        $sql = "SELECT COUNT(*) FROM {$wpdb->posts}
                WHERE post_type = 'shop_order'
                AND post_status IN ('wc-completed', 'wc-processing')
                AND post_date >= %s AND post_date <= %s";

        return (int) $wpdb->get_var($wpdb->prepare($sql, $month_start, $month_end));
    }

    /**
     * Calculate monthly products (WooCommerce)
     *
     * @param string $month_start Start of month
     * @param string $month_end End of month
     * @return int Count of products
     */
    private static function calculateMonthlyProducts($month_start, $month_end)
    {
        if (!class_exists('WooCommerce')) {
            return 0;
        }

        global $wpdb;

        $sql = "SELECT COUNT(*) FROM {$wpdb->posts}
                WHERE post_type = 'product'
                AND post_status = 'publish'
                AND post_date >= %s AND post_date <= %s";

        return (int) $wpdb->get_var($wpdb->prepare($sql, $month_start, $month_end));
    }

    /**
     * Calculate monthly reviews (WooCommerce)
     *
     * @param string $month_start Start of month
     * @param string $month_end End of month
     * @return int Count of reviews
     */
    private static function calculateMonthlyReviews($month_start, $month_end)
    {
        if (!class_exists('WooCommerce')) {
            return 0;
        }

        global $wpdb;

        $sql = "SELECT COUNT(*) FROM {$wpdb->comments} c
                JOIN {$wpdb->posts} p ON p.ID = c.comment_post_ID
                WHERE c.comment_approved = '1'
                AND p.post_type = 'product'
                AND c.comment_date >= %s AND c.comment_date <= %s";

        return (int) $wpdb->get_var($wpdb->prepare($sql, $month_start, $month_end));
    }

    /**
     * Clear cache for specific event type and config
     *
     * @param string $event_type Event type
     * @param array $event_config Event configuration
     * @return void
     */
    public static function clearCacheForEvent($event_type, $event_config)
    {
        $pattern = md5($event_type . '|' . json_encode($event_config));

        foreach (array_keys(self::$monthlyCache) as $key) {
            if (strpos($key, $pattern) === 0) {
                unset(self::$monthlyCache[$key]);
            }
        }
    }

    /**
     * Clear all calculation cache
     *
     * @return void
     */
    public static function clearAllCache()
    {
        self::$monthlyCache = [];
    }
}
