<?php
ini_set('display_errors', 1);

require_once '../../../resources/base_path_include.php';

require_once $base_path_to_learning_resources  . "includes/connect.php";
require_once $base_path_to_learning_resources . 'lib/function.php';
require_once $base_path_to_learning_resources . 'lib/validate_api_signature.php';

//valdation file
require_once $base_path_to_learning_resources . 'lib/validate_function.php';
require_once $base_path_to_learning . 'functions/common_functions.php';
require_once $base_path_to_learning . 'user_management/authenticate.php';
require_once $base_path_to_learning . 'functions/cache_student_academic_function.php';
//dynemic db
require_once $base_path_to_learning_resources . 'includes/specific_db_config.php';
require_once $base_path_to_learning_resources . 'external_requests/finware_curl/groups_ledgers/curl_alter_student_class_section_finware.php';
require_once $base_path_to_learning_resources . 'external_requests/finware_curl/groups_ledgers/curl_function_branch_students.php';

$postdata = json_decode(file_get_contents("php://input"), true);

if (
    !isset($postdata['function_type']) or !checkIfIssetAndNotEmpty($postdata['function_type']) or
    !isset($postdata['api_signature']) or !checkIfIssetAndNotEmpty($postdata['api_signature']) or
    !isset($postdata['jwt_token']) or !checkIfIssetAndNotEmpty($postdata['jwt_token']) 
) {
    errorreturn("All * fields are required.");
}

validateApiSignature($postdata['api_signature']);

$jwttoken = $postdata['jwt_token'];
$jwt_validate = authenticate_jwt($jwttoken);
$userid = $jwt_validate->data->id;
$workspace_id = $jwt_validate->data->workspace_id;
$created_by = $jwt_validate->data->username;
$role = $jwt_validate->data->role;
$institution_id = $jwt_validate->data->institution_id;
$branch_id = $jwt_validate->data->branch_id;

$specific_db_name = validateUserAccess($conn_rjllearning, $userid, $role, $workspace_id, ['principal'], null);
if (!$specific_db_name) {
    errorreturn('Access denied.');
} else {
    $conn_rjllearning_specific = dynamicDbConnection($specific_db_name);
}

require_once $base_path_to_learning . 'user_management/user_versioning.php';

$version = isset($_POST['version']) ? $_POST['version'] : (isset($postdata['version']) ? $postdata['version'] : null);
$updated_time = isset($_POST['updated_time']) ? $_POST['updated_time'] : (isset($postdata['updated_time']) ? $postdata['updated_time'] : null);

$response = user_data_refresh($conn_rjllearning, $conn_rjllearning_specific,$version, $updated_time, $userid, $institution_id);

