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


/* ===================== INPUT ===================== */

$marks = array_values($postdata['marks']);                 // normalize index
$subject_enabled = $postdata['subject_enabled'] ?? [];     // subject flags

/* ===================== HELPERS ===================== */
/* ✅ Average ignoring LT / null values */
function avgIgnoreNull(array $arr) {
    $arr = array_filter($arr, fn($v) => $v !== null);
    return count($arr) ? (array_sum($arr) / count($arr)) : 0;
}
function numVal($v) {
    return (is_numeric($v)) ? (float)$v : null;
}

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

//  ✅ Convert raw oral marks to percent (max  50   )
function percentFromOral50($val) {
    return ($val === null) ? null : (($val / 50) * 100);
}

/* ✅ Convert raw written marks to percent (max 50) */
function percentFromWritten50($val) {
    return ($val === null) ? null : (($val / 50) * 100);
}

/* ✅ set empty string but keep index */
function blankRangeKeepIndex(&$marks, $from, $to) {
    for ($i = $from; $i <= $to; $i++) {
        $marks[$i] = '';
    }
}

/* ===================== SUBJECT ENABLE CHECK ===================== */

$hindiEnabled   = (!empty($subject_enabled['hindi']) && $subject_enabled['hindi'] == 1);
$evsEnabled     = (!empty($subject_enabled['evs']) && $subject_enabled['evs'] == 1);
$gkEnabled      = (!empty($subject_enabled['gk']) && $subject_enabled['gk'] == 1);
$drawingEnabled = (!empty($subject_enabled['drawing']) && $subject_enabled['drawing'] == 1);

/* ===================== IF DISABLED -> BLANK THEIR DATA (KEEP INDEX) ===================== */

if (!$hindiEnabled)   blankRangeKeepIndex($marks, 4, 7);
if (!$evsEnabled)     blankRangeKeepIndex($marks, 12, 13);
if (!$gkEnabled)      blankRangeKeepIndex($marks, 14, 15);
if (!$drawingEnabled) blankRangeKeepIndex($marks, 16, 17);

/* ===================== OVERALL GRADE (18 & 19) ===================== */

$percP3 = [];
$percP4 = [];

/* English (always) */
$percP3[] = percentFromOral50(numVal($marks[0] ?? null));
$percP3[] = percentFromWritten50(numVal($marks[2] ?? null));
$percP4[] = percentFromOral50(numVal($marks[1] ?? null));
$percP4[] = percentFromWritten50(numVal($marks[3] ?? null));

/* Hindi (optional) */
if ($hindiEnabled) {
    $percP3[] = percentFromOral50(numVal($marks[4] ?? null));
    $percP3[] = percentFromWritten50(numVal($marks[6] ?? null));
    $percP4[] = percentFromOral50(numVal($marks[5] ?? null));
    $percP4[] = percentFromWritten50(numVal($marks[7] ?? null));
}

/* Maths (always) */
$percP3[] = percentFromOral50(numVal($marks[8] ?? null));
$percP3[] = percentFromWritten50(numVal($marks[10] ?? null));
$percP4[] = percentFromOral50(numVal($marks[9] ?? null));
$percP4[] = percentFromWritten50(numVal($marks[11] ?? null));

/* EVS (optional oral max 50) */
if ($evsEnabled) {
    $percP3[] = percentFromOral50(numVal($marks[12] ?? null));
    $percP4[] = percentFromOral50(numVal($marks[13] ?? null));
}

/* GK (optional oral max 50) */
if ($gkEnabled) {
    $percP3[] = percentFromOral50(numVal($marks[14] ?? null));
    $percP4[] = percentFromOral50(numVal($marks[15] ?? null));
}

/* Drawing (optional oral max 50) */
if ($drawingEnabled) {
    $percP3[] = percentFromOral50(numVal($marks[16] ?? null));
    $percP4[] = percentFromOral50(numVal($marks[17] ?? null));
}

$avgP3 = avgIgnoreNull($percP3);
$avgP4 = avgIgnoreNull($percP4);

$marks[18] = gradeFromPercent($avgP3);
$marks[19] = gradeFromPercent($avgP4);

/* ===================== ✅ NO CONVERSION FOR 0 to 17 ===================== */
/* (marks[0] to marks[17] will remain numbers or blanks) */


/* ===================== TERM-1 (38 to 57) ===================== */

