<?php

namespace FleekDash\Services\GrowthAchievements;

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

use FleekDash\Services\GrowthAchievements\GrowthAchievementsCalculator;
use FleekDash\Services\GrowthAchievements\GrowthAchievementsDashboard;

/**
 * Growth Achievements Engine Core
 *
 * Main orchestration for the achievements system
 * Handles event creation, monthly processing, and achievement unlocking
 * (v2.2) Uses WordPress-native $wpdb queries instead of Eloquent
 *
 * @package FleekDash\Services\GrowthAchievements
 * @since V2.2
 */
class GrowthAchievementsEngineCore
{
    /**
     * Auto-create achievements for all active events
     * Called during initialization or when new events are added
     * (v2.2) Converted from Eloquent to WordPress-native
     *
     * @return array Summary of created achievements
     */
    public static function autoCreateAchievementsForAllEvents()
    {
        global $wpdb;

        $created = [];
        $skipped = [];
        $errors = [];

        try {
            // V2.2: Direct $wpdb query instead of Eloquent
            $events_table = $wpdb->prefix . 'fleekdash_site_growth_events';
            $active_events = $wpdb->get_results(
                "SELECT * FROM {$events_table} WHERE is_active = 1",
                ARRAY_A
            );

            foreach ($active_events as $event) {
                $event_config = [];

                // Parse tracking_config
                if (!empty($event['tracking_config'])) {
                    if (is_string($event['tracking_config'])) {
                        $decoded = json_decode($event['tracking_config'], true);
                        // Handle double-encoded JSON
                        if (is_string($decoded)) {
                            $decoded = json_decode($decoded, true);
                        }
                        $event_config = is_array($decoded) ? $decoded : [];
                    } elseif (is_array($event['tracking_config'])) {
                        $event_config = $event['tracking_config'];
                    }
                }

                // Create achievement for this event
                $achievement = self::createAchievementForEvent(
                    $event['event_type'],
                    $event_config
                );

                if ($achievement) {
                    $created[] = [
                        'event_id' => $event['id'],
                        'event_type' => $event['event_type'],
                        'event_name' => $event['event_name'],
                        'achievement_id' => $achievement['id'],
                        'achievement_name' => $achievement['achievement_name'],
                        'target_value' => $achievement['target_value'],
                        'current_record' => $achievement['current_record']
                    ];
                } else {
                    $skipped[] = [
                        'event_id' => $event['id'],
                        'event_type' => $event['event_type'],
                        'reason' => 'Already exists or creation failed'
                    ];
                }
            }

        } catch (\Exception $e) {
            $errors[] = $e->getMessage();
            fleekdash_log_error("FleekDash: Error in autoCreateAchievementsForAllEvents: " . $e->getMessage());
        }

        return [
            'created' => $created,
            'skipped' => $skipped,
            'errors' => $errors,
            'summary' => [
                'total_created' => count($created),
                'total_skipped' => count($skipped),
                'total_errors' => count($errors)
            ]
        ];
    }

    /**
     * Process monthly achievements check
     * Called at the end of each month or on-demand
     * (v2.2) Uses Calculator service
     *
     * @param string|null $month_period Specific month to check (YYYY-MM-01) or null for current
     * @return array Summary of achievements processed
     */
    public static function processMonthlyAchievements($month_period = null)
    {
        global $wpdb;

        $month_start = $month_period ?: date('Y-m-01');
        $month_end = date('Y-m-t 23:59:59', strtotime($month_start));

        $results = [
            'month_period' => $month_start,
            'achievements_checked' => 0,
            'achievements_unlocked' => 0,
            'new_records_set' => 0,
            'targets_auto_scaled' => 0,
            'unlocked_achievements' => []
        ];

        try {
            // V2.2: Direct $wpdb query
            $table = $wpdb->prefix . 'fleekdash_site_growth_achievements';
            $achievements = $wpdb->get_results(
                "SELECT * FROM {$table}
                 WHERE achievement_type = 'event_record'
                 AND is_active = 1",
                ARRAY_A
            );

            foreach ($achievements as $achievement) {
                $results['achievements_checked']++;

                // V2.2: Use Calculator service
                $monthly_value = GrowthAchievementsCalculator::calculateMonthlyValue(
                    $achievement['event_type'],
                    json_decode($achievement['event_config'], true) ?: [],
                    $month_start,
                    $month_end
                );

                // Update achievement progress
                $was_newly_achieved = self::updateAchievementProgress(
                    $achievement['id'],
                    $monthly_value
                );

                if ($was_newly_achieved) {
                    $results['achievements_unlocked']++;

                    // Get updated achievement data
                    $updated = $wpdb->get_row($wpdb->prepare(
                        "SELECT * FROM {$table} WHERE id = %d",
                        $achievement['id']
                    ), ARRAY_A);

                    $results['unlocked_achievements'][] = [
                        'id' => $achievement['id'],
                        'name' => $achievement['achievement_name'],
                        'category' => $achievement['category'],
                        'value_achieved' => $monthly_value,
                        'target_was' => $achievement['target_value'],
                        'new_target' => $updated['target_value']
                    ];
                }

                if ($monthly_value > $achievement['current_record']) {
                    $results['new_records_set']++;
                }
            }

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash: Error in processMonthlyAchievements: " . $e->getMessage());
        }

        return $results;
    }

