<?php
/**
 * 🚨 TÄIELIK MOTIVATION_FUNCTIONS.PHP - PARANDATUD VERSIOON V3 + AASTA FILTER
 * Kombineeritud vana stabiilne struktuur uue, võistluspõhise loogikaga + aasta filter tugi.
 * Kõik funktsioonide nimed on säilitatud, lisatud aasta parameeter (tagasiühilduvus tagatud).
 */

// =================================================================================
// 🚀 UUED ABIFUNKTSIOONID (UUEST KOODIST) + AASTA FILTER
// Need on vajalikud, et uus loogika töötaks.
// =================================================================================

/**
 * Kontrollib, kas üks konkreetne võistlus on kasutaja poolt edukalt lõpetatud.
 * Eduka lõpetamise reegel: vähemalt 50% startidest on edukalt lõpetatud (finished=1).
 * 
 * @param int $user_id Kasutaja ID
 * @param int $competition_id Võistluse ID  
 * @param int|null $year Aasta filter (vaikimisi jooksev aasta)
 */
function isCompetitionSuccessfullyCompleted($user_id, $competition_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT
                COUNT(*) as total_starts,
                SUM(CASE WHEN finished = 1 THEN 1 ELSE 0 END) as successful_starts
            FROM results r
            JOIN competitions c ON r.competitionId = c.id
            WHERE r.userId = ? AND r.competitionId = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt->execute([$user_id, $competition_id, $year]);
        $result = $stmt->fetch();

        if ($result['total_starts'] == 0) {
            return false;
        }

        $success_rate = ($result['successful_starts'] / $result['total_starts']) * 100;
        return $success_rate >= 50;

    } catch (Exception $e) {
        error_log("isCompetitionSuccessfullyCompleted error: " . $e->getMessage());
        return false;
    }
}

/**
 * Leiab kõik kasutaja edukalt lõpetatud võistluste ID-d ja kuupäevad.
 * 
 * @param int $user_id Kasutaja ID
 * @param int|null $year Aasta filter (vaikimisi jooksev aasta)
 * @param string|null $month Kuu filter (YYYY-MM formaadis)
 */
function getSuccessfullyCompletedCompetitions($user_id, $year = null, $month = null) {
    global $pdo;
    
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        $successful_competitions = [];
        
        $where_clause = "r.userId = ? AND strftime('%Y', c.date) = ?";
        $params = [$user_id, $year];
        
        if ($month) {
            $where_clause .= " AND strftime('%Y-%m', c.date) = ?";
            $params[] = $month;
        }
        
        $stmt = $pdo->prepare("
            SELECT DISTINCT r.competitionId, c.date as competition_date
            FROM results r
            JOIN competitions c ON r.competitionId = c.id
            WHERE $where_clause
            ORDER BY c.date ASC
        ");
        $stmt->execute($params);
        $competitions = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($competitions as $comp) {
            if (isCompetitionSuccessfullyCompleted($user_id, $comp['competitionId'], $year)) {
                $successful_competitions[] = $comp;
            }
        }
        
        return $successful_competitions;
        
    } catch (Exception $e) {
        error_log('getSuccessfullyCompletedCompetitions error: ' . $e->getMessage());
        return [];
    }
}


// =================================================================================
// ⚙️ MODIFITSEERITUD FUNKTSIOONID (VANA KOODI UUENDATUD VERSIOONID) + AASTA FILTER
// =================================================================================

/**
 * ✅ PARANDATUD - Loendab edukalt lõpetatud VÕISTLUSI, mitte starte + aasta filter.
 */
function checkFinishedCount($user_id, $year = null) {
    if (!$year) {
        $year = date('Y');
    }
    $successful_competitions = getSuccessfullyCompletedCompetitions($user_id, $year);
    return count($successful_competitions);
}

/**
 * ✅ PARANDATUD - Kontrollib, kas kasutajal on vähemalt üks edukalt lõpetatud VÕISTLUS + aasta filter.
 */
function checkHasFinishedResults($user_id, $year = null) {
    if (!$year) {
        $year = date('Y');
    }
    // Kasutame checkFinishedCount funktsiooni, mis juba kasutab uut loogikat.
    return checkFinishedCount($user_id, $year) > 0 ? 1 : 0;
}

/**
 * ✅ PARANDATUD - Arvutab pikima edukalt lõpetatud VÕISTLUSTE seeria + aasta filter.
 */
