<?php

require_once __DIR__ . '/../library/auth.php';
require_once __DIR__ . '/../library/audit_log.php';

allow_roles(['admin', 'teacher']);

$school_id = $_SESSION['school_id'];
$session_id = $_POST['session_id']
    ?? get_current_session_id($pdo);

$action = $_POST['action'] ?? $_GET['action'] ?? '';

switch ($action) {

    case 'add':
        addStudent();
        break;

    case 'edit':
        editStudent();
        break;

    case 'delete':
        deleteStudent();
        break;

    default:
        redirectWithError('index.php', 'Invalid action');
}

/*
|--------------------------------------------------------------------------
| HELPERS
|--------------------------------------------------------------------------
*/

function val($key, $default = '')
{
    return trim($_POST[$key] ?? $default);
}

function redirectWithError($url, $message)
{
    $_SESSION['error'] = $message;

    $_SESSION['old'] = $_POST;

    header("Location: $url");
    exit;
}

function redirectWithSuccess($url, $message)
{
    $_SESSION['success'] = $message;

    unset($_SESSION['old']);

    header("Location: $url");
    exit;
}

function validateImage($file)
{
    if (empty($file['name'])) {
        return true;
    }

    $allowedExt = ['jpg', 'jpeg', 'png', 'webp'];

    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

    if (!in_array($ext, $allowedExt)) {
        return 'Only JPG, JPEG, PNG, WEBP allowed';
    }

    if ($file['size'] > 2 * 1024 * 1024) {
        return 'Image size must be below 2MB';
    }

    $mime = mime_content_type($file['tmp_name']);

    $allowedMime = [
        'image/jpeg',
        'image/png',
        'image/webp'
    ];

    if (!in_array($mime, $allowedMime)) {
        return 'Invalid image file';
    }

    return true;
}

function uploadImage($file, $oldImage = '')
{
    if (empty($file['name'])) {
        return $oldImage;
    }

    $uploadDir = __DIR__ . '/uploads/';

    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }

    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

    $newName = uniqid('student_', true) . '.' . $ext;

    if (!move_uploaded_file($file['tmp_name'], $uploadDir . $newName)) {
        throw new Exception('Image upload failed');
    }

    if (
        !empty($oldImage) &&
        file_exists($uploadDir . $oldImage)
    ) {
        unlink($uploadDir . $oldImage);
    }

    return $newName;
}

function checkDuplicateRollNo($pdo, $school_id, $session_id, $class_id, $roll_no, $ignore_student_id = null)
{
    if (empty($roll_no)) {
        return false;
    }

    $sql = "
        SELECT id
        FROM student_sessions
        WHERE school_id = ?
        AND session_id = ?
        AND class_id = ?
        AND roll_no = ?
    ";

    $params = [
        $school_id,
        $session_id,
        $class_id,
        $roll_no
    ];

    if ($ignore_student_id) {

        $sql .= " AND student_id != ?";

        $params[] = $ignore_student_id;
    }

    $stmt = $pdo->prepare($sql);

    $stmt->execute($params);

    return $stmt->fetch();
}

/*
|--------------------------------------------------------------------------
| DATA HELPERS
|--------------------------------------------------------------------------
*/

function getStudentData($photo)
{
    global $school_id;

    $full_name = trim(
        val('first_name') . ' ' . val('last_name')
    );

    return [

        'school_id' => $school_id,

        'first_name' => val('first_name'),
        'last_name' => val('last_name'),

        'name' => $full_name,

        'gender' => val('gender'),
        'dob' => val('dob'),

        'phone' => val('phone'),
        'email' => val('email'),
		'enrollment_no' => val('scholar_no'),

        'photo' => $photo
    ];
}

function getStudentSessionData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'student_id' => $student_id,
        'session_id' => $session_id,

        'class_id' => val('class_id'),
        'section' => val('section'),

        'roll_no' => val('roll_no'),
        'admission_no' => val('admission_no'),

        'status' => 'Active'
    ];
}

function getParentData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'session_id' => $session_id,
        'student_id' => $student_id,

        'father_name' => val('father_name'),
		'father_phone' => val('father_phone'),
		'father_occupation' => val('father_occupation'),
		'father_income' => val('father_income'),

		'mother_name' => val('mother_name'),
		'mother_phone' => val('mother_phone'),
		'mother_occupation' => val('mother_occupation'),
		'mother_income' => val('mother_income'),

        'guardian_name' => val('guardian_name'),
        'guardian_relation' => val('guardian_relation'),
        'guardian_phone' => val('guardian_phone')
    ];
}

function getAddressData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'session_id' => $session_id,
        'student_id' => $student_id,

        'address' => val('address'),
        'permanent_address' => val('permanent_address'),

        'state' => val('state'),
        'city' => val('city'),
        'village' => val('village'),
        'pincode' => val('pincode')
    ];
}