    /**
     * Hook into event creation to auto-create achievements
     * Called when new SiteGrowthEvent is created
     * (v2.2) WordPress-native
     *
     * @param string $event_type Event type
     * @param array $event_config Event configuration
     * @return array|false Created achievement or false
     */
    public static function onEventCreated($event_type, $event_config = [])
    {
        try {
            // Create achievement for this new event
            $achievement = self::createAchievementForEvent($event_type, $event_config);

            if ($achievement) {
                // Clear relevant caches
                GrowthAchievementsCalculator::clearCacheForEvent($event_type, $event_config);
                GrowthAchievementsDashboard::clearDashboardCache();

                // Log successful creation
                fleekdash_log_info("FleekDash: Auto-created achievement '{$achievement['achievement_name']}' for event '{$event_type}'");

                return $achievement;
            }

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash: Error auto-creating achievement for event {$event_type}: " . $e->getMessage());
        }

        return false;
    }

    /**
     * Process achievement updates when events occur
     * Called from SiteGrowthMeterService when events are tracked
     * (v2.2) WordPress-native with Calculator service
     *
     * @param string $event_type Event type that occurred
     * @param array $event_config Event configuration
     * @return array Summary of achievements affected
     */
    public static function onEventOccurred($event_type, $event_config = [])
    {
        global $wpdb;

        $results = [
            'achievements_checked' => 0,
            'achievements_updated' => 0,
            'achievements_unlocked' => 0,
            'new_records_set' => 0
        ];

        try {
            // Find achievements for this event type and config
            $config_hash = md5(json_encode($event_config));
            $table = $wpdb->prefix . 'fleekdash_site_growth_achievements';

            $achievements = $wpdb->get_results($wpdb->prepare(
                "SELECT * FROM {$table}
                 WHERE achievement_type = 'event_record'
                 AND event_type = %s
                 AND event_config_hash = %s
                 AND is_active = 1",
                $event_type,
                $config_hash
            ), ARRAY_A);

            // If no achievement exists, create one
            if (empty($achievements)) {
                $new_achievement = self::onEventCreated($event_type, $event_config);
                if ($new_achievement) {
                    $achievements = [$new_achievement];
                }
            }

            // Update each matching achievement
            foreach ($achievements as $achievement) {
                $results['achievements_checked']++;

                // Calculate current month performance using Calculator service
                $month_start = date('Y-m-01 00:00:00');
                $month_end = date('Y-m-t 23:59:59');

                $monthly_value = GrowthAchievementsCalculator::calculateMonthlyValue(
                    $event_type,
                    $event_config,
                    $month_start,
                    $month_end
                );

                // Update achievement progress
                $was_newly_achieved = self::updateAchievementProgress(
                    $achievement['id'],
                    $monthly_value
                );

                if ($was_newly_achieved) {
                    $results['achievements_unlocked']++;

                    // Log achievement unlock
                    fleekdash_log_info("FleekDash: Achievement unlocked! '{$achievement['achievement_name']}' - Value: {$monthly_value}");
                }

                if ($monthly_value > $achievement['current_record']) {
                    $results['new_records_set']++;
                }

                $results['achievements_updated']++;
            }

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash: Error in onEventOccurred for {$event_type}: " . $e->getMessage());
        }

        return $results;
    }

