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

/* ================== INCLUDES ================== */
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;





/* ================== VALIDATION ================== */
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.");
}

/* ================== SECURITY ================== */
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;

/* ================== DB ACCESS ================== */
$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);

/* ================== BASIC DATA ================== */
$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;
        }
    }
}

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

/* ================== GRADE FUNCTION ================== */
function gradeFromSum($sum)
{
    if ($sum === '' || $sum === null) {
        return '';
    }

    $sum = round((float)$sum); // ✅ ROUND OFF FIRST

    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 getGradenew($marks) {
    if ($marks === '' || $marks === null) {
        return '';
    }

    $marks = (float)$marks;

    // Convert marks out of 200 to percentage (ROUND OFF)
    $percentage = round(($marks / 200) * 100);

    if ($percentage >= 91 && $percentage <= 100) return 'A1';
    if ($percentage >= 81 && $percentage <= 90)  return 'A2';
    if ($percentage >= 71 && $percentage <= 80)  return 'B1';
    if ($percentage >= 61 && $percentage <= 70)  return 'B2';
    if ($percentage >= 51 && $percentage <= 60)  return 'C1';
    if ($percentage >= 41 && $percentage <= 50)  return 'C2';
    if ($percentage >= 33 && $percentage <= 40)  return 'D';
    if ($percentage >= 21 && $percentage <= 32)  return 'E1';
    if ($percentage >= 0  && $percentage <= 20)  return 'E2';

    return '';
}
/* ================== CORE CALCULATION ================== */
function m($v){
    if ($v === null || $v === '') return 0;
    if (strtoupper(trim($v)) === 'LT') return 0;
    return (float)$v;
}
$marks = array_values($postdata['marks']); // normalize index

$marks[111] = m($marks[108] ?? 0) + m($marks[109] ?? 0) + m($marks[110] ?? 0);
$marks[115] = m($marks[112] ?? 0) + m($marks[113] ?? 0) + m($marks[114] ?? 0);
$marks[119] = m($marks[116] ?? 0) + m($marks[117] ?? 0) + m($marks[118] ?? 0);
$marks[123] = m($marks[120] ?? 0) + m($marks[121] ?? 0) + m($marks[122] ?? 0);
$marks[127] = m($marks[124] ?? 0) + m($marks[125] ?? 0) + m($marks[126] ?? 0);
$marks[131] = m($marks[128] ?? 0) + m($marks[129] ?? 0) + m($marks[130] ?? 0);
$marks[135] = m($marks[132] ?? 0) + m($marks[133] ?? 0) + m($marks[134] ?? 0);
$marks[139] = m($marks[136] ?? 0) + m($marks[137] ?? 0) + m($marks[138] ?? 0);
$marks[143] = m($marks[140] ?? 0) + m($marks[141] ?? 0) + m($marks[142] ?? 0);
$marks[147] = m($marks[144] ?? 0) + m($marks[145] ?? 0) + m($marks[146] ?? 0);
$marks[151] = m($marks[148] ?? 0) + m($marks[149] ?? 0) + m($marks[150] ?? 0);
$marks[155] = m($marks[152] ?? 0) + m($marks[153] ?? 0) + m($marks[154] ?? 0);
$marks[159] = m($marks[156] ?? 0) + m($marks[157] ?? 0) + m($marks[158] ?? 0);
$marks[163] = m($marks[160] ?? 0) + m($marks[161] ?? 0) + m($marks[162] ?? 0);

$marks[167] = m($marks[165] ?? 0) + m($marks[166] ?? 0) + m($marks[164] ?? 0);
$marks[171] = m($marks[170] ?? 0) + m($marks[169] ?? 0) + m($marks[168] ?? 0);

/* ---------- PART 3: GROUP TOTALS ---------- */

$marks[3]  = m($marks[0])  + m($marks[1])  + m($marks[2]);
$marks[7]  = m($marks[4])  + m($marks[5])  + m($marks[6]);
$marks[13] = m($marks[10]) + m($marks[11]) + m($marks[12]);
$marks[17] = m($marks[14]) + m($marks[15]) + m($marks[16]);
$marks[23] = m($marks[20]) + m($marks[21]) + m($marks[22]);
$marks[27] = m($marks[24]) + m($marks[25]) + m($marks[26]);
$marks[33] = m($marks[30]) + m($marks[31]) + m($marks[32]);
$marks[37] = m($marks[34]) + m($marks[35]) + m($marks[36]);
$marks[43] = m($marks[40]) + m($marks[41]) + m($marks[42]);
$marks[47] = m($marks[44]) + m($marks[45]) + m($marks[46]);
$marks[53] = m($marks[50]) + m($marks[51]) + m($marks[52]);
$marks[57] = m($marks[54]) + m($marks[55]) + m($marks[56]);
$marks[63] = m($marks[60]) + m($marks[61]) + m($marks[62]);
$marks[67] = m($marks[64]) + m($marks[65]) + m($marks[66]);
$marks[73] = m($marks[70]) + m($marks[71]) + m($marks[72]);
$marks[77] = m($marks[74]) + m($marks[75]) + m($marks[76]);

$marks[8]  = m($marks[3])   + m($marks[7])   + m($marks[111]) + m($marks[115]);
$marks[18] = m($marks[119]) + m($marks[123]) + m($marks[13])  + m($marks[17]);
$marks[28] = m($marks[23])  + m($marks[27])  + m($marks[127]) + m($marks[131]);
$marks[38] = m($marks[33])  + m($marks[37])  + m($marks[135]) + m($marks[139]);
$marks[48] = m($marks[143]) + m($marks[147]) + m($marks[43])  + m($marks[47]);
$marks[68] = m($marks[151]) + m($marks[155]) + m($marks[63])  + m($marks[67]);
$marks[78] = m($marks[163]) + m($marks[159]) + m($marks[73])  + m($marks[77]);

$marks[9]  = getGradenew($marks[8]);
$marks[19] = getGradenew($marks[18]);
$marks[29] = getGradenew($marks[28]);
$marks[39] = getGradenew($marks[38]);
$marks[49] = getGradenew($marks[48]);
$marks[69] = getGradenew($marks[68]);
$marks[79] = getGradenew($marks[78]);

$marks[151] = $marks[111] + $marks[119] + $marks[127] + $marks[135] + $marks[143];
$marks[155] = $marks[115] + $marks[123] + $marks[131] + $marks[139] + $marks[147];
$final_marks = array_combine(
    range(1, count($marks)),
    array_values($marks)
);

/* ================== SAVE ================== */
$json_data = json_encode($final_marks, JSON_UNESCAPED_UNICODE);
try {
    $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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");

    $insertSuccessful = $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'
    ]);

    if (!$insertSuccessful) {
        errorreturn("Failed to insert data into marksheet_data.");
       
    }

    $insertId = $conn_rjllearning_specific->lastInsertId();

    $analytics = marksheet_analytics_29_store_all($json_data);

    $update = $conn_rjllearning_specific->prepare("
        UPDATE student_marksheet_data 
        SET analytics = ?
        WHERE id = ?
    ");

    $updateSuccessful = $update->execute([
        json_encode($analytics),
        $insertId
    ]);

    if ($updateSuccessful) {
        successreturn("Data inserted successfully.");
    } else {
        errorreturn("Data inserted, but analytics update failed.");
    }

} catch (PDOException $e) {
    errorreturn("Database error: " . $e->getMessage());
}

