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

require_once '../../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';
require_once $base_path_to_learning_resources . 'lib/validate_function.php';
require_once $base_path_to_learning . 'user_management/authenticate.php';
require_once $base_path_to_learning . 'admin_api/academic_session/functions/validate_faculty.php';
require_once $base_path_to_learning . 'admin_api/academic_session/functions/functions.php';
require_once $base_path_to_learning . 'functions/common_functions.php';
require_once $base_path_to_learning_resources . 'includes/specific_db_config.php';
require_once $base_path_to_learning . "vendor/autoload.php";
require_once $base_path_to_learning_resources . 'lib/bucket_functions/bucket_functions.php';
require_once $base_path_to_learning_resources . 'includes/aws_bucket_config.php';

$postdata = $_POST;

if (
    !isset($postdata['institution_id']) || !checkIfIssetAndNotEmpty($postdata['institution_id']) ||
    !isset($postdata['student_id']) || !checkIfIssetAndNotEmpty($postdata['student_id']) ||
    !isset($postdata['marksheet_id']) || !checkIfIssetAndNotEmpty($postdata['marksheet_id']) ||
    !isset($postdata['api_signature']) || !checkIfIssetAndNotEmpty($postdata['api_signature']) ||
    !isset($postdata['jwt_token']) || !checkIfIssetAndNotEmpty($postdata['jwt_token']) ||
    !isset($postdata['marks']) || !is_array($postdata['marks'])
) {
    errorreturn("All * fields are required.");
}

validateApiSignature($postdata['api_signature']);
$jwt_validate = authenticate_jwt($postdata['jwt_token']);

$userid       = $jwt_validate->data->id;
$workspace_id = $jwt_validate->data->workspace_id;
$username     = $jwt_validate->data->username;
$role         = $jwt_validate->data->role;

$specific_db_name = validateUserAccess(
    $conn_rjllearning,
    $userid,
    $role,
    $workspace_id,
    ["superadmin", "admin", "principal", "teacher"],
    null
);

if (!$specific_db_name) {
    errorreturn('Access denied.');
}

$conn_rjllearning_specific = dynamicDbConnection($specific_db_name);

$institution_id = $postdata['institution_id'];
$student_id     = $postdata['student_id'];
$marksheet_id   = $postdata['marksheet_id'];

/* ================== FETCH MARKSHEET ================== */
$ExecuteSqlMarksheet = $conn_rjllearning_specific->prepare(
    "SELECT * FROM marksheet WHERE id = ?"
);
$ExecuteSqlMarksheet->execute([$marksheet_id]);
$rowmarksheet = $ExecuteSqlMarksheet->fetch(PDO::FETCH_ASSOC);

if (!$rowmarksheet) {
    errorreturn("Marksheet does not exist.");
}

$templateid = $rowmarksheet['template_id'];

/* ================== FETCH STUDENT ================== */
$ExecuteSqlStudent = $conn_rjllearning_specific->prepare(
    "SELECT name, branch_id, class_id, academic_id, section_id
     FROM students WHERE id = ?"
);
$ExecuteSqlStudent->execute([$student_id]);
$rowstudent = $ExecuteSqlStudent->fetch(PDO::FETCH_ASSOC);

if (!$rowstudent) {
    errorreturn("Student does not exist.");
}

$branch      = $rowstudent['branch_id'];
$class       = $rowstudent['class_id'];
$academic_id = $rowstudent['academic_id'];
$section_id  = $rowstudent['section_id'];


/* ================== CHECK LOCK TABLE ================== */

$lock_sql = "SELECT class_id, section_id, student_list
             FROM lock_marksheet_cache
             WHERE institution_id = ?
             AND branch_id = ?
             AND marksheet_id = ?";

$lock_stmt = $conn_rjllearning_specific->prepare($lock_sql);
$lock_stmt->execute([
    $institution_id,
    $branch,
    $marksheet_id
]);

$lock_rows = $lock_stmt->fetchAll(PDO::FETCH_ASSOC);

if (!empty($lock_rows)) {

    foreach ($lock_rows as $lock_row) {

        $student_list = json_decode($lock_row['student_list'], true);

        if (!empty($student_list) && in_array((string)$student_id, $student_list)) {

            # Override class and section from lock table
            $class      = $lock_row['class_id'];
            $section_id = $lock_row['section_id'];

            break;
        }
    }
}
$conn_rjllearning_specific->prepare(
    "DELETE FROM student_marksheet_data
     WHERE student_id = ? AND marksheet_id = ?"
)->execute([$student_id, $marksheet_id]);

