<?php
require_once '../../config/database.php';
require_once '../../includes/auth.php';

header('Content-Type: application/json');

// Check authentication
if (!isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Unauthorized access']);
    exit();
}

try {
    // Get current session and recent exam data for predictions
    $stmt = $pdo->query("SELECT DISTINCT session FROM results ORDER BY session DESC LIMIT 1");
    $current_session = $stmt->fetchColumn();
    
    if (!$current_session) {
        throw new Exception("No session data found for predictions");
    }

    // Get students who have recent results
    $students_sql = "
        SELECT DISTINCT s.id, s.student_id, s.first_name, s.last_name, s.class_id
        FROM students s
        JOIN results r ON s.id = r.student_id
        WHERE s.status = 'active'
        ORDER BY s.id
        LIMIT 100
    ";
    
    $stmt = $pdo->query($students_sql);
    $students = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $predictions_generated = 0;
    
    foreach ($students as $student) {
        // Get student's recent performance history
        $history_sql = "
            SELECT 
                r.subject_id,
                r.exam_type,
                r.marks_obtained,
                r.grade,
                r.session,
                sub.name as subject_name
            FROM results r
            JOIN subjects sub ON r.subject_id = sub.id
            WHERE r.student_id = ? 
            AND r.session <= ?
            ORDER BY r.session DESC, r.exam_type DESC
            LIMIT 10
        ";
        
        $stmt = $pdo->prepare($history_sql);
        $stmt->execute([$student['id'], $current_session]);
        $performance_history = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        if (empty($performance_history)) {
            continue;
        }

        // Get unique subjects for this student
        $subjects = array_unique(array_column($performance_history, 'subject_id'));
        
        foreach ($subjects as $subject_id) {
            // Filter history for this specific subject
            $subject_history = array_filter($performance_history, function($item) use ($subject_id) {
                return $item['subject_id'] == $subject_id;
            });
            
            if (count($subject_history) < 2) {
                continue; // Need at least 2 data points for prediction
            }

            // Simple AI prediction algorithm
            $predicted_marks = predictStudentPerformance($subject_history);
            $predicted_grade = calculateGrade($predicted_marks);
            $confidence_score = calculateConfidence($subject_history);
            
            // Check if prediction already exists
            $check_sql = "
                SELECT id FROM ai_performance_predictions 
                WHERE student_id = ? AND subject_id = ? AND session = ? AND exam_type = 'final'
            ";
            $stmt = $pdo->prepare($check_sql);
            $stmt->execute([$student['id'], $subject_id, $current_session]);
            
            if ($stmt->fetch()) {
                // Update existing prediction
                $update_sql = "
                    UPDATE ai_performance_predictions 
                    SET predicted_grade = ?, predicted_marks = ?, confidence_score = ?, analysis_date = CURDATE()
                    WHERE student_id = ? AND subject_id = ? AND session = ? AND exam_type = 'final'
                ";
                $stmt = $pdo->prepare($update_sql);
                $stmt->execute([
                    $predicted_grade, 
                    $predicted_marks, 
                    $confidence_score,
                    $student['id'], 
                    $subject_id, 
                    $current_session
                ]);
            } else {
                // Insert new prediction
                $insert_sql = "
                    INSERT INTO ai_performance_predictions 
                    (student_id, subject_id, exam_type, session, predicted_grade, predicted_marks, confidence_score, analysis_date)
                    VALUES (?, ?, 'final', ?, ?, ?, ?, CURDATE())
                ";
                $stmt = $pdo->prepare($insert_sql);
                $stmt->execute([
                    $student['id'], 
                    $subject_id, 
                    $current_session,
                    $predicted_grade, 
                    $predicted_marks, 
                    $confidence_score
                ]);
            }
            
            $predictions_generated++;
        }
    }

    // Generate learning patterns
    generateLearningPatterns();

    echo json_encode([
        'success' => true,
        'message' => "Generated {$predictions_generated} AI predictions successfully",
        'predictions_count' => $predictions_generated
    ]);

} catch (Exception $e) {
    error_log("AI Prediction Error: " . $e->getMessage());
    echo json_encode([
        'success' => false,
        'message' => 'Error generating predictions: ' . $e->getMessage()
    ]);
}

/**
 * Simple AI prediction algorithm based on historical performance
 */
function predictStudentPerformance($history) {
    if (empty($history)) {
        return 50; // Default average
    }
    
    $marks = array_column($history, 'marks_obtained');
    $recent_marks = array_slice($marks, 0, 3); // Last 3 performances
    
    // Calculate weighted average (more weight to recent performances)
    if (count($recent_marks) >= 3) {
        $prediction = ($recent_marks[0] * 0.5) + ($recent_marks[1] * 0.3) + ($recent_marks[2] * 0.2);
    } elseif (count($recent_marks) == 2) {
        $prediction = ($recent_marks[0] * 0.6) + ($recent_marks[1] * 0.4);
    } else {
        $prediction = $recent_marks[0];
    }
    
    // Add some variance to make it more realistic
    $variance = (mt_rand(-100, 100) / 100) * 5; // ±5 marks variation
    $prediction += $variance;
    
    // Ensure prediction is within reasonable bounds
    return max(0, min(100, round($prediction, 1)));
}