function getDocumentData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'session_id' => $session_id,
        'student_id' => $student_id,

        'aadhaar_no' => val('aadhaar_no'),
        'name_as_per_aadhaar' => val('name_as_per_aadhaar'),

        'apaar_id' => val('apaar_id'),
        'pen_no' => val('pen_no'),

        'samagra_id' => val('samagra_id'),
        'family_sssmid' => val('family_sssmid'),

        'digital_caste_cert_no' => val('digital_caste_cert_no')
    ];
}

function getAcademicData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'session_id' => $session_id,
        'student_id' => $student_id,

        'prev_school_name' => val('prev_school_name'),
        'prev_class_studied' => val('prev_class_studied'),

        'appeared_prev_exam' => val('appeared_prev_exam'),
        'prev_exam_result' => val('prev_exam_result'),

        'marks_percentage' => val('marks_percentage'),
        'class_rank' => val('class_rank'),

        'attendance_prev_year' => val('attendance_prev_year')
    ];
}

function getCategoryData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'session_id' => $session_id,
        'student_id' => $student_id,

        'category' => val('category'),
        'caste' => val('caste'),
        'religion' => val('religion'),

        'minority_group' => val('minority_group'),
        'mother_tongue' => val('mother_tongue'),

        'is_bpl' => (int) val('is_bpl'),
        'is_rte' => (int) val('is_rte'),
        'is_ews' => (int) val('is_ews'),

        'annual_income' => val('annual_income')
    ];
}
function getBankDetailsData($student_id)
{
    global $school_id, $session_id;

    return [

        'school_id' => $school_id,
        'session_id' => $session_id,
        'student_id' => $student_id,

        'bank_acc_no' => val('bank_acc_no'),
        'bank_name' => val('bank_name'),
        'ifsc_code' => val('ifsc_code'),

        'opening_balance' => val('opening_balance')
    ];
}

/*
|--------------------------------------------------------------------------
| COMMON INSERT FUNCTION
|--------------------------------------------------------------------------
*/

function insertData($pdo, $table, $data)
{
    $columns = implode(',', array_keys($data));

    $placeholders = implode(',', array_fill(0, count($data), '?'));

    $sql = "
        INSERT INTO $table ($columns)
        VALUES ($placeholders)
    ";

    $stmt = $pdo->prepare($sql);

    $stmt->execute(array_values($data));
}

function updateData($pdo, $table, $data, $student_id)
{
    global $school_id;

    $setParts = [];

    foreach (array_keys($data) as $column) {

        if ($column == 'student_id') {
            continue;
        }

        $setParts[] = "$column = ?";
    }

    $setClause = implode(',', $setParts);

    $sql = "
        UPDATE $table
        SET $setClause,
        updated_at = NOW()
        WHERE student_id = ?
        AND school_id = ?
    ";

    $values = [];

    foreach ($data as $key => $value) {

        if ($key == 'student_id') {
            continue;
        }

        $values[] = $value;
    }

    $values[] = $student_id;
    $values[] = $school_id;

    $stmt = $pdo->prepare($sql);

    $stmt->execute($values);
}

/*
|--------------------------------------------------------------------------
| ADD STUDENT
|--------------------------------------------------------------------------
*/

function addStudent()
{
    global $pdo, $school_id, $session_id;

    try {

        $imageValidation = validateImage($_FILES['image'] ?? []);

        if ($imageValidation !== true) {
            redirectWithError('add.php', $imageValidation);
        }

        if (
            checkDuplicateRollNo(
                $pdo,
                $school_id,
                $session_id,
                val('class_id'),
                val('roll_no')
            )
        ) {

            redirectWithError(
                'add.php',
                'Roll number already exists'
            );
        }

        $pdo->beginTransaction();

        $photo = uploadImage($_FILES['image'] ?? []);

        /*
        |--------------------------------------------------------------------------
        | STUDENTS
        |--------------------------------------------------------------------------
        */

        $studentData = getStudentData($photo);

        insertData($pdo, 'students', $studentData);

        $student_id = $pdo->lastInsertId();

        /*
        |--------------------------------------------------------------------------
        | CHILD TABLES
        |--------------------------------------------------------------------------
        */

        insertData(
            $pdo,
            'student_sessions',
            getStudentSessionData($student_id)
        );

        insertData(
            $pdo,
            'student_parents',
            getParentData($student_id)
        );

        insertData(
            $pdo,
            'student_address',
            getAddressData($student_id)
        );

        insertData(
            $pdo,
            'student_documents',
            getDocumentData($student_id)
        );

        insertData(
            $pdo,
            'student_academic_info',
            getAcademicData($student_id)
        );

        insertData(
            $pdo,
            'student_category_info',
            getCategoryData($student_id)
        );
		insertData(
    $pdo,
    'student_bank_details',
    getBankDetailsData($student_id)
);

        /*
        |--------------------------------------------------------------------------
        | AUDIT
        |--------------------------------------------------------------------------
        */

        logActivity($pdo, [

            'school_id' => $school_id,
            'user_id' => $_SESSION['user_id'],

            'module' => 'Students',
            'action' => 'CREATE',

            'record_id' => $student_id,

            'message' => 'Student added',

            'new_data' => [

                'name' => $studentData['name'],
                'roll_no' => val('roll_no'),
                'class_id' => val('class_id')
            ]
        ]);

        $pdo->commit();

        redirectWithSuccess(
            'index.php',
            'Student Added Successfully'
        );

    } catch (Exception $e) {

        $pdo->rollBack();

        redirectWithError(
            'add.php',
            $e->getMessage()
        );
    }
}