function gradeFromSum($sum)
{
    if ($sum >= 91) return 'A1';
    if ($sum >= 81) return 'A2';
    if ($sum >= 71) return 'B1';
    if ($sum >= 61) return 'B2';
    if ($sum >= 51) return 'C1';
    if ($sum >= 41) return 'C2';
    if ($sum >= 33) return 'D';
    if ($sum >= 21) return 'E1';
    return 'E2';
}


function num($v)
{
    if ($v === null) return 0;
    if (is_string($v)) {
        $v = trim($v);
        if ($v === '') return 0;
    }
    return is_numeric($v) ? (float)$v : 0;
}


$marks = array_values($postdata['marks']); // normalize

// normalize
$marks = array_values($marks);

/**
 * STEP-1 (0..35)
 * Every 6 values:
 * [a,b,c,total, sum, grade]
 * sum = a+b+c
 * grade = gradeFromSum(sum)
 */
for ($start = 0; $start <= 30; $start += 6) {

    $a = num($marks[$start] ?? 0);
    $b = num($marks[$start + 1] ?? 0);
    $c = num($marks[$start + 2] ?? 0);
    $d = num($marks[$start + 3] ?? 0);

    $sum = $a + $b + $c + $d;

    // put sum in [4],[10],[16]...
    $marks[$start + 4] = $sum;

    // grade in [5],[11],[17]...
    $marks[$start + 5] = gradeFromSum($sum);
}

/**
 * STEP-2 (36)
 * sum of: 0,1,2,6,7,8,12,13,14,18,19,20,24,25,26,30,31,32
 */
$idx36 = [0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32];
$sum36 = 0;
foreach ($idx36 as $i) {
    $sum36 += num($marks[$i] ?? 0);
}
$marks[36] = $sum36;

/**
 * STEP-3 (37)
 * sum of: 3,9,15,21,27,33
 */
$idx37 = [3, 9, 15, 21, 27, 33];
$sum37 = 0;
foreach ($idx37 as $i) {
    $sum37 += num($marks[$i] ?? 0);
}
$marks[37] = $sum37;

/**
 * STEP-4 (38)
 * sum of: 0,1,2,3,6,7,8,9,12,13,14,15,18,19,20,21,24,25,26,27,30,31,32,33
 */
$idx38 = [0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 18, 19, 20, 21, 24, 25, 26, 27, 30, 31, 32, 33];
$sum38 = 0;
foreach ($idx38 as $i) {
    $sum38 += num($marks[$i] ?? 0);
}
$marks[38] = $sum38;

/**
 * STEP-5 (39)
 * gradeFromSum(array[38])
 */
$marks[39] = gradeFromSum(($marks[38] / 600) * 100);

/**
 * STEP-1B (40..57)
 * same pattern:
 * [a,b,c,total, sum, grade]
 */
for ($start = 40; $start <= 52; $start += 6) {

    $a = num($marks[$start] ?? 0);
    $b = num($marks[$start + 1] ?? 0);
    $c = num($marks[$start + 2] ?? 0);
    $d = num($marks[$start + 3] ?? 0);

    $sum = $a + $b + $c + $d;

    // put sum in [44],[50],[56]
    $marks[$start + 4] = $sum;

    // grade in [45],[51],[57]
    $marks[$start + 5] = gradeFromSum($sum);
}
$marks[58] = round(($marks[38] / 600) * 100);


function getGrade($obtained, $total)
{
    if ($total <= 0) return '';

    $p = ($obtained / $total) * 100;

    if ($p >= 91) return 'A1';
    if ($p >= 81) return 'A2';
    if ($p >= 71) return 'B1';
    if ($p >= 61) return 'B2';
    if ($p >= 51) return 'C1';
    if ($p >= 41) return 'C2';
    if ($p >= 33) return 'D';
    if ($p >= 21) return 'E1';
    return 'E2';
}

/**
 * STEP-A (77..112) : 6 groups (each group = 6 values)
 */
for ($start = 77; $start <= 107; $start += 6) {

    $a = num($marks[$start] ?? 0);
    $b = num($marks[$start + 1] ?? 0);
    $c = num($marks[$start + 2] ?? 0);
    $d = num($marks[$start + 3] ?? 0);

    $sum = $a + $b + $c + $d;

    // sum position
    $marks[$start + 4] = $sum;

    // grade position
    $marks[$start + 5] = gradeFromSum($sum);
}
function safeFloat($v)
{
    return is_numeric($v) ? (float)$v : 0;
}
/**
 * STEP-B totals (113,114,115,116)
 */