function calculateLongestFinishedStreak($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        // Leia kõik võistlused, millel kasutaja osales, ajalises järjekorras
        $stmt = $pdo->prepare("
            SELECT DISTINCT r.competitionId, c.date as competition_date
            FROM results r
            JOIN competitions c ON r.competitionId = c.id
            WHERE r.userId = ? AND strftime('%Y', c.date) = ?
            ORDER BY c.date ASC
        ");
        $stmt->execute([$user_id, $year]);
        $all_competitions = $stmt->fetchAll(PDO::FETCH_ASSOC);

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

        $max_streak = 0;
        $current_streak = 0;

        foreach ($all_competitions as $comp) {
            if (isCompetitionSuccessfullyCompleted($user_id, $comp['competitionId'], $year)) {
                $current_streak++;
                $max_streak = max($max_streak, $current_streak);
            } else {
                $current_streak = 0; // Seeria katkeb
            }
        }
        
        return $max_streak;

    } catch (Exception $e) {
        error_log('calculateLongestFinishedStreak (new logic) error: ' . $e->getMessage());
        return 0;
    }
}

/**
 * ✅ PARANDATUD - Kontrollib perfektse lõpetamise määra VÕISTLUSTE tasemel + aasta filter.
 */
function checkPerfectFinishRate($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        // Leia kõik unikaalsed võistlused, kus kasutaja osales
        $stmt = $pdo->prepare("
            SELECT COUNT(DISTINCT r.competitionId) as total_competitions
            FROM results r
            JOIN competitions c ON r.competitionId = c.id
            WHERE r.userId = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt->execute([$user_id, $year]);
        $total_competitions = $stmt->fetch()['total_competitions'];
        
        if ($total_competitions == 0) {
            return 0; // Või 100, sõltuvalt loogikast, aga 0 on turvalisem
        }
        
        // Leia edukalt lõpetatud võistluste arv
        $successful_competitions_count = count(getSuccessfullyCompletedCompetitions($user_id, $year));
        
        $finish_rate = ($successful_competitions_count / $total_competitions) * 100;
        return round($finish_rate);
        
    } catch (Exception $e) {
        error_log('checkPerfectFinishRate (new logic) error: ' . $e->getMessage());
        return 0;
    }
}


// =================================================================================
//  UNTOUCHED FUNCTIONS (ORIGINAL WORKING CODE) + AASTA FILTER LISATUD
// Kõik funktsioonid allpool on originaalfailist ja lisatud on aasta filter tugi.
// =================================================================================

function checkBestPlacement($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT MIN(r.placement) as best_placement 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND r.placement IS NOT NULL AND strftime('%Y', c.date) = ?
        ");
        $stmt->execute([$user_id, $year]);
        $best = $stmt->fetch()['best_placement'];
        
        return $best ? (int)$best : 999;
    } catch (Exception $e) {
        error_log('Best placement error: ' . $e->getMessage());
        return 999;
    }
}

function checkBestPlacementCount($user_id, $max_placement, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*) as count 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND r.placement <= ? AND r.placement IS NOT NULL 
            AND strftime('%Y', c.date) = ?
        ");
        $stmt->execute([$user_id, $max_placement, $year]);
        return $stmt->fetch()['count'];
    } catch (Exception $e) {
        error_log("Best placement count error for $max_placement: " . $e->getMessage());
        return 0;
    }
}

function checkEarlyUser($user_id) {
    global $pdo;
    try {
        $stmt = $pdo->prepare("
            SELECT 
                (SELECT COUNT(*) FROM users WHERE createdAt < u.createdAt) + 1 as position
            FROM users u 
            WHERE u.id = ?
        ");
        $stmt->execute([$user_id]);
        $result = $stmt->fetch();
        
        if (!$result) {
            return 999;
        }
        
        return (int)$result['position'];
    } catch (Exception $e) {
        error_log('Early user check error: ' . $e->getMessage());
        return 999;
    }
}

function checkTriedDiscipline($user_id, $discipline, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(DISTINCT r.competitionId) as count 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND r.discipline = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt->execute([$user_id, $discipline, $year]);
        return $stmt->fetch()['count'];
    } catch (Exception $e) {
        error_log("Tried discipline check error for $discipline: " . $e->getMessage());
        return 0;
    }
}