/*
|--------------------------------------------------------------------------
| EDIT STUDENT
|--------------------------------------------------------------------------
*/

function editStudent()
{
    global $pdo, $school_id, $session_id;

    $student_id = val('student_id');

    try {

        $stmt = $pdo->prepare("
            SELECT *
            FROM students
            WHERE id = ?
            AND school_id = ?
        ");

        $stmt->execute([
            $student_id,
            $school_id
        ]);

        $oldStudent = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$oldStudent) {

            redirectWithError(
                'index.php',
                'Student not found'
            );
        }

        $imageValidation = validateImage($_FILES['image'] ?? []);

        if ($imageValidation !== true) {

            redirectWithError(
                'edit.php?id=' . $student_id,
                $imageValidation
            );
        }

        if (
            checkDuplicateRollNo(
                $pdo,
                $school_id,
                $session_id,
                val('class_id'),
                val('roll_no'),
                $student_id
            )
        ) {

            redirectWithError(
                'edit.php?id=' . $student_id,
                'Roll number already exists'
            );
        }

        $pdo->beginTransaction();

        $photo = uploadImage(
            $_FILES['image'] ?? [],
            $oldStudent['photo']
        );

        /*
        |--------------------------------------------------------------------------
        | UPDATE STUDENTS
        |--------------------------------------------------------------------------
        */

        $studentData = getStudentData($photo);

        $setParts = [];

        foreach (array_keys($studentData) as $column) {

            $setParts[] = "$column = ?";
        }

        $setClause = implode(',', $setParts);

        $sql = "
            UPDATE students
            SET $setClause,
            updated_at = NOW()
            WHERE id = ?
            AND school_id = ?
        ";

        $values = array_values($studentData);

        $values[] = $student_id;
        $values[] = $school_id;

        $updateStmt = $pdo->prepare($sql);

        $updateStmt->execute($values);

        /*
        |--------------------------------------------------------------------------
        | UPDATE CHILD TABLES
        |--------------------------------------------------------------------------
        */

        updateData(
            $pdo,
            'student_sessions',
            getStudentSessionData($student_id),
            $student_id
        );

        updateData(
            $pdo,
            'student_parents',
            getParentData($student_id),
            $student_id
        );

        updateData(
            $pdo,
            'student_address',
            getAddressData($student_id),
            $student_id
        );

        updateData(
            $pdo,
            'student_documents',
            getDocumentData($student_id),
            $student_id
        );

        updateData(
            $pdo,
            'student_academic_info',
            getAcademicData($student_id),
            $student_id
        );

        updateData(
            $pdo,
            'student_category_info',
            getCategoryData($student_id),
            $student_id
        );
		updateData(
    $pdo,
    'student_bank_details',
    getBankDetailsData($student_id),
    $student_id
);

        $pdo->commit();

        redirectWithSuccess(
            'index.php',
            'Student Updated Successfully'
        );

    } catch (Exception $e) {

        $pdo->rollBack();

        redirectWithError(
            'edit.php?id=' . $student_id,
            $e->getMessage()
        );
    }
}

/*
|--------------------------------------------------------------------------
| DELETE STUDENT
|--------------------------------------------------------------------------
*/

function deleteStudent()
{
    global $pdo, $school_id;

    $student_id = (int) ($_GET['id'] ?? 0);

    if (!$student_id) {

        redirectWithError(
            'index.php',
            'Invalid Student ID'
        );
    }

    try {

        $pdo->beginTransaction();

        $tables = [

            'student_sessions',
            'student_parents',
            'student_address',
            'student_documents',
            'student_academic_info',
            'student_category_info'
        ];

        foreach ($tables as $table) {

            $stmt = $pdo->prepare("
                DELETE FROM $table
                WHERE student_id = ?
                AND school_id = ?
            ");

            $stmt->execute([
                $student_id,
                $school_id
            ]);
        }

        $stmt = $pdo->prepare("
            DELETE FROM students
            WHERE id = ?
            AND school_id = ?
        ");

        $stmt->execute([
            $student_id,
            $school_id
        ]);

        $pdo->commit();

        redirectWithSuccess(
            'index.php',
            'Student Deleted Successfully'
        );

    } catch (Exception $e) {

        $pdo->rollBack();

        redirectWithError(
            'index.php',
            $e->getMessage()
        );
    }
}