// marks[113]
$idx113 = [77, 78, 79, 83, 84, 85, 89, 90, 91, 95, 96, 97, 101, 102, 103, 107, 108, 109];
$sum113 = 0;
foreach ($idx113 as $i) {
    $sum113 += num($marks[$i] ?? 0);
}
$marks[113] = $sum113;

// marks[114]
$idx114 = [80, 86, 92, 98, 104, 110];
$sum114 = 0;
foreach ($idx114 as $i) {
    $sum114 += num($marks[$i] ?? 0);
}
$marks[114] = $sum114;

// marks[115]
$idx115 = [77, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 107, 108, 109, 110];
$sum115 = 0;
foreach ($idx115 as $i) {
    $sum115 += num($marks[$i] ?? 0);
}
$marks[115] = $sum115;

$marks[116] = gradeFromSum(($marks[115] / 600) * 100);
/**
 * STEP-C (117..134) : 3 groups
 * (same pattern like 40..57)
 */
for ($start = 117; $start <= 129; $start += 6) {

    $a = num($marks[$start] ?? 0);
    $b = num($marks[$start + 1] ?? 0);
    $c = num($marks[$start + 2] ?? 0);
    $d = num($marks[$start + 3] ?? 0);

    $sum = $a + $b + $c + $d;

    $marks[$start + 4] = $sum;

    $marks[$start + 5] = gradeFromSum($sum);
}
$marks[135] = round((num($marks[115]) / 600) * 100);

$final_marks = array_combine(
    range(1, count($marks)),
    array_values($marks)
);

$json_data = json_encode($final_marks, JSON_UNESCAPED_UNICODE);