    /**
     * Force recalculation of all achievements (maintenance function)
     * (v2.2) WordPress-native
     *
     * @return array Summary of recalculation results
     */
    public static function recalculateAllAchievements()
    {
        global $wpdb;

        $results = [
            'total_processed' => 0,
            'targets_updated' => 0,
            'records_updated' => 0,
            'errors' => []
        ];

        try {
            $table = $wpdb->prefix . 'fleekdash_site_growth_achievements';
            $achievements = $wpdb->get_results(
                "SELECT * FROM {$table} WHERE is_active = 1",
                ARRAY_A
            );

            foreach ($achievements as $achievement) {
                $results['total_processed']++;

                try {
                    // Recalculate historical record
                    $event_config = json_decode($achievement['event_config'], true) ?: [];
                    $new_record = self::calculateHistoricalRecord(
                        $achievement['event_type'],
                        $event_config
                    );

                    $old_record = $achievement['current_record'];
                    $old_target = $achievement['target_value'];

                    // Update record if changed
                    if ($new_record != $old_record) {
                        $wpdb->update(
                            $table,
                            ['current_record' => $new_record],
                            ['id' => $achievement['id']],
                            ['%d'],
                            ['%d']
                        );
                        $results['records_updated']++;
                    }

                    // Recalculate target
                    $new_target = self::calculateIntelligentTarget(
                        $new_record,
                        $achievement['event_type']
                    );

                    if ($new_target != $old_target) {
                        $wpdb->update(
                            $table,
                            [
                                'target_value' => $new_target,
                                'is_achieved' => $new_record >= $new_target ? 1 : 0
                            ],
                            ['id' => $achievement['id']],
                            ['%d', '%d'],
                            ['%d']
                        );
                        $results['targets_updated']++;
                    }

                    // Update last calculated timestamp
                    $wpdb->update(
                        $table,
                        ['last_calculated_at' => \current_time('mysql')],
                        ['id' => $achievement['id']],
                        ['%s'],
                        ['%d']
                    );

                } catch (\Exception $e) {
                    $results['errors'][] = "Achievement {$achievement['id']}: " . $e->getMessage();
                }
            }

            // Clear all caches after recalculation
            GrowthAchievementsCalculator::clearAllCache();
            GrowthAchievementsDashboard::clearAllCache();

        } catch (\Exception $e) {
            $results['errors'][] = "General error: " . $e->getMessage();
        }

        return $results;
    }

    /**
     * Bootstrap achievements system - create achievements for existing events
     * Called during plugin activation or first setup
     * (v2.2) WordPress-native
     *
     * @return array Bootstrap results
     */
    public static function bootstrap()
    {
        try {
            // Auto-create achievements for all existing events
            $auto_creation_results = self::autoCreateAchievementsForAllEvents();

            // Process current month to update any newly created achievements
            $monthly_results = self::processMonthlyAchievements();

            return [
                'success' => true,
                'auto_creation' => $auto_creation_results,
                'monthly_processing' => $monthly_results,
                'message' => 'Achievements system bootstrapped successfully'
            ];

        } catch (\Exception $e) {
            fleekdash_log_error("FleekDash: Error bootstrapping achievements system: " . $e->getMessage());

            return [
                'success' => false,
                'error' => $e->getMessage(),
                'message' => 'Failed to bootstrap achievements system'
            ];
        }
    }

    /**
     * Get achievements summary for API responses
     * (v2.2) WordPress-native
     *
     * @return array API summary
     */
    public static function getApiSummary()
    {
        global $wpdb;
        $table = $wpdb->prefix . 'fleekdash_site_growth_achievements';

        return [
            'system_status' => 'active',
            'total_achievements' => (int) $wpdb->get_var("SELECT COUNT(*) FROM {$table} WHERE is_active = 1"),
            'completed_achievements' => (int) $wpdb->get_var("SELECT COUNT(*) FROM {$table} WHERE is_achieved = 1"),
            'categories' => array_keys(self::getCategories()),
            'last_updated' => \current_time('mysql')
        ];
    }

