<?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_resources . 'includes/specific_db_config.php';

$postdata = $_POST;

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

validateApiSignature($postdata['api_signature']);

$jwt = authenticate_jwt($postdata['jwt_token']);

$user_id      = $jwt->data->id;
$username     = $jwt->data->username;
$workspace_id = $jwt->data->workspace_id;
$role         = $jwt->data->role;

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

if (!$specific_db) {
    errorreturn("Access denied.");
}

$conn_rjllearning_specific = dynamicDbConnection($specific_db);

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

function safeFloat($v)
{
    return is_numeric($v) ? (float)$v : 0;
}

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

$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.");
} else {
    $examination = $rowmarksheet['examination_name'];
    $templateid = $rowmarksheet['template_id'];
    $academicsession = $rowmarksheet['academic_session'];
    $createdon = $rowmarksheet['time_created'];
    $createdon = $rowmarksheet['date_created'];
    $createdby = $rowmarksheet['added_by'];
}

$ExecuteSqlTemplate = $conn_rjllearning->prepare("SELECT cols, template_name FROM template_info WHERE id = ?");
$ExecuteSqlTemplate->execute([$templateid]);
$ResultTemplate = $ExecuteSqlTemplate->fetch(PDO::FETCH_ASSOC);

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

$templateName = $ResultTemplate['template_name'];
$cols = $ResultTemplate['cols'];

$data = [];
for ($i = 1; $i <= $cols; $i++) {
    $data[$i] = null;
}

$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.");
} else {
    $studentname = $rowstudent['name'];
    $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 snapshot
            $class = $lock_row['class_id'];
            $section_id = $lock_row['section_id'];

            break;
        }
    }
}

// foreach ($postdata['marks'] as $i => $val) {
//     $data[$i] = is_numeric($val) ? safeFloat($val) : trim($val);
// }
foreach ($postdata['marks'] as $i => $val) {
    $idx = $i + 1; // keep same index
    $data[$idx] = is_numeric($val) ? safeFloat($val) : trim($val);
}

$rules = [
    //English
    4 => ['sum_of' => [1, 2, 3]],
    8 => ['sum_of' => [5, 6, 7]],
    122 => ['sum_of' => [119, 120, 121]],
    126 => ['sum_of' => [123, 124, 125]],
    9 => ['sum_of' => [4, 8, 122, 126]],
    10 => ['grade_of' => [9, 200]],

    // HINDI
    14 => ['sum_of' => [11, 12, 13]],
    18 => ['sum_of' => [15, 16, 17]],
    130 => ['sum_of' => [127, 128, 129]],
    134 => ['sum_of' => [131, 132, 133]],
    19 => ['sum_of' => [14, 18, 130, 134]],
    20 => ['grade_of' => [19, 200]],

    // PUNJABI
    24 => ['sum_of' => [21, 22, 23]],
    28 => ['sum_of' => [25, 26, 27]],
    138 => ['sum_of' => [135, 136, 137]],
    142 => ['sum_of' => [139, 140, 141]],
    29 => ['sum_of' => [24, 28, 138, 142]],
    30 => ['grade_of' => [29, 200]],

    // MATHS
    34 => ['sum_of' => [31, 32, 33]],
    38 => ['sum_of' => [35, 36, 37]],
    146 => ['sum_of' => [143, 144, 145]],
    150 => ['sum_of' => [147, 148, 149]],
    39 => ['sum_of' => [34, 38, 146, 150]],
    40 => ['grade_of' => [39, 200]],

    // EVS
    44 => ['sum_of' => [41, 42, 43]],
    48 => ['sum_of' => [45, 46, 47]],
    154 => ['sum_of' => [151, 152, 153]],
    158 => ['sum_of' => [155, 156, 157]],
    49 => ['sum_of' => [44, 48, 154, 158]],
    50 => ['grade_of' => [49, 200]],

    // DRAWING
    54 => ['sum_of' => [51, 52, 53]],
    58 => ['sum_of' => [55, 56, 57]],
    170 => ['sum_of' => [167, 168, 169]],
    174 => ['sum_of' => [171, 172, 173]],
    59 => ['sum_of' => [54, 58, 170, 174]],
    60 => ['grade_of' => [59, 200]],

    // COMPUTER
    64 => ['sum_of' => [61, 62, 63]],
    68 => ['sum_of' => [65, 66, 67]],
    178 => ['sum_of' => [175, 176, 177]],
    182 => ['sum_of' => [179, 180, 181]],
    69 => ['sum_of' => [64, 68, 178, 182]],
    70 => ['grade_of' => [69, 200]],

    // GK
    74 => ['sum_of' => [71, 72, 73]],
    78 => ['sum_of' => [75, 76, 77]],
    186 => ['sum_of' => [183, 184, 185]],
    190 => ['sum_of' => [187, 188, 189]],
    79 => ['sum_of' => [74, 78, 186, 190]],
    80 => ['grade_of' => [79, 200]],

    159 => ['sum_of' => [119, 127, 135, 143, 151]],
    160 => ['sum_of' => [120, 128, 136, 144, 152]],
    161 => ['sum_of' => [121, 129, 137, 145, 153]],
    162 => ['sum_of' => [122, 130, 138, 146, 154]],
    163 => ['sum_of' => [123, 131, 139, 147, 155]],
    164 => ['sum_of' => [124, 132, 140, 148, 156]],
    165 => ['sum_of' => [125, 133, 141, 149, 157]],
    166 => ['sum_of' => [126, 134, 142, 150, 158]],

    191 => ['percentage_of' => [[162, 166], 500]],


];