$insert = $conn_rjllearning_specific->prepare("
    INSERT INTO student_marksheet_data (
        institution_id, marksheet_id, student_id, data,
        branch_id, academic_id, class_id, section_id,
        created_by, date_created, time_created, status
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");

$insert->execute([
    $institution_id,
    $marksheet_id,
    $student_id,
    $json_data,
    $branch,
    $academic_id,
    $class,
    $section_id,
    $username,
    date("Y-m-d"),
    date("H:i:s"),
    '1'
]);

$insertId = $conn_rjllearning_specific->lastInsertId();

$analytics = marksheet_analytics_31($json_data);

$conn_rjllearning_specific->prepare("
    UPDATE student_marksheet_data 
    SET analytics = ?
    WHERE id = ?
")->execute([json_encode($analytics), $insertId]);

successreturn("Marksheet saved successfully.");

function calculate_unit_31($data, $subjects, $percentageSubjects, $label = null)
{
    $subjectRankings = [];
    $marksObtained = 0;

    foreach ($subjects as $sub) {

        $total = 0;
        foreach ($sub['sum_of'] as $idx) {
            $total += (float)($data[$idx] ?? 0);
        }

        if (in_array($sub['name'], $percentageSubjects)) {
            $marksObtained += $total;
        }

        $subjectRankings[] = [
            'subject' => $sub['name'],
            'total' => $total,
            'percentage' => round(($total / 20) * 100, 2),
            'grade' => getGrade($total, 20)
        ];
    }

    $totalMax = count($percentageSubjects) * 20;

    usort($subjectRankings, fn($a, $b) => $b['total'] <=> $a['total']);

    return [
        'label' => $label,
        'total_obtained' => $marksObtained,
        'total_max' => $totalMax,
        'percentage' => number_format(($marksObtained / $totalMax) * 100, 2, '.', ''),
        'grade' => getGrade($marksObtained, $totalMax),
        'highest_marks_obtained_subject' => $subjectRankings[0]['subject'] ?? null,
        'lowest_marks_obtained_subject' => end($subjectRankings)['subject'] ?? null,
        'subject_rankings' => $subjectRankings
    ];
}

function calculate_term_31($data, $subjects, $percentageSubjects, $label = null)
{
    $subjectRankings = [];
    $marksObtained = 0;

    foreach ($subjects as $sub) {
        $total = (float)($data[$sub['sum']] ?? 0);

        if (in_array($sub['name'], $percentageSubjects)) {
            $marksObtained += $total;
        }

        $subjectRankings[] = [
            'subject' => $sub['name'],
            'total' => $total,
            'percentage' => round(($total / 100) * 100, 2),
            'grade' => $sub['grade'] !== null ? ($data[$sub['grade']] ?? '') : ''
        ];
    }

    $totalMax = count($percentageSubjects) * 100;

    $percentage = number_format(
        ($marksObtained / $totalMax) * 100,
        2,
        '.',
        ''
    );

    usort($subjectRankings, fn($a, $b) => $b['total'] <=> $a['total']);

    return [
        'label' => $label,
        'total_obtained' => $marksObtained,
        'total_max' => $totalMax,
        'percentage' => $percentage,
        'grade' => getGrade($marksObtained, $totalMax),
        'highest_marks_obtained_subject' => $subjectRankings[0]['subject'] ?? null,
        'lowest_marks_obtained_subject' => end($subjectRankings)['subject'] ?? null,
        'subject_rankings' => $subjectRankings
    ];
}


function marksheet_analytics_31($json)
{
    $data = json_decode($json, true);
    if (!is_array($data)) {
        return ['error' => 'Invalid marks data'];
    }

    // force integer keys
    $data = array_combine(
        array_map('intval', array_keys($data)),
        array_values($data)
    );

    $p1_subjects = [
        ['name' => 'English',  'sum_of' => [78,79,80]],
        ['name' => 'Hindi',    'sum_of' => [84,85,86]],
        ['name' => 'Punjabi',  'sum_of' => [90,91,92]],
        ['name' => 'Maths',    'sum_of' => [96,97,98]],
        ['name' => 'Science',  'sum_of' => [102,103,104]],
        ['name' => 'S.St',     'sum_of' => [108,109,110]],
        ['name' => 'Drawing',  'sum_of' => [118,119,120]],
        ['name' => 'Computer', 'sum_of' => [124,125,126]],
        ['name' => 'Physical Edu', 'sum_of' => [130,131,132]]
    ];

    $term1Subjects = [
        ['name' => 'English', 'sum' => 82, 'grade' => 83],
        ['name' => 'Hindi', 'sum' => 88, 'grade' => 89],
        ['name' => 'Punjabi', 'sum' => 94, 'grade' => 95],
        ['name' => 'Maths', 'sum' => 100, 'grade' => 101],
        ['name' => 'Science', 'sum' => 106, 'grade' => 107],
        ['name' => 'S.St', 'sum' => 112, 'grade' => 113],
        ['name' => 'Drawing', 'sum' => 122, 'grade' => 123],
        ['name' => 'Computer', 'sum' => 128, 'grade' => 129],
        ['name' => 'Physical Edu', 'sum' => 134, 'grade' => 135],
    ];

    $p2_subjects = [
        ['name' => 'English',  'sum_of' => [1,2,3]],
        ['name' => 'Hindi',    'sum_of' => [7,8,9]],
        ['name' => 'Punjabi',  'sum_of' => [13,14,15]],
        ['name' => 'Maths',    'sum_of' => [19,20,21]],
        ['name' => 'Science',  'sum_of' => [25,26,27]],
        ['name' => 'S.St',     'sum_of' => [31,32,33]],
        ['name' => 'Drawing',  'sum_of' => [41,42,43]],
        ['name' => 'Computer', 'sum_of' => [47,48,49]],
        ['name' => 'Physical Edu', 'sum_of' => [53,54,55]]
    ];

    $term2Subjects = [
        ['name' => 'English', 'sum' => 5, 'grade' => 6],
        ['name' => 'Hindi', 'sum' => 11, 'grade' => 12],
        ['name' => 'Punjabi', 'sum' => 17, 'grade' => 18],
        ['name' => 'Maths', 'sum' => 23, 'grade' => 24],
        ['name' => 'Science', 'sum' => 29, 'grade' => 30],
        ['name' => 'S.St', 'sum' => 35, 'grade' => 36],
        ['name' => 'Drawing', 'sum' => 45, 'grade' => 46],
        ['name' => 'Computer', 'sum' => 51, 'grade' => 52],
        ['name' => 'Physical Edu', 'sum' => 57, 'grade' => 58],
    ];

    $percentageSubjects = ['English', 'Hindi', 'Punjabi', 'Maths', 'Science', 'S.St'];
    
    $Unit1 = calculate_unit_31($data, $p1_subjects, $percentageSubjects, 'Unit 1');
    $term1 = calculate_term_31($data, $term1Subjects, $percentageSubjects, 'Term 1');
    $Unit2 = calculate_unit_31($data, $p2_subjects, $percentageSubjects, 'Unit 2');
    $term2 = calculate_term_31($data, $term2Subjects, $percentageSubjects, 'Final');

    return [
        'p1' => $Unit1,
        'p2' => $term1,
        'p3' => $Unit2,
        'final' => $term2
    ];
}