$subject_enabled = $postdata['subject_enabled'] ?? [];

/* ✅ Enabled Subjects */
$hindiEnabled   = (!empty($subject_enabled['hindi']) && $subject_enabled['hindi'] == 1);
$evsEnabled     = (!empty($subject_enabled['evs']) && $subject_enabled['evs'] == 1);
$gkEnabled      = (!empty($subject_enabled['gk']) && $subject_enabled['gk'] == 1);
$drawingEnabled = (!empty($subject_enabled['drawing']) && $subject_enabled['drawing'] == 1);

/* ✅ If Disabled -> Blank Sequence */
if (!$hindiEnabled)   blankRangeKeepIndex($marks, 42, 45);
if (!$evsEnabled)     blankRangeKeepIndex($marks, 50, 51);
if (!$gkEnabled)      blankRangeKeepIndex($marks, 52, 53);
if (!$drawingEnabled) blankRangeKeepIndex($marks, 54, 55);

/* ===================== OVERALL GRADE TERM-1 (56 & 57) ===================== */

$percP1 = [];
$percP2 = [];

/* English */
$percP1[] = percentFromOral50(numVal($marks[38] ?? null));
$percP1[] = percentFromWritten50(numVal($marks[40] ?? null));
$percP2[] = percentFromOral50(numVal($marks[39] ?? null));
$percP2[] = percentFromWritten50(numVal($marks[41] ?? null));

/* Hindi */
if ($hindiEnabled) {
    $percP1[] = percentFromOral50(numVal($marks[42] ?? null));
    $percP1[] = percentFromWritten50(numVal($marks[44] ?? null));
    $percP2[] = percentFromOral50(numVal($marks[43] ?? null));
    $percP2[] = percentFromWritten50(numVal($marks[45] ?? null));
}

/* Maths */
$percP1[] = percentFromOral50(numVal($marks[46] ?? null));
$percP1[] = percentFromWritten50(numVal($marks[48] ?? null));
$percP2[] = percentFromOral50(numVal($marks[47] ?? null));
$percP2[] = percentFromWritten50(numVal($marks[49] ?? null));

/* EVS */
if ($evsEnabled) {
    $percP1[] = percentFromOral50(numVal($marks[50] ?? null));
    $percP2[] = percentFromOral50(numVal($marks[51] ?? null));
}

/* GK */
if ($gkEnabled) {
    $percP1[] = percentFromOral50(numVal($marks[52] ?? null));
    $percP2[] = percentFromOral50(numVal($marks[53] ?? null));
}

/* Drawing */
if ($drawingEnabled) {
    $percP1[] = percentFromOral50(numVal($marks[54] ?? null));
    $percP2[] = percentFromOral50(numVal($marks[55] ?? null));
}

$avgP1 = avgIgnoreNull($percP1);
$avgP2 = avgIgnoreNull($percP2);

$marks[56] = gradeFromPercent($avgP1);
$marks[57] = gradeFromPercent($avgP2);

/* ===================== ✅ NO CONVERSION FOR 38 to 55 ===================== */
/* (marks[38] to marks[55] will remain numbers or blanks) */


/* ===================== FINAL OUTPUT ===================== */

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


/* ================== SAVE ================== */
$json_data = json_encode($final_marks, JSON_UNESCAPED_UNICODE);


$insertStmt = $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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");

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

// ✅ get inserted row id
$lastId = $conn_rjllearning_specific->lastInsertId();

// ✅ analytics generate
$analytics =  marksheet_analytics_34_store_all($json_data);