function studentPromoted($conn_rjllearning, $conn_rjllearning_specific, $institution_id, $branch_id, $promote_students, $password)
{
    // Query to fetch the hashed password from the database
    $sql = "SELECT password, email FROM users WHERE workspace_id = ? AND username = ?";
    $stmt = $conn_rjllearning->prepare($sql);
    $stmt->execute([$GLOBALS['workspace_id'], $GLOBALS['created_by']]);
    $result = $stmt->fetchAll();

    if (count($result) != 1) {
        errorreturn("User not found.");
    }

    $hashed_password_from_db = $result[0]['password'];

    if (!password_verify($password, $hashed_password_from_db)) {
        errorreturn("Incorrect password. Contact admin.");
    }

    $conn_rjllearning_specific->exec("SET TRANSACTION ISOLATION LEVEL READ COMMITTED");
    $conn_rjllearning_specific->beginTransaction();

    try {

        foreach ($promote_students as $student) {
            $fromClassName = $student['from']['class'];
            $fromSectionName = $student['from']['section'];
            $toClassName = $student['to']['class'];

            $classQuery = "SELECT id, classname, class_order FROM class_info WHERE (id = ? OR id = ?) AND branch_id LIKE ?";
            $stmt = $conn_rjllearning_specific->prepare($classQuery);
            $stmt->execute([$fromClassName, $toClassName, "%'" . $branch_id . "'%"]);
            $classResult = $stmt->fetchAll(PDO::FETCH_ASSOC);
            // print_R($classResult);die();
            $classMap = [];
            $classOrderMap = [];

            foreach ($classResult as $row) {
                // print_R($row);die();
                $classMap[$row['id']] = $row['id'];
                $classOrderMap[$row['id']] = $row['class_order'];
            }

            // Validate if both classes exist
            // if (!isset($classMap[$fromClassName]) || !isset($classMap[$toClassName])) {
            //     errorreturn("Class names not found: {$fromClassName} or {$toClassName}.");
            // }

            // Ensure that the class order follows the correct promotion sequence
            if ($classOrderMap[$toClassName] != $classOrderMap[$fromClassName] + 1) {
                errorreturn("Invalid class promotion sequence: {$toClassName} must have class order " . ($classOrderMap[$fromClassName] + 1));
            }

            // Fetch the correct class IDs
            $fromClassId = $classMap[$fromClassName];
            $toClassId = $classMap[$toClassName];

            $sectionQuery = "SELECT id FROM section_info WHERE branch_id LIKE ?";
            $array_params = ["%'" . $branch_id . "'%"];

            if ($fromSectionName ==  'all') {
                $sectionQuery .= '';
            } else if ($fromSectionName !=  null  && $fromSectionName != 'all') {
                $sectionQuery .= " AND id = ? ";
                $array_params[] = $fromSectionName;
            }

            $stmt = $conn_rjllearning_specific->prepare($sectionQuery);
            $stmt->execute($array_params);
            $sectionResult = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$sectionResult) {
                errorreturn("Section not found for this branch.");
            }

            if ($fromSectionName ==  'all') {
                $sectionId = 'all';
            } else if ($fromSectionName !=  null  && $fromSectionName != 'all') {
                $sectionId = $sectionResult['id'];
            }

            // Fetch students for promotion
            $query = "SELECT id, class_id, section_id FROM students WHERE institution_id = ? AND branch_id = ? AND class_id = ?";
            $array_param = [$institution_id, $branch_id, $fromClassId];
            if ($sectionId == 'all') {
                $query .= '';
            } else if ($sectionId !=  null  && $sectionId != 'all') {
                $query .= " AND section_id = ? ";
                $array_param[] = $sectionId;
            }

            $stmt = $conn_rjllearning_specific->prepare($query);
            $stmt->execute($array_param);
            $studentsToUpdate = $stmt->fetchAll(PDO::FETCH_ASSOC);
            if (empty($studentsToUpdate)) {
                errorreturn("No students found for promotion in this class.");
            }

            // Prepare update statement to change the class of students
            $updateQuery = "UPDATE students SET class_id = ? WHERE id = ? AND institution_id = ? AND branch_id = ?";
            $updateStmt = $conn_rjllearning_specific->prepare($updateQuery);

            foreach ($studentsToUpdate as $studentData) {
                // Retrieve branch details
                $branch = getBranchDetails($conn_rjllearning_specific, $branch_id, $institution_id);

                if (!empty($branch)) {
                    // Retrieve class and section details
                    $class_info = getClass($conn_rjllearning_specific, $institution_id, $toClassId);
                    $section_data = getSection($conn_rjllearning_specific, $institution_id, $sectionId);

                    // Reset formatted data for each student
                    $formattedData[] = array(
                            'product_connection_id' => $studentData['id'],
                            'class' => $class_info['class_name'],
                            'section' => $section_data['section_name']
                        );

                    // Create the students data array
                    $students_data = [
                        "workspace_id" => $GLOBALS['workspace_id'],
                        "branch" => $branch,
                        "student_learning" => $formattedData,
                        "created_by" => $GLOBALS['created_by']
                    ];

                    // Call external function to update ledgers
                    curlAlterStudentClassSectionFinware($students_data);
                }
                // Update student class
                $updateStmt->execute([$toClassId, $studentData['id'], $institution_id, $branch_id]);

                // Cache updated student data
                cacheAcademicStudentData(
                    $conn_rjllearning_specific,
                    $institution_id,
                    $branch_id,
                    $toClassId,
                    $sectionId,
                    $studentData['id'],
                    date("Y-m-d")
                );
            }
        }

        $conn_rjllearning_specific->commit();
        successreturn("Students Promoted Successfullty");
    } catch (Exception $e) {
        $conn_rjllearning_specific->rollback();
        errorreturn("Database error: " . $e->getMessage());
    }
}

if ($postdata['function_type']  == "student_promote") {

    $check_academic_confirmation_id = CheckAcademicSession($conn_rjllearning_specific, $institution_id);

    if ($check_academic_confirmation_id != true) {
        errorreturn("Access denied. Academic session not active.");
    }

    $promote_students = $postdata['promote_students'];

    if (!is_array($promote_students) || empty($promote_students)) {
        errorreturn("Students data is required.");
    }

    foreach ($promote_students as $student) {
        if (!is_array($student) || empty($student['from']) || empty($student['to'])) {
            errorreturn("Each student entry must have 'from' and 'to' details.");
        }

        if (!is_array($student['from']) || empty($student['from']['class']) || empty($student['from']['section'])) {
            errorreturn("'from' must contain both 'class' and 'section'.");
        }
    }
    $password = trim($postdata['password']);
    studentPromoted($conn_rjllearning, $conn_rjllearning_specific, $institution_id, $branch_id, $promote_students, $password);
}