    /**
     * Create achievement for specific event
     * (v2.2) WordPress-native helper method
     *
     * @param string $event_type Event type
     * @param array $event_config Event configuration
     * @return array|false Created achievement or false
     */
    private static function createAchievementForEvent($event_type, $event_config = [])
    {
        global $wpdb;
        $table = $wpdb->prefix . 'fleekdash_site_growth_achievements';

        // Check if achievement already exists
        $config_hash = md5(json_encode($event_config));
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$table}
             WHERE event_type = %s AND event_config_hash = %s",
            $event_type,
            $config_hash
        ));

        if ($existing > 0) {
            return false; // Already exists
        }

        // Calculate initial values
        $historical_record = self::calculateHistoricalRecord($event_type, $event_config);
        $target_value = self::calculateIntelligentTarget($historical_record, $event_type);

        // Create achievement
        $achievement_name = self::generateAchievementName($event_type, $event_config);

        $wpdb->insert(
            $table,
            [
                'achievement_name' => $achievement_name,
                'description' => "Monthly record for {$achievement_name}",
                'achievement_type' => 'event_record',
                'event_type' => $event_type,
                'event_config' => json_encode($event_config),
                'event_config_hash' => $config_hash,
                'target_value' => $target_value,
                'current_record' => $historical_record,
                'is_active' => 1,
                'created_at' => \current_time('mysql')
            ],
            ['%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%s']
        );

        if ($wpdb->insert_id) {
            return $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM {$table} WHERE id = %d",
                $wpdb->insert_id
            ), ARRAY_A);
        }

        return false;
    }

    /**
     * Update achievement progress
     * (v2.2) WordPress-native helper
     *
     * @param int $achievement_id Achievement ID
     * @param int $new_value New value achieved
     * @return bool Whether achievement was newly unlocked
     */
    private static function updateAchievementProgress($achievement_id, $new_value)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'fleekdash_site_growth_achievements';

        $achievement = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$table} WHERE id = %d",
            $achievement_id
        ), ARRAY_A);

        if (!$achievement) {
            return false;
        }

        $was_achieved = $achievement['is_achieved'];
        $is_now_achieved = $new_value >= $achievement['target_value'];
        $newly_achieved = !$was_achieved && $is_now_achieved;

        // Update current record if it's a new record
        $update_data = [];
        $update_format = [];

        if ($new_value > $achievement['current_record']) {
            $update_data['current_record'] = $new_value;
            $update_format[] = '%d';
        }

        if ($is_now_achieved && !$was_achieved) {
            $update_data['is_achieved'] = 1;
            $update_data['achieved_at'] = \current_time('mysql');
            $update_data['times_achieved'] = ($achievement['times_achieved'] ?? 0) + 1;
            $update_format[] = '%d';
            $update_format[] = '%s';
            $update_format[] = '%d';
        }

        if (!empty($update_data)) {
            $wpdb->update(
                $table,
                $update_data,
                ['id' => $achievement_id],
                $update_format,
                ['%d']
            );
        }

        return $newly_achieved;
    }

    /**
     * Calculate historical record for event type
     *
     * @param string $event_type Event type
     * @param array $event_config Event configuration
     * @return int Historical best value
     */
    private static function calculateHistoricalRecord($event_type, $event_config)
    {
        // Look back 12 months and find the best month
        $best_value = 0;

        for ($i = 0; $i < 12; $i++) {
            $month_start = date('Y-m-01 00:00:00', strtotime("-{$i} months"));
            $month_end = date('Y-m-t 23:59:59', strtotime("-{$i} months"));

            $value = GrowthAchievementsCalculator::calculateMonthlyValue(
                $event_type,
                $event_config,
                $month_start,
                $month_end
            );

            if ($value > $best_value) {
                $best_value = $value;
            }
        }

        return $best_value;
    }

    /**
     * Calculate intelligent target based on historical record
     *
     * @param int $current_record Current record
     * @param string $event_type Event type
     * @return int Target value
     */
    private static function calculateIntelligentTarget($current_record, $event_type)
    {
        if ($current_record == 0) {
            return 10; // Default starting target
        }

        // Increase target by 10-20% depending on current level
        $increase_percentage = $current_record < 100 ? 0.20 : 0.10;
        return (int) ceil($current_record * (1 + $increase_percentage));
    }

    /**
     * Generate achievement name from event type and config
     *
     * @param string $event_type Event type
     * @param array $event_config Event configuration
     * @return string Achievement name
     */
    private static function generateAchievementName($event_type, $event_config)
    {
        $names = [
            'new_post' => 'Blog Post Publishing',
            'new_user' => 'User Registrations',
            'new_comment' => 'Community Engagement',
            'new_order' => 'Sales Performance',
            'new_product' => 'Product Catalog Growth',
            'product_review' => 'Product Reviews'
        ];

        $base_name = $names[$event_type] ?? ucwords(str_replace('_', ' ', $event_type));

        // Add config specifics if present
        if (!empty($event_config['post_type'])) {
            $base_name .= " ({$event_config['post_type']})";
        }

        return $base_name;
    }

    /**
     * Get achievement categories
     *
     * @return array Categories
     */
    private static function getCategories()
    {
        return [
            'growth' => 'Growth Milestones',
            'content' => 'Content Creation',
            'engagement' => 'Community Engagement',
            'commerce' => 'E-commerce Success'
        ];
    }
}
