<?php
// api/update_enrollment_status.php
// This API endpoint handles updating the status of a course enrollment
// (e.g., approving or rejecting an enrollment request).
// It now also generates monthly payment records when an enrollment is approved.

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

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

// Ensure user is logged in and is either an admin or instructor
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true || ($_SESSION['user_role'] !== 'admin' && $_SESSION['user_role'] !== 'instructor')) {
    echo json_encode(['success' => false, 'message' => 'Authentication required or not authorized.']);
    exit();
}

require_once '../config/database.php'; // Path to database connection

$input = json_decode(file_get_contents('php://input'), true);
$enrollment_id = filter_var($input['enrollment_id'] ?? null, FILTER_VALIDATE_INT);
$new_status = trim($input['new_status'] ?? '');

$response = ['success' => false, 'message' => ''];

$current_user_id = $_SESSION['user_id'];
$current_user_role = $_SESSION['user_role'];

// --- 1. Basic Input Validation ---
if (!$enrollment_id || !in_array($new_status, ['enrolled', 'rejected'])) {
    $response['message'] = "Invalid enrollment ID or status provided.";
    echo json_encode($response);
    exit();
}

try {
    // --- 2. Fetch current enrollment details for validation and authorization ---
    $stmt = $pdo->prepare("
        SELECT ce.id, ce.status, ce.enrollment_date, ce.student_id,
               c.id AS course_id, c.instructor_id, c.fees, c.duration
        FROM course_enrollments ce
        JOIN courses c ON ce.course_id = c.id
        WHERE ce.id = ? LIMIT 1
    ");
    $stmt->execute([$enrollment_id]);
    $enrollment = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$enrollment) {
        $response['message'] = "Enrollment record not found.";
        echo json_encode($response);
        exit();
    }

    // Authorization check: Instructor can only manage enrollments for their own courses.
    if ($current_user_role === 'instructor' && $enrollment['instructor_id'] != $current_user_id) {
        $response['message'] = "You are not authorized to manage this enrollment.";
        echo json_encode($response);
        exit();
    }

    // Prevent updating if already in final status
    if ($enrollment['status'] === 'enrolled' || $enrollment['status'] === 'rejected') {
        $response['message'] = "Enrollment is already in a final state (" . htmlspecialchars($enrollment['status']) . "). Cannot update.";
        echo json_encode($response);
        exit();
    }
    // Prevent approving if payment not uploaded (unless admin overrides, not built here)
    if ($new_status === 'enrolled' && $enrollment['status'] === 'pending') {
        $response['message'] = "Enrollment must have payment details uploaded before it can be approved.";
        echo json_encode($response);
        exit();
    }

    // Start a transaction for atomicity
    $pdo->beginTransaction();

    // --- 3. Update Enrollment Status ---
    $stmt = $pdo->prepare("UPDATE course_enrollments SET status = ? WHERE id = ?");
    if (!$stmt->execute([$new_status, $enrollment_id])) {
        throw new Exception("Failed to update enrollment status.");
    }

    // --- 4. Generate Monthly Payment Records if Status is 'enrolled' ---
    if ($new_status === 'enrolled') {
        // Check if monthly payments already exist for this enrollment to prevent duplicates
        $stmt_check_monthly = $pdo->prepare("SELECT COUNT(*) FROM monthly_payments WHERE enrollment_id = ?");
        $stmt_check_monthly->execute([$enrollment_id]);
        if ($stmt_check_monthly->fetchColumn() == 0) { // Only generate if no existing payments
            $course_fees = $enrollment['fees'];
            $course_duration_text = $enrollment['duration'];
            $enrollment_date = new DateTime($enrollment['enrollment_date']);

            $num_installments = 0;
            // Basic parsing of duration string (e.g., "3 months", "1 year")
            if (preg_match('/(\d+)\s*months?/i', $course_duration_text, $matches)) {
                $num_installments = (int)$matches[1];
            } elseif (preg_match('/(\d+)\s*year/i', $course_duration_text, $matches)) {
                $num_installments = (int)$matches[1] * 12;
            }

            if ($num_installments > 0) {
                $monthly_amount = round($course_fees / $num_installments, 2);
                $remaining_fees = $course_fees;

                // Prepare insert statement for monthly payments
                $stmt_insert_monthly = $pdo->prepare("
                    INSERT INTO monthly_payments (enrollment_id, month_due_date, amount_due, status)
                    VALUES (?, ?, ?, 'due')
                ");

                for ($i = 0; $i < $num_installments; $i++) {
                    // Calculate the due date for the first day of each month
                    $month_due_date_obj = (clone $enrollment_date)->modify('+' . $i . ' month');
                    // Set day to 1st to represent the month's due date
                    $month_due_date_obj->setDate($month_due_date_obj->format('Y'), $month_due_date_obj->format('m'), 1);
                    $month_due_date = $month_due_date_obj->format('Y-m-d');

                    // Adjust the last installment for any rounding differences
                    $current_installment_amount = $monthly_amount;
                    if ($i === $num_installments - 1) {
                        // Ensure the last installment covers any remaining cents
                        $current_installment_amount = $remaining_fees;
                    }
                    $remaining_fees -= $current_installment_amount;


                    if (!$stmt_insert_monthly->execute([$enrollment_id, $month_due_date, $current_installment_amount])) {
                        throw new Exception("Failed to generate monthly payment for installment " . ($i + 1) . ".");
                    }
                }
            } else {
                // Handle cases where duration isn't clear for monthly payments (e.g., one-time payment course)
                // For now, if duration is not interpretable for monthly, we assume it's a one-time payment.
                // You might choose to add a flag in 'courses' table for 'is_monthly_payment'
                error_log("Enrollment ID {$enrollment_id}: Course duration '{$course_duration_text}' not suitable for monthly payments. No installments generated.");
            }
        } else {
            error_log("Enrollment ID {$enrollment_id}: Monthly payments already exist. Skipping generation.");
        }
    }

    $pdo->commit(); // Commit the transaction
    $response['success'] = true;
    $response['message'] = "Enrollment status updated to " . ucwords($new_status) . " successfully! " . ($new_status === 'enrolled' ? "Monthly payments generated." : "");

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack(); // Rollback if something went wrong during transaction
    }
    $response['message'] = "Server error: " . $e->getMessage();
    error_log("Update Enrollment Status API Error: " . $e->getMessage());
}

echo json_encode($response);
exit();