// ✅ update analytics in same row
$updateStmt = $conn_rjllearning_specific->prepare("
    UPDATE student_marksheet_data 
    SET analytics = ?
    WHERE id = ?
");

$updateStmt->execute([
    json_encode($analytics, JSON_UNESCAPED_UNICODE),
    $lastId
]);

successreturn("Marksheet saved successfully.");


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

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

//     // ✅ Convert keys into int (1..n)
//     $data = array_combine(
//         array_map('intval', array_keys($data)),
//         array_values($data)
//     );

//     // ✅ numeric safe
//     $num = function ($v) {
//         return (is_numeric($v)) ? (float)$v : 0;
//     };

//     // ✅ subject enabled check (optional subjects)
//     $isEnabledByIndex = function ($idxList) use ($data) {
//         foreach ($idxList as $idx0) {
//             $k = $idx0 + 1; // JSON keys are 1-based
//             if (isset($data[$k]) && $data[$k] !== '' && $data[$k] !== null) {
//                 return true;
//             }
//         }
//         return false;
//     };

//     // ✅ Grade mapping same as your grading logic
//     $gradeFromPercent = function ($percent) {
//         if ($percent >= 91) return 'A1';
//         if ($percent >= 81) return 'A2';
//         if ($percent >= 71) return 'B1';
//         if ($percent >= 61) return 'B2';
//         if ($percent >= 51) return 'C1';
//         if ($percent >= 41) return 'C2';
//         if ($percent >= 33) return 'D';
//         if ($percent >= 21) return 'E1';
//         return 'E2';
//     };

//     /*
//       ✅ SUBJECT INDEX GROUPS (0-based)
//       Total subject marks = (P3+P4) + (P1+P2)
//     */
//     $subjects = [
//         [
//             'name' => 'English',
//             'p3p4' => [0, 1, 2, 3],
//             'p1p2' => [38, 39, 40, 41],
//             'optional' => false
//         ],
//         [
//             'name' => 'Hindi',
//             'p3p4' => [4, 5, 6, 7],
//             'p1p2' => [42, 43, 44, 45],
//             'optional' => true
//         ],
//         [
//             'name' => 'Maths',
//             'p3p4' => [8, 9, 10, 11],
//             'p1p2' => [46, 47, 48, 49],
//             'optional' => false
//         ],
//         [
//             'name' => 'EVS',
//             'p3p4' => [12, 13],
//             'p1p2' => [50, 51],
//             'optional' => true
//         ],
//         [
//             'name' => 'GK',
//             'p3p4' => [14, 15],
//             'p1p2' => [52, 53],
//             'optional' => true
//         ],
//         [
//             'name' => 'Drawing',
//             'p3p4' => [16, 17],
//             'p1p2' => [54, 55],
//             'optional' => true
//         ],
//     ];

//     // ✅ Build subject rankings same as template 29 format
//     $subjectRankings = [];
//     $marksObtained = 0;

//     foreach ($subjects as $sub) {

//         // ✅ skip optional if empty
//         $enabled = true;
//         if ($sub['optional']) {
//             $enabled = $isEnabledByIndex(array_merge($sub['p3p4'], $sub['p1p2']));
//         }
//         if (!$enabled) continue;

//         // ✅ total = P3+P4 + P1+P2 marks
//         $total = 0;

//         foreach ($sub['p3p4'] as $idx0) {
//             $total += $num($data[$idx0 + 1] ?? 0);
//         }
//         foreach ($sub['p1p2'] as $idx0) {
//             $total += $num($data[$idx0 + 1] ?? 0);
//         }

//         $marksObtained += $total;

//         // ✅ per subject max:
//         // English/Hindi/Maths: Oral30+Written50 for each term (P1,P2,P3,P4) => 80*4 = 320
//         // EVS/GK/Drawing: Oral30 for each term (P1,P2,P3,P4) => 30*4 = 120
//         $subjectMax = 0;
//         if (in_array($sub['name'], ['English', 'Hindi', 'Maths'])) {
//             $subjectMax = 320;
//         } else {
//             $subjectMax = 120;
//         }

//         $subjectPercent = ($subjectMax > 0) ? round(($total / $subjectMax) * 100, 2) : 0;
//         $subjectGrade = $gradeFromPercent($subjectPercent);

//         $subjectRankings[] = [
//             'subject'    => $sub['name'],
//             'total'      => round($total, 2),
//             'percentage' => $subjectPercent,
//             'grade'      => $subjectGrade
//         ];
//     }

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

//     // ✅ total max calculate based on enabled subjects
//     $totalMax = 0;
//     foreach ($subjectRankings as $row) {
//         if (in_array($row['subject'], ['English', 'Hindi', 'Maths'])) {
//             $totalMax += 320;
//         } else {
//             $totalMax += 120;
//         }
//     }

//     // ✅ overall percentage + grade
//     $percentage = ($totalMax > 0) ? round(($marksObtained / $totalMax) * 100, 2) : 0;
//     $overallGrade = $gradeFromPercent($percentage);

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


function marksheet_analytics_34($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));
    $num = fn($v) => is_numeric($v) ? (float)$v : 0;

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

    $has_unit2  = isset($data[1]) || isset($data[3]);
    $has_unit1  = isset($data[39]) && !isset($data[40]);
    $has_term1  = isset($data[39]) && isset($data[40]);
    $has_final  = $has_unit2 && ($has_unit1 || $has_term1);

    if ($has_final) {
        $use_p3p4 = range(0, 17);
        $use_p1p2 = range(38, 55);
    } elseif ($has_term1) {
        $use_p3p4 = [];
        $use_p1p2 = range(38, 56);
    } elseif ($has_unit1) {
        $use_p3p4 = [];
        $use_p1p2 = [38,39,42,43,46,47,50,52,54];
    } elseif ($has_unit2) {
        $use_p3p4 = range(0, 17);
        $use_p1p2 = [];
    } else {
        return ['error' => 'Unable to detect exam type'];
    }

    $subjects = [
        'English' => ['idx' => [0,1,2,3], 'max' => 400],
        'Hindi'   => ['idx' => [4,5,6,7], 'max' => 400],
        'Maths'   => ['idx' => [8,9,10,11], 'max' => 400],
        'EVS'     => ['idx' => [12,13], 'max' => 200],
        'GK'      => ['idx' => [14,15], 'max' => 200],
        'Drawing' => ['idx' => [16,17], 'max' => 200],
    ];

    $subjectRankings = [];
    $marksObtained = 0;
    $totalMax = 0;

    foreach ($subjects as $subject => $cfg) {
        $total = 0;

        foreach ($use_p3p4 as $i) {
            if (in_array($i, $cfg['idx'])) {
                $total += $num($data[$i + 1] ?? 0);
            }
        }

        foreach ($use_p1p2 as $i) {
            $i0 = $i - 38;
            if (in_array($i0, $cfg['idx'])) {
                $total += $num($data[$i + 1] ?? 0);
            }
        }

        if ($total <= 0) continue;

        $percent = round(($total / $cfg['max']) * 100, 2);
        $grade = $gradeFromPercent($percent);

        $marksObtained += $total;
        $totalMax += $cfg['max'];

        $subjectRankings[] = [
            'subject' => $subject,
            'total' => round($total, 2),
            'percentage' => $percent,
            'grade' => $grade
        ];
    }

    usort($subjectRankings, fn($a, $b) => $b['total'] <=> $a['total']);
    // $overallPercent = $totalMax > 0 ? round(($marksObtained / $totalMax) * 100, 2) : 0;