// function marksheet_analytics_29($json)
// {
//     $data = json_decode($json, true);

//     if (!is_array($data)) {
//         return ['error' => 'Invalid marks data'];
//     }

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

//     $subjects = [
//         ['name' => 'English',  'sum' => 9,  'grade' => 10],
//         ['name' => 'Hindi',    'sum' => 19, 'grade' => 20],
//         ['name' => 'Punjabi',  'sum' => 29, 'grade' => 30],
//         ['name' => 'Maths',    'sum' => 39, 'grade' => 40],
//         ['name' => 'EVS',      'sum' => 49, 'grade' => 50],
//         ['name' => 'Drawing',  'sum' => 59, 'grade' => 60],
//         ['name' => 'GK/A.P', 'sum' => 69, 'grade' => 70]
//     ];

//     $percentageIndices = [9, 19, 29, 39, 49];

//     $marksObtained = 0;
//     foreach ($percentageIndices as $idx) {
//         $marksObtained += (float)($data[$idx] ?? 0);
//     }

//     $totalMax = 1000; // 5 × 200
//     $percentage = round(($marksObtained / $totalMax) * 100, 2);
//     $overallGrade = getGrade($marksObtained, $totalMax);

//     $subjectRankings = [];
//     foreach ($subjects as $subject) {
//         $obtained = (float)($data[$subject['sum']] ?? 0);

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

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

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

/* ================== GRADE FUNCTION ================== */
function getGrade($obtained, $total)
{
    if ($total <= 0) return 'E2';

    $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';
}

