<?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'];

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

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

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

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

/* ---------- PART 3: GROUP TOTALS (FIXED & SAFE) ---------- */

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

$marks[8]  =
    (float)($marks[3]   ?? 0) +
    (float)($marks[7]   ?? 0) +
    (float)($marks[111] ?? 0) +
    (float)($marks[115] ?? 0);

$marks[18] =
    (float)($marks[119] ?? 0) +
    (float)($marks[123] ?? 0) +
    (float)($marks[13]  ?? 0) +
    (float)($marks[17]  ?? 0);

$marks[28] =
    (float)($marks[23]  ?? 0) +
    (float)($marks[27]  ?? 0) +
    (float)($marks[127] ?? 0) +
    (float)($marks[131] ?? 0);

$marks[38] =
    (float)($marks[33]  ?? 0) +
    (float)($marks[37]  ?? 0) +
    (float)($marks[135] ?? 0) +
    (float)($marks[139] ?? 0);

$marks[48] =
    (float)($marks[143] ?? 0) +
    (float)($marks[147] ?? 0) +
    (float)($marks[43]  ?? 0) +
    (float)($marks[47]  ?? 0);

$marks[68] =
    (float)($marks[151] ?? 0) +
    (float)($marks[155] ?? 0) +
    (float)($marks[63]  ?? 0) +
    (float)($marks[67]  ?? 0);

$marks[78] =
    (float)($marks[163] ?? 0) +
    (float)($marks[159] ?? 0) +
    (float)($marks[73]  ?? 0) +
    (float)($marks[77]  ?? 0);

$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]) && is_numeric($data[$k])) {
            $sum += (float)$data[$k];
        }
    }
    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 MARKS ---------- */
    $SUBJECT_MAX = [
        'English'  => 100,
        'Hindi'    => 100,
        'Punjabi'  => 100,
        'Maths'    => 100,
        'EVS'      => 100,
        'Drawing'  => 100,
        'GK/A.P'   => 100,
    ];

    /* ---------- UNIT 1 (ONLY OBTAINED MARKS) ---------- */
    $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],
    ];

    /* ---------- TERM 1 ---------- */
    $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'   => [],
    ];

    /* ---------- UNIT 2 ---------- */
    $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 ---------- */
    $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)
        ),
    ];
}
