<?php
/**
 * Growth Achievements Service
 *
 * Manages automatic achievements based on Growth Score records
 * This service automatically creates achievements when users break records
 */

namespace FleekDash\Services;

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

use FleekDash\Models\GrowthAchievement;
use FleekDash\Models\SiteGrowthScore;

class GrowthAchievementsService
{
    /**
     * Check and create achievements based on current Growth Score
     * This is called whenever the Growth Score is updated
     */
    public function checkAndCreateAchievements()
    {
        try {
            $current_scores = $this->getCurrentScores();
            $achievements_created = [];

            // Check daily record
            if ($daily_achievement = $this->checkDailyRecord($current_scores['daily'])) {
                $achievements_created[] = $daily_achievement;
            }

            // Check weekly record
            if ($weekly_achievement = $this->checkWeeklyRecord($current_scores['weekly'])) {
                $achievements_created[] = $weekly_achievement;
            }

            // Check monthly record
            if ($monthly_achievement = $this->checkMonthlyRecord($current_scores['monthly'])) {
                $achievements_created[] = $monthly_achievement;
            }

            // Check all-time record
            if ($alltime_achievement = $this->checkAllTimeRecord($current_scores['all_time'])) {
                $achievements_created[] = $alltime_achievement;
            }

            // Check milestone achievements
            $milestone_achievements = $this->checkMilestoneAchievements($current_scores['all_time']);
            $achievements_created = array_merge($achievements_created, $milestone_achievements);

            return [
                'success' => true,
                'achievements_created' => count($achievements_created),
                'achievements' => $achievements_created
            ];

        } catch (\Exception $e) {
            fleekdash_log_error('FleekDash: Error checking achievements: ' . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Get current Growth Scores for all periods
     */
    private function getCurrentScores()
    {
        global $wpdb;
        $events_table = $wpdb->prefix . 'fleekdash_site_growth_events';

        // Get total points from all active events (this is the Growth Score)
        $total_points = $wpdb->get_var(
            "SELECT SUM(total_occurrences * weight_points)
             FROM {$events_table}
             WHERE is_active = 1"
        );

        $total_points = intval($total_points ?: 0);

        // For now, we'll use the same total for all periods
        // In the future, we can implement period-specific calculations
        return [
            'daily' => $this->getDailyScore(),
            'weekly' => $this->getWeeklyScore(),
            'monthly' => $this->getMonthlyScore(),
            'all_time' => $total_points
        ];
    }

    /**
     * Get daily score (last 24 hours)
     */
    private function getDailyScore()
    {
        global $wpdb;
        $events_table = $wpdb->prefix . 'fleekdash_site_growth_events';

        // For now, return a percentage of total score
        // This can be enhanced to track actual daily activity
        $total_score = $wpdb->get_var(
            "SELECT SUM(total_occurrences * weight_points)
             FROM {$events_table}
             WHERE is_active = 1"
        );

        return intval($total_score * 0.1); // 10% of total as daily approximation
    }

    /**
     * Get weekly score (last 7 days)
     */
    private function getWeeklyScore()
    {
        global $wpdb;
        $events_table = $wpdb->prefix . 'fleekdash_site_growth_events';

        $total_score = $wpdb->get_var(
            "SELECT SUM(total_occurrences * weight_points)
             FROM {$events_table}
             WHERE is_active = 1"
        );

        return intval($total_score * 0.3); // 30% of total as weekly approximation
    }

    /**
     * Get monthly score (last 30 days)
     */
    private function getMonthlyScore()
    {
        global $wpdb;
        $events_table = $wpdb->prefix . 'fleekdash_site_growth_events';

        $total_score = $wpdb->get_var(
            "SELECT SUM(total_occurrences * weight_points)
             FROM {$events_table}
             WHERE is_active = 1"
        );

        return intval($total_score * 0.7); // 70% of total as monthly approximation
    }

    /**
     * Check if daily record was broken
     */
    private function checkDailyRecord($current_daily_score)
    {
        $previous_record = GrowthAchievement::getLatestRecord(GrowthAchievement::PERIOD_DAILY) ?: 0;

        if ($current_daily_score > $previous_record) {
            // Create achievement
            $achievement_data = [
                'achievement_type' => GrowthAchievement::TYPE_DAILY_RECORD,
                'achievement_name' => 'Daily Growth Record!',
                'description' => "New daily record of {$current_daily_score} points! Previous record was {$previous_record} points.",
                'period_type' => GrowthAchievement::PERIOD_DAILY,
                'record_value' => $current_daily_score,
                'previous_record' => $previous_record,
                'points_breakdown' => json_encode($this->getPointsBreakdown())
            ];

            $achievement_id = GrowthAchievement::createAchievement($achievement_data);

            if ($achievement_id) {
                return array_merge($achievement_data, ['id' => $achievement_id]);
            }
        }

        return null;
    }

    /**
     * Check if weekly record was broken
     */
    private function checkWeeklyRecord($current_weekly_score)
    {
        $previous_record = GrowthAchievement::getLatestRecord(GrowthAchievement::PERIOD_WEEKLY) ?: 0;

        if ($current_weekly_score > $previous_record) {
            $achievement_data = [
                'achievement_type' => GrowthAchievement::TYPE_WEEKLY_RECORD,
                'achievement_name' => 'Weekly Growth Record!',
                'description' => "New weekly record of {$current_weekly_score} points! Previous record was {$previous_record} points.",
                'period_type' => GrowthAchievement::PERIOD_WEEKLY,
                'record_value' => $current_weekly_score,
                'previous_record' => $previous_record,
                'points_breakdown' => json_encode($this->getPointsBreakdown())
            ];

            $achievement_id = GrowthAchievement::createAchievement($achievement_data);

            if ($achievement_id) {
                return array_merge($achievement_data, ['id' => $achievement_id]);
            }
        }

        return null;
    }

    /**
     * Check if monthly record was broken
     */
    private function checkMonthlyRecord($current_monthly_score)
    {
        $previous_record = GrowthAchievement::getLatestRecord(GrowthAchievement::PERIOD_MONTHLY) ?: 0;

        if ($current_monthly_score > $previous_record) {
            $achievement_data = [
                'achievement_type' => GrowthAchievement::TYPE_MONTHLY_RECORD,
                'achievement_name' => 'Monthly Growth Record!',
                'description' => "New monthly record of {$current_monthly_score} points! Previous record was {$previous_record} points.",
                'period_type' => GrowthAchievement::PERIOD_MONTHLY,
                'record_value' => $current_monthly_score,
                'previous_record' => $previous_record,
                'points_breakdown' => json_encode($this->getPointsBreakdown())
            ];

            $achievement_id = GrowthAchievement::createAchievement($achievement_data);

            if ($achievement_id) {
                return array_merge($achievement_data, ['id' => $achievement_id]);
            }
        }

        return null;
    }

    /**
     * Check if all-time record was broken
     */
    private function checkAllTimeRecord($current_total_score)
    {
        $previous_record = GrowthAchievement::getLatestRecord(GrowthAchievement::PERIOD_ALL_TIME) ?: 0;

        if ($current_total_score > $previous_record) {
            $achievement_data = [
                'achievement_type' => GrowthAchievement::TYPE_ALL_TIME_RECORD,
                'achievement_name' => 'All-Time Growth Record!',
                'description' => "New all-time record of {$current_total_score} points! Previous record was {$previous_record} points.",
                'period_type' => GrowthAchievement::PERIOD_ALL_TIME,
                'record_value' => $current_total_score,
                'previous_record' => $previous_record,
                'points_breakdown' => json_encode($this->getPointsBreakdown())
            ];

            $achievement_id = GrowthAchievement::createAchievement($achievement_data);

            if ($achievement_id) {
                return array_merge($achievement_data, ['id' => $achievement_id]);
            }
        }

        return null;
    }

    /**
     * Check milestone achievements (1K, 5K, 10K, 25K, 50K, 100K points)
     */
    private function checkMilestoneAchievements($total_score)
    {
        $milestones = [1000, 5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000];
        $achievements = [];

        foreach ($milestones as $milestone) {
            if ($total_score >= $milestone) {
                // Check if this milestone achievement already exists
                if (!GrowthAchievement::achievementExists(
                    GrowthAchievement::TYPE_POINTS_MILESTONE,
                    GrowthAchievement::PERIOD_ALL_TIME,
                    $milestone
                )) {
                    $achievement_data = [
                        'achievement_type' => GrowthAchievement::TYPE_POINTS_MILESTONE,
                        'achievement_name' => $this->getMilestoneName($milestone),
                        'description' => "Reached {$milestone} total growth points!",
                        'period_type' => GrowthAchievement::PERIOD_ALL_TIME,
                        'record_value' => $milestone,
                        'previous_record' => 0,
                        'points_breakdown' => json_encode($this->getPointsBreakdown()),
                        'is_milestone' => true,
                        'milestone_level' => $milestone
                    ];

                    $achievement_id = GrowthAchievement::createAchievement($achievement_data);

                    if ($achievement_id) {
                        $achievements[] = array_merge($achievement_data, ['id' => $achievement_id]);
                    }
                }
            }
        }

        return $achievements;
    }

    /**
     * Get milestone name based on points
     */
    private function getMilestoneName($points)
    {
        $names = [
            1000 => 'Growth Starter',
            5000 => 'Growth Achiever',
            10000 => 'Growth Master',
            25000 => 'Growth Expert',
            50000 => 'Growth Champion',
            100000 => 'Growth Legend',
            250000 => 'Growth Hero',
            500000 => 'Growth Titan',
            1000000 => 'Growth God'
        ];

        return $names[$points] ?? "Milestone: {$points} Points";
    }

    /**
     * Get points breakdown by event type
     */
    private function getPointsBreakdown()
    {
        global $wpdb;
        $events_table = $wpdb->prefix . 'fleekdash_site_growth_events';

        $results = $wpdb->get_results(
            "SELECT event_type, SUM(total_occurrences * weight_points) as total_points
             FROM {$events_table}
             WHERE is_active = 1
             GROUP BY event_type",
            \ARRAY_A
        );

        $breakdown = [];
        foreach ($results as $result) {
            $breakdown[$result['event_type']] = intval($result['total_points']);
        }

        return $breakdown;
    }

    /**
     * Get all achievements for display
     */
    public function getAllAchievements($limit = null, $filter_type = null)
    {
        if ($filter_type) {
            return GrowthAchievement::getByType($filter_type, $limit);
        }

        return GrowthAchievement::getAllAchievements($limit);
    }

    /**
     * Get achievement statistics
     */
    public function getAchievementStats()
    {
        global $wpdb;
        $table = $wpdb->prefix . 'fleekdash_growth_achievements';

        $total_achievements = $wpdb->get_var("SELECT COUNT(*) FROM {$table}");
        $milestones = $wpdb->get_var("SELECT COUNT(*) FROM {$table} WHERE is_milestone = 1");
        $records = $wpdb->get_var("SELECT COUNT(*) FROM {$table} WHERE is_milestone = 0");
        $latest_achievement = $wpdb->get_row(
            "SELECT * FROM {$table} ORDER BY achieved_at DESC LIMIT 1",
            \ARRAY_A
        );

        return [
            'total_achievements' => intval($total_achievements),
            'milestones' => intval($milestones),
            'records' => intval($records),
            'latest_achievement' => $latest_achievement
        ];
    }
}