foreach ($rules as $target => $rule) {

    if (isset($rule['sum_of'])) {
        $sum = 0;
        foreach ($rule['sum_of'] as $src) {
            $sum += safeFloat($data[$src] ?? 0);
        }
        $data[$target] = $sum;
    }

    if (isset($rule['grade_of'])) {
        [$sumIndex, $total] = $rule['grade_of'];
        $data[$target] = getGrade(
            safeFloat($data[$sumIndex] ?? 0),
            $total
        );
    }

    if (isset($rule['ratio_of'])) {
        [$obtIdx, $totIdx] = $rule['ratio_of'];

        $obt = safeFloat($data[$obtIdx] ?? 0);
        $tot = safeFloat($data[$totIdx] ?? 0);

        $data[$target] = ($tot > 0)
            ? round(($obt / $tot) * 100, 2)
            : 0;
    }

   if (isset($rule['percentage_of'])) {
    [$indices, $total] = $rule['percentage_of'];

    $obtained = 0;
    foreach ($indices as $idx) {
        $obtained += safeFloat($data[$idx] ?? 0);
    }

    $data[$target] = ($total > 0)
        ? (int) round(($obtained / $total) * 100) // 🔥 fully rounded
        : 0;
}
}

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

// $json = json_encode(array_values($data), JSON_UNESCAPED_UNICODE);
$json = json_encode($data, 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");

    // Execute the query with the provided parameters
    $insertSuccessful = $insert->execute([
        $institution_id,
        $marksheet_id,
        $student_id,
        $json,
        $branch,
        $academic_id,
        $class,
        $section_id,
        $username, // Added by the current user
        date("Y-m-d"), // Date created
        date("H:i:s"), // Time created
        '1' // Default status to 1 if not provided
    ]);

    $insertId = $conn_rjllearning_specific->lastInsertId();

    $analytics = marksheet_analytics_30($json);

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

    if ($insertSuccessful) {
        successreturn("Data inserted successfully.");
    } else {
        errorreturn("Failed to insert data into marksheet_data.");
    }
} catch (PDOException $e) {
    errorreturn("Database error: " . $e->getMessage());
}

function calculate_term_30($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 / 100) * 100, 2),
            'grade' => getGrade($total, 100)
        ];
    }

    $totalMax = count($percentageSubjects) * 100;

    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_unit_30($data, $subjects, $percentageSubjects, $label = null)
{
    $subjectRankings = [];
    $marksObtained = 0;

    foreach ($subjects as $sub) {

        // single index value
        $total = (float)($data[$sub['sum']] ?? 0);

        // only these count in percentage
        if (in_array($sub['name'], $percentageSubjects)) {
            $marksObtained += $total;
        }

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

    // ✅ 5 subjects × 50 marks
    $totalMax = count($percentageSubjects) * 50;

    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 marksheet_analytics_30($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)
    );

    $p1_subjects = [
        ['name' => 'English',  'sum' => 122],
        ['name' => 'Hindi',    'sum' => 130],
        ['name' => 'Punjabi',  'sum' => 138],
        ['name' => 'Maths',    'sum' => 146],
        ['name' => 'EVS',      'sum' => 154],
        ['name' => 'Drawing',  'sum' => 170],
        ['name' => 'Computer', 'sum' => 178],
        ['name' => 'GK',       'sum' => 186]
    ];

    $term1Subjects = [
        ['name' => 'English',  'sum_of' => [122, 126]],
        ['name' => 'Hindi',    'sum_of' => [130, 134]],
        ['name' => 'Punjabi',  'sum_of' => [138, 142]],
        ['name' => 'Maths',    'sum_of' => [146, 150]],
        ['name' => 'EVS',      'sum_of' => [154, 158]],
        ['name' => 'Drawing',  'sum_of' => [170, 174]],
        ['name' => 'Computer', 'sum_of' => [178, 182]],
        ['name' => 'GK',       'sum_of' => [186, 190]]
    ];

    $p2_subjects = [
        ['name' => 'English',  'sum' => 4],
        ['name' => 'Hindi',    'sum' => 14],
        ['name' => 'Punjabi',  'sum' => 24],
        ['name' => 'Maths',    'sum' => 34],
        ['name' => 'EVS',      'sum' => 44],
        ['name' => 'Drawing',  'sum' => 54],
        ['name' => 'Computer', 'sum' => 64],
        ['name' => 'GK',       'sum' => 74]
    ];

    $term2Subjects = [
        ['name' => 'English',  'sum_of' => [4, 8]],
        ['name' => 'Hindi',    'sum_of' => [14, 18]],
        ['name' => 'Punjabi',  'sum_of' => [24, 28]],
        ['name' => 'Maths',    'sum_of' => [34, 38]],
        ['name' => 'EVS',      'sum_of' => [44, 48]],
        ['name' => 'Drawing',  'sum_of' => [54, 58]],
        ['name' => 'Computer', 'sum_of' => [64, 68]],
        ['name' => 'GK',       'sum_of' => [74, 78]]
    ];

    // only these subjects count in percentage
    $percentageSubjects = ['English', 'Hindi', 'Punjabi', 'Maths', 'EVS'];

    $Unit1 = calculate_unit_30($data, $p1_subjects, $percentageSubjects, 'Unit 1');
    $term1 = calculate_term_30($data, $term1Subjects, $percentageSubjects, 'Term 1');
    $Unit2 = calculate_unit_30($data, $p2_subjects, $percentageSubjects, 'Unit 2');
    $term2 = calculate_term_30($data, $term2Subjects, $percentageSubjects, 'Final');

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