/* ================== SAFE SUM ================== */
function safe_sum(array $data, array $keys): float
{
    $sum = 0;

    foreach ($keys as $k) {

        if (!isset($data[$k])) continue;

        $v = $data[$k];

        // treat LT as 0
        if (is_string($v) && strtoupper(trim($v)) === 'LT') {
            $v = 0;
        }

        if (is_numeric($v)) {
            $sum += (float)$v;
        }
    }

    return $sum;
}

/* ================== SUBJECT RANKINGS ================== */
function build_subject_rankings(array $subjectTotals, array $subjectMax)
{
    $rankings = [];

    foreach ($subjectTotals as $subject => $total) {
        $max = $subjectMax[$subject] ?? 0;

        $rankings[] = [
            'subject'    => $subject,
            'total'      => $total,
            'percentage' => $max > 0 ? round(($total / $max) * 100, 2) : 0,
            'grade'      => getGrade($total, $max)
        ];
    }

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

    return $rankings;
}

/* ================== CORE CALCULATION ================== */
function calculate_block($json, array $subjectIndexMap, array $subjectMax)
{
    $data = json_decode($json, true);

    if (!is_array($data)) {
        return [
            'total_obtained' => 0,
            'total_max' => 0,
            'percentage' => 0,
            'grade' => 'E2',
            'highest_marks_obtained_subject' => null,
            'lowest_marks_obtained_subject' => null,
            'subject_rankings' => []
        ];
    }

    // normalize numeric keys
    $data = array_combine(
        array_map('intval', array_keys($data)),
        array_values($data)
    );

    $subjectTotals = [];

    foreach ($subjectIndexMap as $subject => $indices) {
        $subjectTotals[$subject] = safe_sum($data, $indices);
    }

    $totalObtained = array_sum($subjectTotals);
    $totalMax = array_sum($subjectMax);

    $rankings = build_subject_rankings($subjectTotals, $subjectMax);

    return [
        'total_obtained' => $totalObtained,
        'total_max' => $totalMax,
        'percentage' => $totalMax > 0 ? round(($totalObtained / $totalMax) * 100, 2) : 0,
        'grade' => getGrade($totalObtained, $totalMax),
        'highest_marks_obtained_subject' => $rankings[0]['subject'] ?? null,
        'lowest_marks_obtained_subject' => end($rankings)['subject'] ?? null,
        'subject_rankings' => $rankings
    ];
}

/* ================== MAIN FUNCTION ================== */
function marksheet_analytics_29_store_all($json)
{
    $SUBJECT_MAX = [
        'English'  => 100,
        'Hindi'    => 100,
        'Punjabi'  => 100,
        'Maths'    => 100,
        'EVS'      => 100,
        'Drawing'  => 100,
        'GK/A.P'   => 100,
    ];

    $UNIT1 = [
        'English'  => [109,110,111,112],
        'Hindi'    => [117,118,119,120],
        'Punjabi'  => [125,126,127,128],
        'Maths'    => [133,134,135,136],
        'EVS'      => [141,142,143,144],
        'Drawing'  => [145,146,147,148],
        'GK/A.P'   => [150,151],
    ];

    $TERM1 = [
        'English'  => range(109,116),
        'Hindi'    => range(117,124),
        'Punjabi'  => range(125,132),
        'Maths'    => range(133,140),
        'EVS'      => range(141,148),
        'Drawing'  => [],
        'GK/A.P'   => [],
    ];

    $UNIT2 = [
        'English'  => [1,2,3,4],
        'Hindi'    => [11,12,13,14],
        'Punjabi'  => [21,22,23,24],
        'Maths'    => [31,32,33,34],
        'EVS'      => [41,42,43,44],
        'Drawing'  => [51,52,53,54],
        'GK/A.P'   => [61,62,63,64],
    ];

    $FINAL = [
        'English'  => range(1,10),
        'Hindi'    => range(11,20),
        'Punjabi'  => range(21,30),
        'Maths'    => range(31,40),
        'EVS'      => range(41,50),
        'Drawing'  => range(51,60),
        'GK/A.P'   => range(61,70),
    ];

    return [
        'p1' => array_merge(['label' => 'Unit 1'], calculate_block($json, $UNIT1, $SUBJECT_MAX)),
        'p2' => array_merge(['label' => 'Term 1'], calculate_block($json, $TERM1, $SUBJECT_MAX)),
        'p3' => array_merge(['label' => 'Unit 2'], calculate_block($json, $UNIT2, $SUBJECT_MAX)),
        'final' => array_merge(['label' => 'Final'], calculate_block($json, $FINAL, $SUBJECT_MAX)),
    ];
}