/**
 * Calculate grade based on marks
 */
function calculateGrade($marks) {
    if ($marks >= 80) return 'A+';
    if ($marks >= 70) return 'A';
    if ($marks >= 60) return 'A-';
    if ($marks >= 50) return 'B';
    if ($marks >= 40) return 'C';
    if ($marks >= 33) return 'D';
    return 'F';
}

/**
 * Calculate confidence score based on data quality and consistency
 */
function calculateConfidence($history) {
    $count = count($history);
    
    if ($count < 2) return 0.3; // Low confidence with little data
    if ($count < 4) return 0.6; // Medium confidence
    
    // Calculate consistency (standard deviation)
    $marks = array_column($history, 'marks_obtained');
    $mean = array_sum($marks) / count($marks);
    $variance = array_sum(array_map(function($mark) use ($mean) {
        return pow($mark - $mean, 2);
    }, $marks)) / count($marks);
    $std_dev = sqrt($variance);
    
    // Lower standard deviation = higher confidence
    $consistency_factor = max(0.1, 1 - ($std_dev / 50));
    
    return min(0.95, 0.7 + ($consistency_factor * 0.25)); // Cap at 95%
}

/**
 * Generate learning patterns for students
 */
function generateLearningPatterns() {
    global $pdo;
    
    // Get students with sufficient performance history
    $pattern_sql = "
        SELECT 
            s.id as student_id,
            r.subject_id,
            GROUP_CONCAT(r.marks_obtained ORDER BY r.session, r.exam_type) as marks_history
        FROM students s
        JOIN results r ON s.id = r.student_id
        WHERE s.status = 'active'
        GROUP BY s.id, r.subject_id
        HAVING COUNT(r.id) >= 3
    ";
    
    $stmt = $pdo->query($pattern_sql);
    $student_patterns = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    foreach ($student_patterns as $pattern) {
        $marks = explode(',', $pattern['marks_history']);
        $marks = array_map('floatval', $marks);
        
        if (count($marks) < 3) continue;
        
        // Calculate trend slope
        $slope = calculateTrendSlope($marks);
        $consistency = calculateConsistencyScore($marks);
        $pattern_type = determinePatternType($slope, $consistency);
        
        // Check if pattern exists
        $check_sql = "
            SELECT id FROM ai_learning_patterns 
            WHERE student_id = ? AND subject_id = ?
        ";
        $stmt = $pdo->prepare($check_sql);
        $stmt->execute([$pattern['student_id'], $pattern['subject_id']]);
        
        if ($stmt->fetch()) {
            // Update existing pattern
            $update_sql = "
                UPDATE ai_learning_patterns 
                SET pattern_type = ?, trend_slope = ?, consistency_score = ?, last_updated = CURDATE()
                WHERE student_id = ? AND subject_id = ?
            ";
            $stmt = $pdo->prepare($update_sql);
            $stmt->execute([
                $pattern_type, 
                $slope, 
                $consistency,
                $pattern['student_id'], 
                $pattern['subject_id']
            ]);
        } else {
            // Insert new pattern
            $insert_sql = "
                INSERT INTO ai_learning_patterns 
                (student_id, subject_id, pattern_type, trend_slope, consistency_score, last_updated)
                VALUES (?, ?, ?, ?, ?, CURDATE())
            ";
            $stmt = $pdo->prepare($insert_sql);
            $stmt->execute([
                $pattern['student_id'], 
                $pattern['subject_id'],
                $pattern_type, 
                $slope, 
                $consistency
            ]);
        }
    }
}

/**
 * Calculate trend slope using linear regression
 */
function calculateTrendSlope($marks) {
    $n = count($marks);
    if ($n < 2) return 0;
    
    $sum_x = $sum_y = $sum_xy = $sum_xx = 0;
    
    for ($i = 0; $i < $n; $i++) {
        $x = $i + 1;
        $y = $marks[$i];
        $sum_x += $x;
        $sum_y += $y;
        $sum_xy += $x * $y;
        $sum_xx += $x * $x;
    }
    
    $denominator = $n * $sum_xx - $sum_x * $sum_x;
    if ($denominator == 0) return 0;
    
    return ($n * $sum_xy - $sum_x * $sum_y) / $denominator;
}

/**
 * Calculate consistency score (lower standard deviation = higher consistency)
 */
function calculateConsistencyScore($marks) {
    $mean = array_sum($marks) / count($marks);
    $variance = array_sum(array_map(function($mark) use ($mean) {
        return pow($mark - $mean, 2);
    }, $marks)) / count($marks);
    $std_dev = sqrt($variance);
    
    // Convert to consistency score (0-1)
    return max(0, min(1, 1 - ($std_dev / 30))); // Assume 30 is max reasonable std dev
}

/**
 * Determine pattern type based on trend and consistency
 */
function determinePatternType($slope, $consistency) {
    if (abs($slope) < 2 && $consistency > 0.7) return 'stable';
    if ($slope > 2 && $consistency > 0.5) return 'improvement';
    if ($slope < -2 && $consistency > 0.5) return 'decline';
    return 'volatile';
}
?>