$overallPercent = $totalMax > 0
    ? number_format(($marksObtained / $totalMax) * 100, 2, '.', '')
    : 0;
    
    return [
        'total_obtained' => round($marksObtained, 2),
        'total_max' => $totalMax,
        'percentage' => $overallPercent,
        'grade' => $gradeFromPercent($overallPercent),
        'highest_marks_obtained_subject' => $subjectRankings[0]['subject'] ?? null,
        'lowest_marks_obtained_subject' => end($subjectRankings)['subject'] ?? null,
        'subject_rankings' => $subjectRankings
    ];
}


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

    // helper to filter keys
    $only = function ($keys) use ($data) {
        $out = [];
        foreach ($keys as $k) {
            if (isset($data[$k])) {
                $out[$k] = $data[$k];
            }
        }
        return json_encode($out);
    };

    // 🔹 key maps (exactly from your HTML)
    $unit2_keys = [1,3,5,7,9,11,13,15,17];
    $unit1_keys = [39,41,43,45,47,49,51,53,55];
    $term1_keys = [39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56];
    $final_keys = array_merge(range(1,17), range(39,56));
    
    // $unit2_keys = [0,2,4,6,8,10,12,14,16];
    // $unit1_keys = [38,40,42,44,46,48,50,52,54];
    // $term1_keys = [39,41,43,45,47,49,51,53,55];

    return [
        'p1' => array_merge(
            ['label' => 'Unit 1'],
            marksheet_analytics_34($only($unit1_keys))
        ),
        'p2' => array_merge(
            ['label' => 'Term 1'],
            marksheet_analytics_34($only($term1_keys))
        ),
        'p3' => array_merge(
            ['label' => 'Unit 2'],
            marksheet_analytics_34($only($unit2_keys))
        ),
        'final' => array_merge(
            ['label' => 'Final'],
            marksheet_analytics_34($only($final_keys))
        )
    ];
}
?>