function checkTop5InAllDisciplines($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    $disciplines = ['koolisoit', 'takistussoit', 'kestvusratsutamine'];
    
    try {
        foreach ($disciplines as $discipline) {
            $stmt = $pdo->prepare("
                SELECT MIN(r.placement) as best_placement 
                FROM results r 
                JOIN competitions c ON r.competitionId = c.id 
                WHERE r.userId = ? AND r.discipline = ? AND r.placement IS NOT NULL 
                AND strftime('%Y', c.date) = ?
            ");
            $stmt->execute([$user_id, $discipline, $year]);
            $best = $stmt->fetch()['best_placement'];
            
            if (!$best || $best > 5) {
                return 0;
            }
        }
        return 3;
    } catch (Exception $e) {
        error_log('TOP 5 all disciplines error: ' . $e->getMessage());
        return 0;
    }
}

function checkMonthlyImprovement($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        // Praeguse aasta jooksev kuu
        $current_month = date('Y-m');
        
        // Kui vaatame eelmist aastat, võtame viimase kuu
        if ($year != date('Y')) {
            $current_month = $year . '-12';
        }
        
        $stmt_current = $pdo->prepare("
            SELECT AVG(r.points) as avg_points 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ?
        ");
        $stmt_current->execute([$user_id, $current_month]);
        $current_avg = $stmt_current->fetch()['avg_points'];
        
        // Eelmine kuu
        $prev_month = date('Y-m', strtotime($current_month . '-01 -1 month'));
        
        $stmt_prev = $pdo->prepare("
            SELECT AVG(r.points) as avg_points 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ?
        ");
        $stmt_prev->execute([$user_id, $prev_month]);
        $previous_avg = $stmt_prev->fetch()['avg_points'];
        
        if ($previous_avg > 0 && $current_avg) {
            $improvement = (($current_avg - $previous_avg) / $previous_avg) * 100;
            return max(0, round($improvement));
        }
        return 0;
    } catch (Exception $e) {
        error_log('Monthly improvement error: ' . $e->getMessage());
        return 0;
    }
}

function checkTotalTrainings($user_id, $year = null) {
    global $pdo;
    try {
        if ($year && $year != date('Y')) {
            // Konkreetne aasta
            $stmt = $pdo->prepare("
                SELECT COUNT(*) as count 
                FROM training_log 
                WHERE userId = ? AND strftime('%Y', date) = ?
            ");
            $stmt->execute([$user_id, $year]);
        } else {
            // Kõik ajad (tagasiühilduvus)
            $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM training_log WHERE userId = ?");
            $stmt->execute([$user_id]);
        }
        return $stmt->fetch()['count'];
    } catch (Exception $e) {
        error_log('Total trainings error: ' . $e->getMessage());
        return 0;
    }
}

function checkAverageMood($user_id, $year = null) {
    global $pdo;
    try {
        if ($year && $year != date('Y')) {
            // Konkreetne aasta
            $stmt = $pdo->prepare("
                SELECT AVG(mood) as avg_mood 
                FROM training_log 
                WHERE userId = ? AND mood IS NOT NULL AND strftime('%Y', date) = ?
            ");
            $stmt->execute([$user_id, $year]);
        } else {
            // Kõik ajad (tagasiühilduvus)
            $stmt = $pdo->prepare("SELECT AVG(mood) as avg_mood FROM training_log WHERE userId = ? AND mood IS NOT NULL");
            $stmt->execute([$user_id]);
        }
        $result = $stmt->fetch()['avg_mood'];
        return $result ? round($result, 1) : 0;
    } catch (Exception $e) {
        error_log('Average mood error: ' . $e->getMessage());
        return 0;
    }
}

function countUniqueCompetitionsForUser($user_id, $year = null) {
    global $pdo;
    
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(DISTINCT r.competitionId) as competitions_count
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt->execute([$user_id, $year]);
        return $stmt->fetch()['competitions_count'];
    } catch (Exception $e) {
        error_log('Count unique competitions error: ' . $e->getMessage());
        return 0;
    }
}

function countUniqueCompetitionsForUserInMonth($user_id, $month = null) {
    global $pdo;
    
    if (!$month) {
        $month = date('Y-m');
    }
    
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(DISTINCT r.competitionId) as competitions_count
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ?
        ");
        $stmt->execute([$user_id, $month]);
        return $stmt->fetch()['competitions_count'];
    } catch (Exception $e) {
        error_log('Count unique competitions in month error: ' . $e->getMessage());
        return 0;
    }
}

/**
 * ✅ PARANDATUD - AASTA FILTER LISATUD
 */
function checkAchievementProgress($user_id, $achievement_key, $achievement, $year = null) {
    global $pdo, $ACHIEVEMENTS;
    if (!$year) {
        $year = date('Y');
    }
    
    if (!isset($achievement['check_function'])) {
        return 0;
    }
    
    try {
        switch ($achievement['check_function']) {
            case 'hasResults':
                return countUniqueCompetitionsForUser($user_id, $year);
                
            case 'hasFinishedResults':
                return checkHasFinishedResults($user_id, $year); // Uses new logic
                
            case 'maxPointsReached':
                $stmt = $pdo->prepare("
                    SELECT MAX(r.points) as max_points 
                    FROM results r 
                    JOIN competitions c ON r.competitionId = c.id 
                    WHERE r.userId = ? AND strftime('%Y', c.date) = ?
                ");
                $stmt->execute([$user_id, $year]);
                $max = $stmt->fetch()['max_points'];
                return $max ? (float)$max : 0;
                
            case 'bestPlacement':
                $best_placement = checkBestPlacement($user_id, $year);
                $target_placement = $achievement['target'];
                return ($best_placement <= $target_placement && $best_placement > 0) ? $target_placement : 0;
                
            case 'bestPlacementCount':
                $placement_limit = $achievement['placement_limit'] ?? $achievement['target'];
                return checkBestPlacementCount($user_id, $placement_limit, $year);
                
            case 'longestStreak':
                return calculateLongestFinishedStreak($user_id, $year); // Uses new logic
                
            case 'finishedCount':
                return checkFinishedCount($user_id, $year); // Uses new logic
                
            case 'disciplinesCount':
                $stmt = $pdo->prepare("
                    SELECT COUNT(DISTINCT r.discipline) as count 
                    FROM results r 
                    JOIN competitions c ON r.competitionId = c.id 
                    WHERE r.userId = ? AND strftime('%Y', c.date) = ?
                ");
                $stmt->execute([$user_id, $year]);
                return $stmt->fetch()['count'];
                
            case 'triedDiscipline':
                $discipline = $achievement['discipline'] ?? 'takistussoit';
                return checkTriedDiscipline($user_id, $discipline, $year);
                
            case 'top5InAllDisciplines':
                return checkTop5InAllDisciplines($user_id, $year);
                
            case 'seasonStarts':
                return countUniqueCompetitionsForUser($user_id, $year);
                
            case 'monthlyStarts':
                return countUniqueCompetitionsForUserInMonth($user_id);
                
            case 'totalTrainings':
                return checkTotalTrainings($user_id, $year);
                
            case 'monthlyTrainings':
                $current_month = $year == date('Y') ? date('Y-m') : $year . '-12';
                $stmt = $pdo->prepare("
                    SELECT COUNT(*) as count 
                    FROM training_log 
                    WHERE userId = ? AND strftime('%Y-%m', date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];
                
            case 'averageMood':
                return checkAverageMood($user_id, $year);
                
            case 'perfectFinishRate':
                return checkPerfectFinishRate($user_id, $year); // Uses new logic
                
            case 'monthlyImprovement':
                return checkMonthlyImprovement($user_id, $year);
                
            case 'earlyUser':
                $position = checkEarlyUser($user_id);
                return $position <= $achievement['target'] ? $achievement['target'] : 0;
                
            default:
                error_log("Unknown achievement check function: {$achievement['check_function']}");
                return 0;
        }
    } catch (Exception $e) {
        error_log("Achievement progress check error for {$achievement_key}: " . $e->getMessage());
        return 0;
    }
}

/**
 * ✅ PARANDATUD - AASTA FILTER LISATUD
 */
function calculateUserAchievements($user_id, $achievements_array, $year = null) {
    global $pdo;
    
    if (!$year) {
        $year = date('Y');
    }

    $results = ['newly_unlocked' => [], 'all_unlocked' => [], 'progress' => []];

    try {
        // Lae kasutaja saavutused valitud aastani (inclusiv)
        $stmt = $pdo->prepare("
            SELECT achievement_key 
            FROM user_achievements 
            WHERE userId = ? AND strftime('%Y', unlocked_at) <= ?
        ");
        $stmt->execute([$user_id, $year]);
        $unlocked_keys = array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'achievement_key');
        $results['all_unlocked'] = $unlocked_keys;

        if (!is_array($achievements_array)) {
            error_log('Achievement calculation error: $achievements_array is not a valid array.');
            return $results;
        }

        foreach ($achievements_array as $key => $achievement) {
            $is_unlocked = in_array($key, $unlocked_keys);
            
            if (!is_array($achievement) || !isset($achievement['target'])) {
                continue; 
            }

            // Arvuta progress valitud aasta andmete põhjal
            $current_progress = $is_unlocked ? $achievement['target'] : checkAchievementProgress($user_id, $key, $achievement, $year);

            // Uute saavutuste avamine ainult jooksval aastal
            if (!$is_unlocked && $current_progress >= $achievement['target'] && $year == date('Y')) {
                unlockAchievement($user_id, $key);
                $results['newly_unlocked'][] = $key;
                $results['all_unlocked'][] = $key;
                $is_unlocked = true;
            }

            $target = $achievement['target'] ?? 0;
            $percentage = ($target > 0) ? min(100, ($current_progress / $target) * 100) : 0;

            $results['progress'][$key] = [
                'current' => $current_progress,
                'target' => $target,
                'percentage' => $percentage,
                'unlocked' => $is_unlocked
            ];
        }
    } catch (Throwable $t) {
        error_log('Achievement calculation error: ' . $t->getMessage());
    }

    return $results;
}

function unlockAchievement($user_id, $achievement_key) {
    global $pdo, $ACHIEVEMENTS;
    
    try {
        $achievement = $ACHIEVEMENTS[$achievement_key] ?? null;
        if (!$achievement) {
            error_log("Achievement $achievement_key not found");
            return false;
        }
        
        $points_reward = $achievement['points_reward'] ?? 0;
        
        $stmt = $pdo->prepare("
            INSERT OR IGNORE INTO user_achievements (userId, achievement_key, unlocked_at, points_awarded) 
            VALUES (?, ?, CURRENT_TIMESTAMP, ?)
        ");
        $stmt->execute([$user_id, $achievement_key, $points_reward]);
        
        $inserted = $stmt->rowCount() > 0;
        
        if ($inserted) {
            error_log("✅ Achievement $achievement_key unlocked for user $user_id (+$points_reward points)");
            
            if (function_exists('logActivity')) {
                logActivity($user_id, 'achievement_unlocked', "Achievement unlocked: {$achievement_key}");
            }
        }
        
        return true;
    } catch (Exception $e) {
        error_log('Achievement unlock error: ' . $e->getMessage());
        return false;
    }
}

// ... ja nii edasi kõikide ülejäänud funktsioonidega, mis olid originaalfailis ...
// Jätan alles kõik ülejäänud funktsioonid, nagu `ensureMonthlyChallenges`, `generatePersonalChallenges`, `calculateChallengeProgress` jne.
// `calculateChallengeProgress` vajab samuti uuendamist.

function ensureMonthlyChallenges($user_id) {
    global $pdo, $CHALLENGE_TEMPLATES;
    
    $current_month = date('Y-m');
    $start_date = date('Y-m-01');
    $end_date = date('Y-m-t');
    
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*) as count 
            FROM user_challenges 
            WHERE userId = ? AND strftime('%Y-%m', start_date) = ?
        ");
        $stmt->execute([$user_id, $current_month]);
        $existing = $stmt->fetch()['count'];
        
        if ($existing == 0) {
            $challenge_keys = array_keys($CHALLENGE_TEMPLATES);
            $selected_count = min(5, count($challenge_keys));
            $selected_challenges = array_rand(array_flip($challenge_keys), $selected_count);
            
            if (!is_array($selected_challenges)) {
                $selected_challenges = [$selected_challenges];
            }
            
            foreach ($selected_challenges as $challenge_key) {
                $template = $CHALLENGE_TEMPLATES[$challenge_key];
                
                $stmt_insert = $pdo->prepare("
                    INSERT INTO user_challenges 
                    (userId, challenge_key, start_date, end_date, target_value, challenge_type) 
                    VALUES (?, ?, ?, ?, ?, 'monthly')
                ");
                $stmt_insert->execute([
                    $user_id, 
                    $challenge_key, 
                    $start_date, 
                    $end_date, 
                    $template['target']
                ]);
            }
            
            error_log("✅ Created monthly challenges for user $user_id");
        }
        
        return true;
    } catch (Exception $e) {
        error_log('Ensure monthly challenges error: ' . $e->getMessage());
        return false;
    }
}

function generatePersonalChallenges($user_id) {
    global $pdo, $CHALLENGE_TEMPLATES;
    
    ensureMonthlyChallenges($user_id);
    
    $challenges = [];
    $current_month = date('Y-m');
    
    try {
        $stmt = $pdo->prepare("
            SELECT challenge_key, target_value, current_progress, completed
            FROM user_challenges 
            WHERE userId = ? AND strftime('%Y-%m', start_date) = ?
        ");
        $stmt->execute([$user_id, $current_month]);
        $existing = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($existing as $challenge) {
            $progress = calculateChallengeProgress($user_id, $challenge['challenge_key']);
            $target = $challenge['target_value'] ?? 0;
            $completed = ($target > 0 && $progress >= $target) ? 1 : 0;
            
            $stmt_update = $pdo->prepare("
                UPDATE user_challenges 
                SET current_progress = ?, completed = ? 
                WHERE userId = ? AND challenge_key = ? AND strftime('%Y-%m', start_date) = ?
            ");
            $stmt_update->execute([$progress, $completed, $user_id, $challenge['challenge_key'], $current_month]);
            
            $challenges[] = [
                'key' => $challenge['challenge_key'],
                'current_progress' => $progress,
                'target_value' => $target,
                'completed' => $completed,
                'percentage' => min(100, ($target > 0 ? ($progress / $target) * 100 : 0))
            ];
        }
    } catch (Exception $e) {
        error_log('Challenge generation error: ' . $e->getMessage());
    }
    
    return $challenges;
}


/**
 * ✅ PARANDATUD - Arvutab väljakutse progressi (kasutab uut loogikat)
 */
function calculateChallengeProgress($user_id, $challenge_key) {
    global $pdo, $CHALLENGE_TEMPLATES;
    
    if (!isset($CHALLENGE_TEMPLATES[$challenge_key])) return 0;
    
    $template = $CHALLENGE_TEMPLATES[$challenge_key];
    if (!isset($template['check_function'])) return 0;

    $current_month = date('Y-m');
    
    try {
        switch ($template['check_function']) {
            case 'monthlyStarts':
                return countUniqueCompetitionsForUserInMonth($user_id, $current_month);
                
            case 'monthlyFinishedCount':
                // ✅ PARANDATUD: Edukalt lõpetatud võistlused kuus
                $successful_competitions = getSuccessfullyCompletedCompetitions($user_id, date('Y'), $current_month);
                return count($successful_competitions);
                
            case 'monthlyFinishRate':
                // ✅ PARANDATUD: Võistluste eduka lõpetamise määr
                $total_competitions = countUniqueCompetitionsForUserInMonth($user_id, $current_month);
                if ($total_competitions == 0) return 0;
                
                $successful_competitions = getSuccessfullyCompletedCompetitions($user_id, date('Y'), $current_month);
                $successful_count = count($successful_competitions);
                
                return round(($successful_count / $total_competitions) * 100);
                
            case 'monthlyTotalPoints':
                $stmt = $pdo->prepare("
                    SELECT COALESCE(SUM(r.points), 0) as total_points 
                    FROM results r 
                    JOIN competitions c ON r.competitionId = c.id 
                    WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['total_points'];
                
            case 'monthlyDisciplinesCount':
                $stmt = $pdo->prepare("
                    SELECT COUNT(DISTINCT r.discipline) as count 
                    FROM results r 
                    JOIN competitions c ON r.competitionId = c.id 
                    WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];
                
            case 'monthlyTrainings':
                $stmt = $pdo->prepare("
                    SELECT COUNT(*) as count 
                    FROM training_log 
                    WHERE userId = ? AND strftime('%Y-%m', date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];
                
            case 'monthlyAverageMood':
                $stmt = $pdo->prepare("
                    SELECT AVG(mood) as avg_mood 
                    FROM training_log 
                    WHERE userId = ? AND strftime('%Y-%m', date) = ? AND mood IS NOT NULL
                ");
                $stmt->execute([$user_id, $current_month]);
                $result = $stmt->fetch()['avg_mood'];
                return $result ? round($result, 1) : 0;
                
            case 'monthlyHighMoodTrainings':
                $stmt = $pdo->prepare("
                    SELECT COUNT(*) as count 
                    FROM training_log 
                    WHERE userId = ? AND strftime('%Y-%m', date) = ? 
                    AND mood >= 4.0
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];
                
            case 'improvementPercentage':
                return checkMonthlyImprovement($user_id);
                
            // =============================================================
            // 🚀 UUED LISATUD FUNKTSIOONID (5 tk)
            // =============================================================

            // Väljakutse: Sotsiaalne ratsutaja
            case 'monthlyDifferentLocations':
                $stmt = $pdo->prepare("
                    SELECT COUNT(DISTINCT c.location) as count
                    FROM results r
                    JOIN competitions c ON r.competitionId = c.id
                    WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];

            // Väljakutse: Varajane lind
            case 'monthlyEarlyParticipation':
                $stmt = $pdo->prepare("
                    SELECT COUNT(r.id) as count
                    FROM results r
                    JOIN competitions c ON r.competitionId = c.id
                    WHERE r.userId = ? AND strftime('%Y-%m', c.date) = ? AND CAST(strftime('%d', c.date) AS INTEGER) <= 15
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];

            // Väljakutse: Väike perfektsionist
            case 'monthlyPerfectFinishWithMinimum':
                // See loogika nõuab kahte kontrolli:
                // 1. Kas on vähemalt 2 võistlust?
                $total_competitions = countUniqueCompetitionsForUserInMonth($user_id, $current_month);
                if ($total_competitions < 2) {
                    return 0; // Ei vasta miinimumi nõudele
                }
                
                // 2. Kui on, siis arvuta lõpetamise määr
                $successful_competitions = getSuccessfullyCompletedCompetitions($user_id, date('Y'), $current_month);
                $successful_count = count($successful_competitions);
                
                return round(($successful_count / $total_competitions) * 100);

            // Väljakutse: Mitmekülgne sportlane
            case 'monthlyTrainingTypesCount':
                // MÄRKUS: See eeldab, et 'training_log' tabelis on veerg nimega 'type'
                $stmt = $pdo->prepare("
                    SELECT COUNT(DISTINCT type) as count
                    FROM training_log
                    WHERE userId = ? AND strftime('%Y-%m', date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                return $stmt->fetch()['count'];

            // Väljakutse: Järjekindluse kuningas
            case 'monthlyConsecutiveWeeksTraining':
                // See loogika on keerukam ja tehakse PHP-s, mitte puhtas SQL-is
                $stmt = $pdo->prepare("
                    SELECT DISTINCT date FROM training_log 
                    WHERE userId = ? AND strftime('%Y-%m', date) = ?
                ");
                $stmt->execute([$user_id, $current_month]);
                $dates = $stmt->fetchAll(PDO::FETCH_COLUMN);

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

                $weeks_with_training = [];
                foreach ($dates as $date) {
                    $week_number = date('W', strtotime($date)); // 'W' annab ISO-8601 nädala numbri
                    $weeks_with_training[$week_number] = true;
                }

                return count($weeks_with_training);
                
            default:
                return 0;
        }
    } catch (Exception $e) {
        error_log("Challenge progress error for {$challenge_key}: " . $e->getMessage());
        return 0;
    }
}

/**
 * ✅ PARANDATUD - AASTA FILTER LISATUD
 */
function getProgressionData($user_id, $months = 6, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        // Kui vaatame jooksvat aastat, kasutame tavalist loogikat
        if ($year == date('Y')) {
            $stmt = $pdo->prepare("
                SELECT 
                    strftime('%Y-%m', c.date) as month, 
                    AVG(r.points) as avg_points, 
                    COUNT(DISTINCT r.competitionId) as competitions_count, 
                    MAX(r.points) as max_points 
                FROM results r 
                JOIN competitions c ON r.competitionId = c.id 
                WHERE r.userId = ? AND c.date >= date('now', '-{$months} months') 
                GROUP BY strftime('%Y-%m', c.date) 
                ORDER BY month ASC
            ");
            $stmt->execute([$user_id]);
        } else {
            // Konkreetse aasta andmed
            $stmt = $pdo->prepare("
                SELECT 
                    strftime('%Y-%m', c.date) as month, 
                    AVG(r.points) as avg_points, 
                    COUNT(DISTINCT r.competitionId) as competitions_count, 
                    MAX(r.points) as max_points 
                FROM results r 
                JOIN competitions c ON r.competitionId = c.id 
                WHERE r.userId = ? AND strftime('%Y', c.date) = ?
                GROUP BY strftime('%Y-%m', c.date) 
                ORDER BY month ASC
            ");
            $stmt->execute([$user_id, $year]);
        }
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (Exception $e) {
        error_log('Progression data error: ' . $e->getMessage());
        return [];
    }
}

/**
 * ✅ PARANDATUD - AASTA FILTER LISATUD
 */
function getPersonalStats($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    $stats = [];
    
    try {
        // Kogudistants (kestvusratsutamise tulemused + hinnanguline 5km teistele)
        $stmt1 = $pdo->prepare("
            SELECT SUM(CASE WHEN r.discipline = 'kestvusratsutamine' THEN r.distance ELSE 5 END) as total_distance 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt1->execute([$user_id, $year]);
        $stats['total_distance'] = $stmt1->fetch()['total_distance'] ?: 0;
        
        // Kogupunktid võrreldes teistega
        $stmt2_sub = $pdo->prepare("
            SELECT SUM(r2.points) 
            FROM results r2 
            JOIN competitions c2 ON r2.competitionId = c2.id 
            WHERE r2.userId = ? AND strftime('%Y', c2.date) = ?
        ");
        $stmt2_sub->execute([$user_id, $year]);
        $user_total = $stmt2_sub->fetchColumn() ?: 0;

        $stmt2 = $pdo->prepare("
            SELECT COUNT(*) + 1 as position 
            FROM (
                SELECT SUM(r.points) as total 
                FROM results r 
                JOIN competitions c ON r.competitionId = c.id 
                WHERE r.userId != ? AND strftime('%Y', c.date) = ? 
                GROUP BY r.userId 
                HAVING total > ?
            )
        ");
        $stmt2->execute([$user_id, $year, $user_total]);
        $stats['overall_position'] = $stmt2->fetch()['position'];
        
        // Aastate võrdlus
        $last_year = $year - 1;
        $stmt3 = $pdo->prepare("
            SELECT AVG(r.points) as avg_points 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt3->execute([$user_id, $last_year]);
        $last_year_avg = $stmt3->fetch()['avg_points'];
        $stmt3->execute([$user_id, $year]);
        $current_year_avg = $stmt3->fetch()['avg_points'];
        
        if ($last_year_avg > 0 && $current_year_avg) {
            $stats['year_improvement'] = round((($current_year_avg - $last_year_avg) / $last_year_avg) * 100);
        } else {
            $stats['year_improvement'] = 0;
        }
        
        // ✅ PARANDATUD: Lõpetamise määr kasutab nüüd uut, võistluspõhist funktsiooni
        $stats['finish_rate'] = checkPerfectFinishRate($user_id, $year);
        
        $stats['competitions_count'] = countUniqueCompetitionsForUser($user_id, $year);
        
    } catch (Exception $e) {
        error_log('Personal stats error: ' . $e->getMessage());
    }
    return $stats;
}


function getNextLevelTargets($user_id, $year = null) {
    global $pdo;
    $targets = [];
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        // TOP 3 koolisõidus eesmärk
        $stmt1 = $pdo->prepare("
            SELECT MIN(r.points) as min_top3_points 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.discipline = 'koolisoit' AND r.placement <= 3 AND strftime('%Y', c.date) = ?
        ");
        $stmt1->execute([$year]);
        $min_top3 = $stmt1->fetch()['min_top3_points'];
        
        $stmt2 = $pdo->prepare("
            SELECT MAX(r.points) as best_points 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND r.discipline = 'koolisoit' AND strftime('%Y', c.date) = ?
        ");
        $stmt2->execute([$user_id, $year]);
        $user_best = $stmt2->fetch()['best_points'];
        
        if ($min_top3 > 0 && $user_best) {
            $targets['top3_dressage'] = [
                'name' => 'TOP 3 koolisõidus',
                'current' => $user_best,
                'target' => $min_top3,
                'remaining' => max(0, $min_top3 - $user_best),
                'percentage' => min(100, ($user_best / $min_top3) * 100)
            ];
        }
        
        $current_competitions = countUniqueCompetitionsForUser($user_id, $year);
        
        $targets['season_hero'] = [
            'name' => 'Hooaja kangelane',
            'current' => $current_competitions,
            'target' => 15,
            'remaining' => max(0, 15 - $current_competitions),
            'percentage' => min(100, ($current_competitions / 15) * 100)
        ];
    } catch (Exception $e) {
        error_log('Next level targets error: ' . $e->getMessage());
    }
    return $targets;
}

/**
 * ✅ PARANDATUD - AASTA FILTER LISATUD
 */
function debugUserCompetitions($user_id, $year = null) {
    global $pdo;
    if (!$year) {
        $year = date('Y');
    }
    
    try {
        // Loendame tulemusi
        $stmt1 = $pdo->prepare("
            SELECT COUNT(*) as results_count 
            FROM results r 
            JOIN competitions c ON r.competitionId = c.id 
            WHERE r.userId = ? AND strftime('%Y', c.date) = ?
        ");
        $stmt1->execute([$user_id, $year]);
        $results_count = $stmt1->fetch()['results_count'];
        
        // Loendame unikaalseid võistlusi
        $competitions_count = countUniqueCompetitionsForUser($user_id, $year);
        
        // Loendame edukalt lõpetatud võistlusi (uus loogika)
        $successful_competitions = getSuccessfullyCompletedCompetitions($user_id, $year);
        $successful_count = count($successful_competitions);
        
        error_log("🔧 DEBUG User $user_id ($year): $results_count tulemust, $competitions_count unikaalset võistlust, $successful_count edukalt lõpetatud.");
        
        return [
            'results_count' => $results_count,
            'competitions_count' => $competitions_count,
            'successful_competitions_count' => $successful_count
        ];
        
    } catch (Exception $e) {
        error_log('Debug competitions error: ' . $e->getMessage());
        return null;
    }
}
?>