File "StudentApiController.php"

Full Path: /home/trinadezambia/public_html/admin_panel/app/Http/Controllers/Api/StudentApiController.php
File size: 93.73 KB
MIME-type: text/x-php
Charset: utf-8

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\TimetableCollection;
use App\Http\Resources\UserDataResource;
use App\Models\AssignmentSubmission;
use App\Models\OnlineExamCommon;
use App\Models\School;
use App\Models\Students;
use App\Models\User;
use Carbon\Carbon;
use App\Models\DiaryCategory;
use App\Repositories\Announcement\AnnouncementInterface;
use App\Repositories\Assignment\AssignmentInterface;
use App\Repositories\AssignmentSubmission\AssignmentSubmissionInterface;
use App\Repositories\Attendance\AttendanceInterface;
use App\Repositories\DiaryStudent\DiaryStudentInterface;
use App\Repositories\Exam\ExamInterface;
use App\Repositories\ExamResult\ExamResultInterface;
use App\Repositories\Files\FilesInterface;
use App\Repositories\Holiday\HolidayInterface;
use App\Repositories\Lessons\LessonsInterface;
use App\Repositories\OnlineExam\OnlineExamInterface;
use App\Repositories\OnlineExamCommon\OnlineExamCommonInterface;
use App\Repositories\OnlineExamQuestionChoice\OnlineExamQuestionChoiceInterface;
use App\Repositories\OnlineExamStudentAnswer\OnlineExamStudentAnswerInterface;
use App\Repositories\SessionYear\SessionYearInterface;
use App\Repositories\Sliders\SlidersInterface;
use App\Repositories\Student\StudentInterface;
use App\Repositories\StudentOnlineExamStatus\StudentOnlineExamStatusInterface;
use App\Repositories\StudentSubject\StudentSubjectInterface;
use App\Repositories\SubjectTeacher\SubjectTeacherInterface;
use App\Repositories\Timetable\TimetableInterface;
use App\Repositories\Topics\TopicsInterface;
use App\Repositories\User\UserInterface;
use App\Models\OnlineExamQuestionOption;
use App\Rules\MaxFileSize;
use App\Services\CachingService;
use App\Services\FeaturesService;
use App\Services\FcmTokenService;
use App\Services\ResponseService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use JetBrains\PhpStorm\NoReturn;
use App\Traits\DateFormatTrait;
use Throwable;


class StudentApiController extends Controller
{
    use DateFormatTrait;
    private StudentInterface $student;
    private UserInterface $user;
    private AssignmentInterface $assignment;
    private AssignmentSubmissionInterface $assignmentSubmission;
    private FilesInterface $files;
    private CachingService $cache;
    private StudentSubjectInterface $studentSubject;
    private TimetableInterface $timetable;
    private ExamInterface $exam;
    private ExamResultInterface $examResult;
    private LessonsInterface $lesson;
    private TopicsInterface $lessonTopic;
    private AttendanceInterface $attendance;
    private HolidayInterface $holiday;
    private SessionYearInterface $sessionYear;
    private SubjectTeacherInterface $subjectTeacher;
    private AnnouncementInterface $announcement;
    private OnlineExamInterface $onlineExam;
    private StudentOnlineExamStatusInterface $studentOnlineExamStatus;
    private OnlineExamQuestionChoiceInterface $onlineExamQuestionChoice;
    private OnlineExamStudentAnswerInterface $onlineExamStudentAnswer;
    private OnlineExamCommonInterface $onlineExamCommon;
    private SlidersInterface $sliders;
    private FeaturesService $featureService;
    private DiaryStudentInterface $diaryStudent;

    public function __construct(StudentInterface $student, UserInterface $user, AssignmentInterface $assignment, AssignmentSubmissionInterface $assignmentSubmission, FilesInterface $files, CachingService $cache, StudentSubjectInterface $studentSubject, TimetableInterface $timetable, ExamInterface $exam, ExamResultInterface $examResult, LessonsInterface $lesson, TopicsInterface $lessonTopic, AttendanceInterface $attendance, HolidayInterface $holiday, SessionYearInterface $sessionYear, SubjectTeacherInterface $subjectTeacher, AnnouncementInterface $announcement, OnlineExamInterface $onlineExam, StudentOnlineExamStatusInterface $studentOnlineExamStatus, OnlineExamQuestionChoiceInterface $onlineExamQuestionChoice, OnlineExamStudentAnswerInterface $onlineExamStudentAnswer, SlidersInterface $sliders, FeaturesService $featuresService, OnlineExamCommonInterface $onlineExamCommon, DiaryStudentInterface $diaryStudent)
    {
        $this->student = $student;
        $this->user = $user;
        $this->assignment = $assignment;
        $this->assignmentSubmission = $assignmentSubmission;
        $this->files = $files;
        $this->cache = $cache;
        $this->studentSubject = $studentSubject;
        $this->timetable = $timetable;
        $this->exam = $exam;
        $this->examResult = $examResult;
        $this->lesson = $lesson;
        $this->lessonTopic = $lessonTopic;
        $this->attendance = $attendance;
        $this->holiday = $holiday;
        $this->sessionYear = $sessionYear;
        $this->subjectTeacher = $subjectTeacher;
        $this->announcement = $announcement;
        $this->onlineExam = $onlineExam;
        $this->studentOnlineExamStatus = $studentOnlineExamStatus;
        $this->onlineExamQuestionChoice = $onlineExamQuestionChoice;
        $this->onlineExamStudentAnswer = $onlineExamStudentAnswer;
        $this->sliders = $sliders;
        $this->featureService = $featuresService;
        $this->onlineExamCommon = $onlineExamCommon;
        $this->diaryStudent = $diaryStudent;
    }


    #[NoReturn] public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'gr_number' => 'required',
            'password' => 'required',
            'school_code' => 'required|alpha_num',
        ], [
            'gr_number.required' => 'The GR number is required.',
            'password.required' => 'The password is required.',
            'school_code.required' => 'The school code is required.',
            'school_code.alpha_num' => 'The school code must contain only letters and numbers.',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }

        $school = School::on('mysql')->where('code', $request->school_code)->first();

        if ($school) {
            DB::setDefaultConnection('school');
            Config::set('database.connections.school.database', $school->database_name);
            DB::purge('school');
            DB::connection('school')->reconnect();
            DB::setDefaultConnection('school');
        } else {
            ResponseService::errorResponse('Invalid Login Credentials', null, config('constants.RESPONSE_CODE.INVALID_LOGIN'));
        }

        $user = User::withTrashed()
            ->where('email', $request->gr_number)
            ->has('student')
            ->first();

        $seesionYear = $this->sessionYear->builder()->where('default', 1)->first();

        if ($user && Hash::check($request->password, $user->password)) {
            if ($user->trashed()) {
                // User is soft-deleted, handle accordingly
                ResponseService::errorResponse(trans('your_account_has_been_deactivated_please_contact_admin'), null, config('constants.RESPONSE_CODE.INACTIVATED_USER'));
            }
            $student = Students::where('user_id', $user->id)->first();
            if ($student->session_year_id != $seesionYear->id) {
                ResponseService::errorResponse('Invalid Login Credentials', null, config('constants.RESPONSE_CODE.INVALID_LOGIN'));
            }
        }

        if (Auth::attempt(['email' => $request->gr_number, 'password' => $request->password, 'status' => 1])) {
            //Here Email Field is referenced as a GR Number for Student
            $auth = Auth::user()->load('student');

            if (!$auth->student) {
                // logout
                Auth::logout();
                ResponseService::errorResponse('Invalid Login Credentials', null, config('constants.RESPONSE_CODE.INVALID_LOGIN'));
            }

            // Check role
            // $auth->assignRole('Student');
            // if (!$auth->hasRole('Student')) {
            //     ResponseService::errorResponse('Invalid Login Credentials', null, config('constants.RESPONSE_CODE.INVALID_LOGIN'));
            // }
            // Check school status is activated or not
            if ($auth->school->status == 0) {
                ResponseService::errorResponse('Your account has been deactivated', null, config('constants.RESPONSE_CODE.INVALID_LOGIN'));
            }
            $token = $auth->createToken($auth->first_name)->plainTextToken;
            $user = $auth->load([
                'student.class_section' => function ($q) {
                    $q->with('section', 'class', 'class.shift', 'medium');
                },
                'student.guardian',
                'school',
                'fcmTokens'
            ]);

            // child.user', 'child.class_section.class', 'child.class_section.section', 'child.class_section.medium', 'child.user.school
            // $user = $auth->load(['student.guardian.child' => function($q) {
            //     $q->with('user.school','class_section.class','class_section.section', 'class_section.medium');
            // }]);

            // Store FCM tokens using FcmTokenService
            $fcmTokenService = app(FcmTokenService::class);
            if ($request->fcm_id) {
                $fcmTokenService->storeOrUpdateToken(
                    $auth,
                    $request->fcm_id,
                    $request->device_type ?? 'android',
                    $request->device_id ?? null
                );
            }
            if ($request->web_fcm) {
                $fcmTokenService->storeOrUpdateToken(
                    $auth,
                    $request->web_fcm,
                    'web',
                    $request->device_id ?? null
                );
            }

            $extraData = [
                'fcm_id' => $request->fcm_id,
                'web_fcm' => $request->web_fcm,
                'device_type' => $request->device_type,
            ];
            $user->extra_data = $extraData;

            ResponseService::successResponse('User logged-in!', new UserDataResource($user), ['error' => false, 'token' => $token]);
        }
        ResponseService::errorResponse('Invalid Login Credentials', null, config('constants.RESPONSE_CODE.INVALID_LOGIN'));
    }

    public function forgotPassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'gr_no' => 'required',
            'dob' => 'required|date',
            'school_code' => 'required'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $schoolCode = $request->school_code;
            if ($schoolCode) {
                $school = School::on('mysql')->where('code', $schoolCode)->first();

                if ($school) {
                    DB::setDefaultConnection('school');
                    Config::set('database.connections.school.database', $school->database_name);
                    DB::purge('school');
                    DB::connection('school')->reconnect();
                    DB::setDefaultConnection('school');

                    $user = $this->user->builder()->whereHas('student', function ($query) use ($request) {
                        $query->where('admission_no', $request->gr_no);
                    })->whereDate('dob', '=', date('Y-m-d', strtotime($request->dob)))->first();
                    //  dd($user);
                    if ($user) {
                        /*NOTE : Revert this if needed */
                        //$this->user->update($user->id, ['reset_request' => 1,'school_id' => $user->school_id]);
                        $this->user->update($user->id, ['reset_request' => 1, 'school_id' => $user->school_id]);
                        ResponseService::successResponse("Request Send Successfully");
                    } else {
                        ResponseService::errorResponse("Invalid user Details", null, config('constants.RESPONSE_CODE.INVALID_USER_DETAILS'));
                    }
                } else {
                    return response()->json(['error' => true, 'message' => 'Invalid school code'], 200);
                }
            } else {
                return response()->json(['error' => true, 'message' => 'Unauthenticated'], 200);
            }
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function classSubjects(Request $request)
    {
        try {
            $user = $request->user();
            $subjects = $user->student->currentSemesterClassSubjects();
            ResponseService::successResponse('Class Subject Fetched Successfully.', $subjects);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function subjects(Request $request)
    {
        try {
            $user = $request->user();
            $subjects = $user->student->currentSemesterSubjects();
            ResponseService::successResponse('Student Subject Fetched Successfully.', $subjects);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function selectSubjects(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'subject_group.*.id' => 'required',
            'subject_group.*.class_subject_id' => 'required|array',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            DB::beginTransaction();
            $sessionYear = $this->cache->getDefaultSessionYear(); // Default Session Year From Cache
            $student = $request->user()->student; // Logged in Student Details
            $classSection = $student->class_section; // Class Section Data
            $studentSubject = array();

            // Loop to Subject Group
            foreach ($request->subject_group as $subjectGroup) {
                // Loop to Subject's ID
                foreach ($subjectGroup['class_subject_id'] as $classSubjectId) {
                    // Create Two Dimensional Student Subject Array
                    $studentSubject[] = array(
                        'student_id' => $student->user_id,
                        'class_subject_id' => $classSubjectId,
                        'class_section_id' => $classSection->id,
                        'session_year_id' => $sessionYear->id,
                    );
                }
            }

            // Update OR Create Data
            $this->studentSubject->upsert($studentSubject, ['student_id', 'class_subject_id', 'class_section_id', 'session_year_id'], ['student_id', 'class_subject_id', 'class_section_id', 'session_year_id',]);
            DB::commit();
            ResponseService::successResponse("Subject Selected Successfully");
        } catch (Throwable $e) {
            DB::rollBack();
            ResponseService::logErrorResponse($e, "StudentApiController :- selectSubject Method");
            ResponseService::errorResponse();
        }
    }

    public function getGuardianDetails(Request $request)
    {
        try {
            $student = $request->user()->student->load(['guardian']);
            $data = array(
                'guardian' => (!empty($student->guardian)) ? $student->guardian : (object) []
            );
            ResponseService::successResponse("Guardian Details Fetched Successfully", $data);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getTimetable(Request $request)
    {
        try {
            $student = $request->user()->student;
            $studentSubjects = $student->currentSemesterSubjects();

            $core_subjects = $studentSubjects["core_subject"]->pluck('id')->toArray();

            $elective_subjects = $studentSubjects["elective_subject"] ?? [];

            if ($elective_subjects) {
                $elective_subjects = $elective_subjects->pluck('class_subject.subject.id')->toArray();
            }

            $subjectIds = array_merge($core_subjects, $elective_subjects);

            $timetable = $this->timetable->builder()
                ->where('class_section_id', $student->class_section_id)
                ->where(function ($query) use ($subjectIds) {
                    $query->whereIn('subject_id', $subjectIds)
                        ->orWhereNull('subject_id');
                })
                ->where(function ($query) use ($subjectIds) {
                    $query->whereHas('subject_teacher', function ($q) use ($subjectIds) {
                        $q->whereIn('subject_id', $subjectIds);
                    })
                        ->orWhereDoesntHave('subject_teacher');
                })
                ->with([
                    'subject_teacher.subject:id,name,type,code,bg_color,image',
                    'subject_teacher.teacher:id,first_name,last_name'
                ])
                ->orderBy('start_time')
                ->get();

            ResponseService::successResponse("Timetable Fetched Successfully", new TimetableCollection($timetable));
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }


    public function getLessons(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'lesson_id' => 'nullable|numeric',
            'class_subject_id' => 'required',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = $request->user()->student;

            $lessonQuery = $this->lesson->builder()->whereHas('lesson_commons', function ($q) use ($request, $student) {
                $q->whereHas('syllabus.class_subject', function ($q) use ($request) {
                    $q->where('id', $request->class_subject_id);
                })->where('class_section_id', $student->class_section_id);
            })
                ->with([
                    'topic' => function ($q) {
                        $q->orderBy('id', 'DESC');
                    },
                    'file'
                ]);
            if ($request->lesson_id) {
                $lessonQuery->where('id', $request->lesson_id);
            }

            $lessonData = $lessonQuery->orderBy('id', 'DESC')->get();

            ResponseService::successResponse("Lessons Fetched Successfully", $lessonData);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getLessonTopics(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'lesson_id' => 'required|numeric',
            'topic_id' => 'nullable|numeric',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $lessonTopicQuery = $this->lessonTopic->builder()->with('lesson.lesson_commons')->where('lesson_id', $request->lesson_id)->with('file');
            if ($request->topic_id) {
                $lessonTopicQuery->where('id', $request->topic_id);
            }
            $lessonTopicData = $lessonTopicQuery->get();
            ResponseService::successResponse("Topics Fetched Successfully", $lessonTopicData);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "StudentApiController :- getLessonTopics Method");
            ResponseService::errorResponse();
        }
    }

    public function getAssignments(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'assignment_id' => 'nullable|numeric',
            'class_subject_id' => 'nullable|numeric',
            'is_submitted' => 'nullable|numeric',
            'search' => 'nullable|string',
            'sort' => 'nullable|string',
        ]);

        if ($validator->fails()) {
            return ResponseService::validationError($validator->errors()->first());
        }

        try {
            /* -------------------------------------------------
             | 1. Resolve student + class + class_section
             -------------------------------------------------*/
            $student = $request->user()->student;

            if (
                !$student ||
                !$student->class_section_id ||
                !$student->class_section ||
                !$student->class_section->class_id
            ) {
                return ResponseService::errorResponse('Invalid student or class context');
            }

            $classSectionId = $student->class_section_id;
            $classId = $student->class_section->class_id;

            /* -------------------------------------------------
             | 2. Resolve allowed class_subject_ids
             -------------------------------------------------*/
            $allowedClassSubjectIds = DB::table('class_subjects')
                ->where('class_id', $classId)
                ->where(function ($q) use ($student) {

                    // Compulsory → always allowed
                    $q->where('type', 'Compulsory')

                        // Elective → only if assigned
                        ->orWhere(function ($q) use ($student) {
                            $q->where('type', 'Elective')
                                ->whereExists(function ($sub) use ($student) {
                                    $sub->select(DB::raw(1))
                                        ->from('student_subjects')
                                        ->whereColumn(
                                            'student_subjects.class_subject_id',
                                            'class_subjects.id'
                                        )
                                        ->where('student_subjects.student_id', $student->user_id);
                                });
                        });
                })
                ->pluck('id');

            /* -------------------------------------------------
             | 3. Base assignment query
             -------------------------------------------------*/
            $data = $this->assignment->builder()
                ->with([
                    'file',
                    'class_subject.subject',
                    'submission' => function ($query) use ($student) {
                        $query->where('student_id', $student->user_id)
                            ->with('file');
                    }
                ])
                ->whereHas('assignment_commons', function ($query) use ($classSectionId, $allowedClassSubjectIds) {
                    $query->where('class_section_id', $classSectionId)
                        ->whereIn('class_subject_id', $allowedClassSubjectIds);
                });

            /* -------------------------------------------------
             | 4. Search
             -------------------------------------------------*/
            if (!empty($request->search)) {
                $search = $request->search;
                $data->where(function ($query) use ($search) {
                    $query->where('name', 'LIKE', "%{$search}%")
                        ->orWhere('instructions', 'LIKE', "%{$search}%")
                        ->orWhereHas('class_subject.subject', function ($q) use ($search) {
                            $q->where('name', 'LIKE', "%{$search}%");
                        });
                });
            }

            /* -------------------------------------------------
             | 5. Filters
             -------------------------------------------------*/
            if ($request->assignment_id) {
                $data->where('id', $request->assignment_id);
            }

            // Optional class_subject filter (still validated server-side)
            if ($request->class_subject_id) {
                $data->whereHas('assignment_commons', function ($q) use ($request, $allowedClassSubjectIds) {
                    $q->where('class_subject_id', $request->class_subject_id)
                        ->whereIn('class_subject_id', $allowedClassSubjectIds);
                });
            }

            // Submission filter
            if (isset($request->is_submitted)) {
                if ((int) $request->is_submitted === 1) {
                    $data->whereHas('submission', function ($q) use ($student) {
                        $q->where('student_id', $student->user_id);
                    });
                } else {
                    $data->whereDoesntHave('submission', function ($q) use ($student) {
                        $q->where('student_id', $student->user_id);
                    });
                }
            }

            /* -------------------------------------------------
             | 6. Sorting
             -------------------------------------------------*/
            switch ($request->sort) {
                case 'assigned_latest':
                    $data->orderBy('created_at', 'desc');
                    break;

                case 'assigned_oldest':
                    $data->orderBy('created_at', 'asc');
                    break;

                case 'due_latest':
                    $data->orderBy('due_date', 'desc');
                    break;

                case 'due_oldest':
                    $data->orderBy('due_date', 'asc');
                    break;

                default:
                    $data->orderBy('id', 'desc');
            }

            /* -------------------------------------------------
             | 7. Response
             -------------------------------------------------*/
            $result = $data->paginate(15);

            ResponseService::successResponse(
                'Assignments Fetched Successfully',
                $result
            );
        } catch (Throwable $e) {
            ResponseService::logErrorResponse(
                $e,
                'Student Api Controller -> getAssignments'
            );
            ResponseService::errorResponse();
        }
    }

    public function submitAssignment(Request $request)
    {
        $file_upload_size_limit = $this->cache->getSystemSettings('file_upload_size_limit');
        $validator = Validator::make($request->all(), [
            'assignment_id' => 'required|numeric',
            'subject_id' => 'nullable|numeric',

            // Either files OR add_url is required
            'files' => 'required_without:add_url|array',
            'files.*' => [
                'mimes:jpeg,png,jpg,gif,svg,webp,pdf,doc,docx,xml',
                'max:' . ($file_upload_size_limit * 1024), // MB → KB
            ],

            'add_url' => 'required_without:files|nullable|url',
        ], [
            'files.required_without' => __('Please upload a file or provide a URL.'),
            'add_url.required_without' => __('Please upload a file or provide a URL.'),
            'files.*.max' => __('The uploaded file must be less than :size MB.', [
                'size' => $file_upload_size_limit,
            ]),
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }

        if (!$this->assignment->builder()->where('id', $request->assignment_id)->exists()) {
            ResponseService::errorResponse("Assignment not found");
        }

        try {
            DB::beginTransaction();
            $assignmentSubmissionData = array();
            $student = $request->user()->student;
            $sessionYear = $this->cache->getDefaultSessionYear();

            $assignment = $this->assignment->builder()->where('id', $request->assignment_id)->first();

            $assignmentSubmissionQuery = $this->assignmentSubmission->builder()->where(['assignment_id' => $assignment->id, 'student_id' => $student->user_id])->first();
            if (empty($assignmentSubmissionQuery)) {
                $assignmentSubmissionData = array(
                    'assignment_id' => $request->assignment_id,
                    'student_id' => $student->user_id,
                    'session_year_id' => $sessionYear->id
                );
            } else if (($assignmentSubmissionQuery->status == 2 && $assignment->resubmission) || $assignmentSubmissionQuery->status == 3) {
                // if assignment submission is rejected and
                // Assignment has resubmission allowed then change the status to resubmitted
                $assignmentSubmissionData = array(
                    'id' => $assignmentSubmissionQuery->id,
                    'status' => 3
                );
                // Check Old Files and Delete it
                if ($assignmentSubmissionQuery->file) {
                    foreach ($assignmentSubmissionQuery->file as $file) {
                        if (Storage::disk('public')->exists($file->getRawOriginal('file_url'))) {
                            Storage::disk('public')->delete($file->getRawOriginal('file_url'));
                        }
                    }
                }
                $assignmentSubmissionQuery->file()->delete();
            } else {
                ResponseService::errorResponse("You already have submitted your assignment.", null, config('constants.RESPONSE_CODE.ASSIGNMENT_ALREADY_SUBMITTED'));
            }
            $assignmentSubmission = $this->assignmentSubmission->updateOrCreate(['id' => $assignmentSubmissionData['id'] ?? null], $assignmentSubmissionData);

            //If File Exists
            if ($request->hasFile('files')) {
                $fileData = array(); // Empty FileData Array
                // Create A File Model Instance
                $assignmentSubmissionModelAssociate = $this->files->model()->modal()->associate($assignmentSubmission); // Get the Association Values of File with Assignment Submission
                foreach ($request->file('files') as $file_upload) {
                    // Create Temp File Data Array
                    $tempFileData = array(
                        'modal_type' => $assignmentSubmissionModelAssociate->modal_type,
                        'modal_id' => $assignmentSubmissionModelAssociate->modal_id,
                        'file_name' => $file_upload->getClientOriginalName(),
                        'type' => 1,
                        'file_url' => $file_upload
                    );
                    $fileData[] = $tempFileData; // Store Temp File Data in Multi-Dimensional File Data Array
                }
                $this->files->createBulk($fileData); // Store File Data
            }

            if ($request->add_url) {
                $urlData = [];
                $urls = is_array($request->add_url) ? $request->add_url : [$request->add_url];

                foreach ($urls as $url) {
                    $urlParts = parse_url($url);
                    $fileName = basename($urlParts['path'] ?? '/');

                    $assignmentSubmissionModelAssociate = $this->files->model()->modal()->associate($assignmentSubmission);

                    $tempUrlData = array(
                        'modal_type' => $assignmentSubmissionModelAssociate->modal_type,
                        'modal_id' => $assignmentSubmissionModelAssociate->modal_id,
                        'file_name' => $fileName,
                        'type' => 4,
                        'file_url' => $url,
                    );

                    $urlData[] = $tempUrlData;
                }

                // Store the URL data
                $this->files->createBulk($urlData);
            }
            $submittedAssignment = $this->assignmentSubmission->builder()->where('id', $assignmentSubmission->id)->with('file')->get();


            DB::commit();
            ResponseService::successResponse("Assignments Submitted Successfully", $submittedAssignment);
        } catch (Throwable $e) {
            DB::rollback();
            ResponseService::logErrorResponse($e, "Student Api Controller -> submitAssignment Method");
            ResponseService::errorResponse();
        }
    }

    public function deleteAssignmentSubmission(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'assignment_submission_id' => 'required|numeric',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            DB::beginTransaction();
            $student = $request->user();
            $assignment_submission = AssignmentSubmission::where('id', $request->assignment_submission_id)->where('student_id', $student->id)->with('file')->first();

            if (!empty($assignment_submission) && $assignment_submission->status == 0) {
                foreach ($assignment_submission->file as $file) {
                    if (Storage::disk('public')->exists($file->file_url)) {
                        Storage::disk('public')->delete($file->file_url);
                    }
                }
                $assignment_submission->file()->delete();
                $assignment_submission->delete();
                DB::commit();
                ResponseService::successResponse("Assignments Deleted Successfully");
            } else {
                ResponseService::errorResponse("You can not delete assignment");
            }
        } catch (Throwable $e) {
            DB::rollBack();
            ResponseService::logErrorResponse($e, "Student Api Controller -> deleteAssignmentSubmission Method");
            ResponseService::errorResponse();
        }
    }

    public function getAttendance(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'month' => 'nullable|numeric',
            'year' => 'nullable|numeric',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = $request->user()->student;
            $sessionYear = $this->cache->getDefaultSessionYear();

            $attendance = $this->attendance->builder()->where(['student_id' => $student->user_id, 'session_year_id' => $sessionYear->id]);
            $holidays = $this->holiday->builder();
            $session_year_data = $this->sessionYear->findById($sessionYear->id);
            if (isset($request->month)) {
                $attendance = $attendance->whereMonth('date', $request->month);
                $holidays = $holidays->whereMonth('date', $request->month);
            }

            if (isset($request->year)) {
                $attendance = $attendance->whereYear('date', $request->year);
                $holidays = $holidays->whereYear('date', $request->year);
            }
            $attendance = $attendance->get();
            $holidays = $holidays->get();


            $data = ['attendance' => $attendance, 'holidays' => $holidays, 'session_year' => $session_year_data];

            ResponseService::successResponse("Attendance Details Fetched Successfully", $data);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "Student Api Controller -> getAttendance Method");
            ResponseService::errorResponse();
        }
    }

    public function getAnnouncements(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'type' => 'nullable|in:subject,noticeboard,class',
            'class_subject_id' => 'required_if:type,subject|numeric'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = $request->user()->student;
            $classSectionId = $student->class_section->id;
            $sessionYear = $this->cache->getDefaultSessionYear();
            if (isset($request->type) && $request->type == "subject") {
                // TODO : There might be some mistake in this code
                $table = $this->subjectTeacher->builder()->where(['class_section_id' => $student->class_section_id, 'class_subject_id' => $request->class_subject_id])->pluck('id');
                if ($table === null) {
                    ResponseService::errorResponse("Invalid Subject ID", null, config('constants.RESPONSE_CODE.INVALID_SUBJECT_ID'));
                }
            }

            $announcementData = $this->announcement->builder()->with('file', 'announcement_class')->where('session_year_id', $sessionYear->id);

            if (isset($request->type) && $request->type == "class") {
                $announcementData = $announcementData->whereHas('announcement_class', function ($query) use ($classSectionId) {
                    $query->where(['class_section_id' => $classSectionId, 'class_subject_id' => null]);
                });
            }

            if (isset($request->type) && $request->type == "subject") {
                $announcementData = $announcementData->whereHas('announcement_class', function ($query) use ($classSectionId, $request) {
                    $query->where(['class_section_id' => $classSectionId, 'class_subject_id' => $request->class_subject_id]);
                });
            }

            $announcementData = $announcementData->orderBy('id', 'desc')->paginate(15);
            ResponseService::successResponse("Announcement Details Fetched Successfully", $announcementData);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "StudentApiController :- getAnnouncements Method");
            ResponseService::errorResponse();
        }
    }

    public function getExamList(Request $request)
    {
        try {
            $studentId = Auth::user()->student->id;
            $studentData = Auth::user()->student;
            $student = $this->student->findById($studentId, ['*'], ['class_section']);
            $classId = $student->class_section->class_id;
            $studentSubjects = $studentData->currentSemesterSubjects();
            $core_subjects = $studentSubjects['core_subject']->pluck('id')->toArray();
            $elective_subjects = $studentSubjects['elective_subject'] ?? [];
            if ($elective_subjects) {
                $elective_subjects = $elective_subjects->pluck('class_subject.subject.id')->toArray();
            }
            $subjectIds = array_merge($core_subjects, $elective_subjects);
            $currentSessionYear = $this->cache->getDefaultSessionYear();
            $exam = $this->exam->builder()
                ->where([
                    'class_id' => $classId,
                    'session_year_id' => $currentSessionYear->id
                ])
                ->whereHas('timetable', function ($query) use ($subjectIds) {
                    $query->owner()
                        ->whereHas('class_subject', function ($q) use ($subjectIds) {
                            $q->whereIn('subject_id', $subjectIds); // filter by actual subject
                        });
                })
                ->with([
                    'timetable' => function ($query) use ($subjectIds) {
                        $query->owner()
                            ->whereHas('class_subject', function ($q) use ($subjectIds) {
                                $q->whereIn('subject_id', $subjectIds); // filter by actual subject
                            })
                            ->selectRaw('*, SUM(total_marks) as total_marks')
                            ->groupBy('exam_id');
                    }
                ])
                ->orderBy('id', 'DESC')
                ->get();

            $exam_data = array();
            foreach ($exam as $data) {
                if (isset($request->status) && $request->status != $data->exam_status && $request->status != 3) {
                    continue;
                }

                $exam_data[] = [
                    'id' => $data->id,
                    'name' => $data->name,
                    'description' => $data->description,
                    'publish' => $data->publish,
                    'session_year' => $data->session_year->name,
                    'exam_starting_date' => $data->start_date,
                    'exam_ending_date' => $data->end_date,
                    'exam_status' => $data->exam_status,
                ];
            }


            ResponseService::successResponse("", $exam_data);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "StudentApiController :- getExamList Method");
            ResponseService::errorResponse();
        }
    }

    public function getExamDetails(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'exam_id' => 'required|nullable'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $studentData = Auth::user()->student;
            $classId = $studentData->class_section->class_id;
            $studentSubjects = $studentData->currentSemesterSubjects();
            $core_subjects = $studentSubjects['core_subject']->pluck('id')->toArray();
            $elective_subjects = $studentSubjects['elective_subject'] ?? [];
            if ($elective_subjects) {
                $elective_subjects = $elective_subjects->pluck('class_subject.subject.id')->toArray();
            }
            $subjectIds = array_merge($core_subjects, $elective_subjects);

            // Fetch exam and filter timetable by student's subjects
            $examData = $this->exam->builder()
                ->where([
                    'id' => $request->exam_id,
                    'class_id' => $classId
                ])
                ->with([
                    'timetable' => function ($query) use ($subjectIds) {
                        $query->owner()
                            ->with(['class_subject.subject'])
                            ->whereHas('class_subject', function ($q) use ($subjectIds) {
                                $q->whereIn('subject_id', $subjectIds); // filter by actual subject
                            })
                            ->orderBy('date');
                    }
                ])
                ->first();


            if (!$examData) {
                ResponseService::successResponse("", []);
            }

            foreach ($examData->timetable as $data) {
                $exam_data[] = array(
                    'exam_timetable_id' => $data->id,
                    'total_marks' => $data->total_marks,
                    'passing_marks' => $data->passing_marks,
                    'date' => $data->date,
                    'starting_time' => $data->start_time,
                    'ending_time' => $data->end_time,
                    'subject' => array(
                        'id' => $data->class_subject->subject->id,
                        'class_subject_id' => $data->class_subject_id,
                        'name' => $data->class_subject->subject->name,
                        'bg_color' => $data->class_subject->subject->bg_color,
                        'image' => $data->class_subject->subject->image,
                        'type' => $data->class_subject->subject->type,
                    )
                );
            }
            ResponseService::successResponse("", $exam_data ?? []);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "StudentApiController :- getExamDetails Method");
            ResponseService::errorResponse();
        }
    }

    public function getExamMarks(Request $request)
    {
        try {
            $studentData = Auth::user()->student->load('class_section.class:id,name,shift_id', 'class_section.class.shift:id,name', 'class_section.section:id,name', 'class_section.medium:id,name');

            // Exam Result Data
            $examResultDB = $this->examResult->builder()->with([
                'user' => function ($q) {
                    $q->select('id', 'first_name', 'last_name')->with('student:id,user_id,roll_number');
                },
                'exam.timetable:id,exam_id,start_time,end_time',
                'session_year',
                'exam.marks' => function ($q) use ($studentData) {
                    $q->where('student_id', $studentData->user_id)
                        ->with([
                            'class_subject' => function ($q) {
                                $q->withTrashed()->with([
                                    'subject' => function ($q) {
                                        $q->withTrashed();
                                    }
                                ]);
                            }
                        ]);
                }
            ])->where('student_id', $studentData->user_id);

            if ($request->result_id) {
                $examResultDB = $examResultDB->where('id', $request->result_id);
            }

            if ($request->session_year_id) {
                $examResultDB = $examResultDB->where('session_year_id', $request->session_year_id);
            }

            $examResultDB = $examResultDB->get();


            // Check that Exam Result DB is not empty
            if (count($examResultDB)) {
                foreach ($examResultDB as $examResultData) {
                    $exam_result = array(
                        'result_id' => $examResultData->id,
                        'exam_id' => $examResultData->exam_id,
                        'exam_name' => $examResultData->exam->name,
                        'class_name' => $studentData->class_section->full_name,
                        'student_name' => $examResultData->user->full_name,
                        'exam_date' => $examResultData->exam->start_date,
                        'total_marks' => $examResultData->total_marks,
                        'obtained_marks' => $examResultData->obtained_marks,
                        'percentage' => $examResultData->percentage,
                        'grade' => $examResultData->grade,
                        'session_year' => $examResultData->session_year->name,
                    );
                    $exam_marks = array();
                    foreach ($examResultData->exam->marks as $marks) {
                        $exam_marks[] = array(
                            'marks_id' => $marks->id,
                            'subject_name' => $marks->class_subject->subject->name,
                            'subject_type' => $marks->class_subject->subject->type,
                            'total_marks' => $marks->timetable->total_marks,
                            'passing_marks' => $marks->timetable->passing_marks,
                            'obtained_marks' => $marks->obtained_marks,
                            'teacher_review' => $marks->teacher_review,
                            'grade' => $marks->grade,
                        );
                    }
                    $data[] = array(
                        'result' => $exam_result,
                        'exam_marks' => $exam_marks,
                    );
                }
                ResponseService::successResponse("Exam Result Fetched Successfully", $data ?? null);
            } else {
                ResponseService::successResponse("Exam Result Fetched Successfully", []);
            }
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getProfileDetails()
    {
        try {
            $studentData = Auth::user()->load([
                'student' => function ($query) {
                    $query->with([
                        'class_section' => function ($query) {
                            $query->with('section', 'class', 'medium', 'class.shift', 'class.stream');
                        }
                    ], 'guardian');
                },
                'extra_student_details.form_field',
                'school'
            ]);

            $extraDetails = $studentData->extra_student_details->map(function ($item) {
                $field = $item->form_field;
                $value = $item->data;

                if ($field) {
                    // Dropdown or Radio: replace numeric/index key with label
                    if (in_array($field->type, ['dropdown'])) {
                        $options = $field->default_values ?? [];
                        $value = $options[$value] ?? $value;
                    }

                    // Checkbox: decode JSON array, keep valid options
                    if ($field->type === 'checkbox') {
                        $selected = json_decode($value, true) ?: [];
                        $options = $field->default_values ?? [];
                        $value = json_encode(array_values(array_intersect($selected, $options)));
                    }
                }

                return [
                    'id' => $item->id,
                    'user_id' => $item->user_id,
                    'form_field_id' => $item->form_field_id,
                    'data' => $value,
                    'school_id' => $item->school_id,
                    'created_at' => $item->created_at,
                    'updated_at' => $item->updated_at,
                    'deleted_at' => $item->deleted_at,
                    'file_url' => $item->file_url ?? null,
                    'form_field' => $field ? [
                        'id' => $field->id,
                        'name' => $field->name,
                        'type' => $field->type,
                        'is_required' => $field->is_required,
                        'default_values' => $field->default_values,
                        'school_id' => $field->school_id,
                        'user_type' => $field->user_type,
                        'rank' => $field->rank,
                        'display_on_id' => $field->display_on_id,
                        'created_at' => $field->created_at,
                        'updated_at' => $field->updated_at,
                        'deleted_at' => $field->deleted_at,
                    ] : null,
                ];
            });

            $data = array(
                'id' => $studentData->id,
                'first_name' => $studentData->first_name,
                'last_name' => $studentData->last_name,
                'mobile' => $studentData->mobile,
                'roll_number' => $studentData->student->roll_number,
                'admission_no' => $studentData->student->admission_no,
                'admission_date' => $studentData->student->admission_date,
                'gender' => $studentData->gender,
                'image' => $studentData->image,
                'dob' => $studentData->dob,
                'current_address' => $studentData->current_address,
                'permanent_address' => $studentData->permanent_address,
                'occupation' => $studentData->occupation,
                'status' => $studentData->status,
                'fcm_id' => $studentData->fcm_id,
                'school_id' => $studentData->school_id,
                'session_year_id' => $studentData->student->session_year_id,
                'email_verified_at' => $studentData->email_verified_at,
                'created_at' => $studentData->created_at,
                'updated_at' => $studentData->updated_at,
                'class_section' => $studentData->student->class_section,
                'guardian' => $studentData->student->guardian,
                'extra_details' => $extraDetails,
                'school' => $studentData->school,
            );

            ResponseService::successResponse('Data Fetched Successfully', $data);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getSessionYear()
    {
        try {
            $sessionYear = $this->cache->getDefaultSessionYear();
            ResponseService::successResponse("Session Year Fetched Successfully", $sessionYear);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }


    public function getOnlineExamList(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'class_subject_id' => 'nullable|numeric'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;
            $classSectionId = $student->class_section->id;
            $sessionYear = $this->cache->getDefaultSessionYear();

            $classSubjectId = [];
            if ($request->class_subject_id) {
                $classSubjectId[] = $request->class_subject_id;
            } else {
                $studentSubjects = $student->currentSemesterSubjects();

                $coreSubject = $studentSubjects['core_subject']->toArray();
                $electiveSubject = [];
                if (isset($studentSubjects['elective_subject'])) {
                    $electiveSubject = is_array($studentSubjects['elective_subject'])
                        ? $studentSubjects['elective_subject']
                        : $studentSubjects['elective_subject']->toArray();
                }

                $classSubjectId = collect($coreSubject)->pluck('class_subject_id')->toArray();
                $elective_subject_ids = collect($electiveSubject)->pluck('class_subject_id')->toArray();
                $classSubjectId = array_merge($classSubjectId, $elective_subject_ids);
            }

            if (env('DEMO_MODE')) {
                $check_student_status = $this->studentOnlineExamStatus->builder()->where('student_id', $student->user_id);
                if ($check_student_status->count()) {
                    $status_id = $check_student_status->pluck('id');
                    $this->studentOnlineExamStatus->builder()->whereIn('id', $status_id)->delete();
                }

                $check_student_answers = $this->onlineExamStudentAnswer->builder()->where('student_id', $student->user_id);
                if ($check_student_answers->count()) {
                    $status_id = $check_student_answers->pluck('id');
                    $this->onlineExamStudentAnswer->builder()->whereIn('id', $status_id)->delete();
                }
            }


            $onlineExamData = $this->onlineExam->builder()
                ->whereHas('online_exam_commons', function ($query) use ($student) {
                    $query->where('class_section_id', $student->class_section_id);
                })
                ->where(['session_year_id' => $sessionYear->id])
                ->where('end_date', '>=', now())
                ->has('question_choice')
                ->with('class_subject', 'question_choice:id,online_exam_id,marks')
                ->whereDoesntHave('student_attempt', function ($q) use ($student) {
                    $q->where('student_id', $student->user_id);
                })
                ->when($classSubjectId, function ($query, $classSubjectId) {
                    return $query->whereIn('class_subject_id', $classSubjectId);
                })
                ->orderBy('start_date', 'desc')
                ->paginate(15);

            ResponseService::successResponse('Data Fetched Successfully', $onlineExamData);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getOnlineExamQuestions(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'exam_id' => 'required',
            'exam_key' => 'required',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;
            // Checks Student Exam Status
            if (
                $this->studentOnlineExamStatus->builder()
                ->where(['online_exam_id' => $request->exam_id, 'student_id' => $student->user_id])
                ->exists()
            ) {
                ResponseService::errorResponse('Student already attempted exam', null, config('constants.RESPONSE_CODE.STUDENT_ALREADY_ATTEMPTED_EXAM'));
            }

            $onlineExamCommon = OnlineExamCommon::with(['online_exam'])
                ->where('online_exam_id', $request->exam_id)
                ->first();

            if (!$onlineExamCommon) {
                return ResponseService::errorResponse("Exam configuration not found");
            }

            // Check if the associated online_exam exists and matches request parameters
            $onlineExam = $onlineExamCommon->online_exam;

            if (
                !$onlineExam ||
                $onlineExam->id != $request->exam_id ||
                $onlineExam->exam_key != $request->exam_key
            ) {
                return ResponseService::errorResponse("Invalid Exam Key");
            }

            // Check if the exam has started
            $currentDateTime = now(); // Get the current date and time
            if ($currentDateTime < $onlineExam->start_date_iso) {
                return ResponseService::errorResponse("Exam not started yet");
            }

            // Add Student Status Entry
            $this->studentOnlineExamStatus->create([
                'student_id' => $student->user_id,
                'online_exam_id' => $request->exam_id,
                'status' => 1,
            ]);

            $onlineExamQuestionChoice = $this->onlineExamQuestionChoice->builder();

            // Get Total Questions
            $totalQuestions = $onlineExamQuestionChoice->where('online_exam_id', $request->exam_id)->count();

            // Get Questions Data
            $examQuestionData = $onlineExamQuestionChoice->where('online_exam_id', $request->exam_id)->with('questions')->get();
            $totalMarks = 0;
            $questionData = [];
            foreach ($examQuestionData as $examQuestion) {
                $totalMarks += $examQuestion->marks;

                // Make Options Array
                $optionData = $examQuestion->questions->options->map(function ($optionsData) {
                    return [
                        'id' => $optionsData->id,
                        'option' => htmlspecialchars_decode($optionsData->option),
                        //'is_answer' => $optionsData->is_answer == 1 ? 1 : 0
                    ];
                });


                // Make Question Array Data
                $questionData[] = [
                    'id' => $examQuestion->id,
                    'question' => htmlspecialchars_decode($examQuestion->questions->question),
                    'options' => $optionData,
                    'marks' => $examQuestion->marks,
                    'image' => $examQuestion->questions->image_url,
                    'note' => $examQuestion->questions->note,
                ];
            }
            ResponseService::successResponse('Data Fetched Successfully', $questionData, [
                'total_questions' => $totalQuestions,
                'total_marks' => $totalMarks
            ]);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function submitOnlineExamAnswers(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'online_exam_id' => 'required|numeric',
            'answers_data' => 'nullable|array',
            //'answers_data.*.question_id'    => 'required|numeric',
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;

            DB::beginTransaction();
            // Check Online Exam Exists or not
            //$onlineExamData = $this->onlineExam->findById($request->online_exam_id);
            //if (!$onlineExamData) {
            //ResponseService::errorResponse('Invalid online exam id');
            //}

            // Clean existing answers for fresh submission
            $this->onlineExamStudentAnswer->builder()->where(['student_id' => $student->user_id, 'online_exam_id' => $request->online_exam_id])->delete();
            $answers = [];
            foreach ($request->answers_data ?? [] as $answerData) {

                // checks the question exists with provided exam id
                $questionChoice = $this->onlineExamQuestionChoice->findById($answerData['question_id']);
                if (!$questionChoice || $questionChoice->online_exam_id != $request->online_exam_id) {
                    ResponseService::errorResponse('Invalid question id');
                }
                // Remove duplicates from submitted options for this question
                $uniqueOptionIds = array_unique($answerData['option_id']);

                foreach ($uniqueOptionIds as $optionId) {
                    // add the data of answers
                    $onlineExamQuestionOption = OnlineExamQuestionOption::find($optionId);
                    $answers[] = [
                        'student_id' => $student->user_id,
                        'online_exam_id' => $request->online_exam_id,
                        'question_id' => $answerData['question_id'],
                        'option_id' => $optionId,
                        'true_answer' => $onlineExamQuestionOption->is_answer == 1 ? 1 : 0,
                        'question_marks' => $questionChoice->marks,
                        'submitted_date' => now()->toDateString(),
                    ];
                }
            }

            // Debug: Log what we're about to store
            \Log::info('About to store answers:', [
                'exam_id' => $request->online_exam_id,
                'student_id' => $student->user_id,
                'answers_count' => count($answers),
                'answers' => $answers
            ]);
            if (count($answers) > 0) {
                $this->onlineExamStudentAnswer->createBulk($answers);
            }
            // Update student exam status
            $this->studentOnlineExamStatus->updateOrCreate(
                ['student_id' => $student->user_id, 'online_exam_id' => $request->online_exam_id],
                ['status' => 2]
            );
            DB::commit();
            ResponseService::successResponse('Data Stored Successfully');
        } catch (Throwable $e) {
            DB::rollback();
            ResponseService::logErrorResponse($e, "StudentApiController submitOnlineExamAnswers Method");
            ResponseService::errorResponse();
        }
    }

    public function getOnlineExamResultList(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'class_subject_id' => 'nullable|numeric'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;

            $classSectionId = $student->class_section_id;

            if ($request->session_year_id) {
                $sessionYear = $request->session_year_id;
            } else {
                $sessionYear = $this->cache->getDefaultSessionYear();
                $sessionYear = $sessionYear->id;
            }

            $classSubjectId = [];

            if ($request->class_subject_id) {
                $classSubjectId[] = $request->class_subject_id;
            } else {
                $studentSubjects = $student->currentSemesterSubjects();

                $coreSubject = $studentSubjects['core_subject']->toArray();
                $electiveSubject = [];
                if (isset($studentSubjects['elective_subject'])) {
                    $electiveSubject = is_array($studentSubjects['elective_subject'])
                        ? $studentSubjects['elective_subject']
                        : $studentSubjects['elective_subject']->toArray();
                }

                $classSubjectId = collect($coreSubject)->pluck('class_subject_id')->toArray();
                $elective_subject_ids = collect($electiveSubject)->pluck('class_subject_id')->toArray();
                $classSubjectId = array_merge($classSubjectId, $elective_subject_ids);
            }

            // Get Online Exam Data Where Logged in Student have attempted data and Relation Data with Question Choice , Student's answer with user submitted question with question and its option
            $query = $this->onlineExam->builder()
                ->when($request->class_subject_id, function ($query) use ($request, $classSectionId, $classSubjectId) {
                    $query->whereHas('online_exam_commons', function ($q) use ($classSectionId, $classSubjectId) {
                        $q->whereIn('class_subject_id', $classSubjectId)
                            ->where('class_section_id', $classSectionId);
                    });
                })
                ->where(['session_year_id' => $sessionYear])
                ->whereHas('student_attempt', function ($q) use ($student) {
                    $q->where('student_id', $student->user_id)
                        ->where('status', 2);
                })
                ->with('student_attempt')
                ->with([
                    'student_answers' => function ($q) {
                        $q->where('student_id', Auth::user()->id)
                            ->with('user_submitted_questions.questions:id', 'user_submitted_questions.questions.options:id,question_id,is_answer');
                    }
                ])
                ->with('question_choice:id,online_exam_id,marks', 'class_subject.subject:id,name,type,code,bg_color,image')
                ->orderBy('id', 'desc');


            $onlineExamData = $query->paginate(15)->toArray();
            // dd($onlineExamData);
            $examListData = array(); // Initialized Empty examListData Array

            // dd($onlineExamData);
            // Loop through Exam data
            foreach ($onlineExamData['data'] as $data) {
                // Reset for each exam
                $examSubmittedDate = null;
                $examSubmittedCreatedDate = null;

                // Get Total Marks of Particular Exam

                $totalMarks = collect($data['question_choice'])->sum('marks');


                // Initialized totalObtainedMarks with 0
                $totalObtainedMarks = 0;

                // Group Student's Answers by question_id
                $grouped_answers = [];
                foreach ($data['student_answers'] as $student_answer) {
                    $examSubmittedDate = date('Y-m-d', strtotime($student_answer['submitted_date']));
                    $examSubmittedCreatedDate = date('d-m-Y H:i', strtotime($student_answer['created_at']));

                    if (isset($student_answer['question_marks'])) {
                        if (isset($student_answer['true_answer']) && $student_answer['true_answer'] == 1) {
                            $totalObtainedMarks += $student_answer['question_marks'];
                        }
                    } else {
                        $grouped_answers[$student_answer['question_id']][] = $student_answer;
                    }
                }

                // Fallback to student_attempt created_at if examSubmittedCreatedDate is not set
                if (!$examSubmittedCreatedDate && isset($data['student_attempt'][0]['created_at'])) {
                    $examSubmittedCreatedDate = date('d-m-Y H:i', strtotime($data['student_attempt'][0]['created_at']));
                }

                if ($grouped_answers && $grouped_answers != []) {
                    foreach ($grouped_answers as $student_answers) {

                        // Filter the options whose is_answer values is 1
                        $correct_option_ids = array_filter($student_answers[0]['user_submitted_questions']['questions']['options'], static function ($option) {
                            return $option['is_answer'] == 1;
                        });

                        // Get All Correct Options
                        $correct_option_ids = array_column($correct_option_ids, 'id');

                        // Get Student's Correct Options
                        $student_option_ids = array_column($student_answers, 'option_id');

                        // Check if the student's answers exactly match the correct answers then add marks with totalObtainedMarks
                        if (!array_diff($correct_option_ids, $student_option_ids) && !array_diff($student_option_ids, $correct_option_ids)) {
                            $totalObtainedMarks += $student_answers[0]['user_submitted_questions']['marks'];
                        }
                    }
                }
                // Loop through Student's Grouped answers

                // Make Exam List Data
                $examListData[] = array(
                    'online_exam_id' => $data['id'],
                    'subject' => array(
                        'id' => $data['class_subject']['subject']['id'],
                        'name' => $data['class_subject']['subject']['name'] . ' - ' . $data['class_subject']['subject']['type'],
                    ),
                    'title' => $data['title'],
                    'obtained_marks' => $totalObtainedMarks,
                    'total_marks' => $totalMarks ?? "0",
                    'exam_submitted_date' => $examSubmittedCreatedDate,

                    // 'exam_submitted_date' => $examSubmittedDate ?? carbon::createFromFormat($settings['date_format'] . ' ' . $settings['time_format'], $data['student_attempt'][0]['created_at'])
                );
            }

            $examList = array(
                'current_page' => $onlineExamData['current_page'],
                'data' => $examListData,
                'from' => $onlineExamData['from'],
                'last_page' => $onlineExamData['last_page'],
                'per_page' => $onlineExamData['per_page'],
                'to' => $onlineExamData['to'],
                'total' => $onlineExamData['total'],
            );

            ResponseService::successResponse("", $examList);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "StudentApiController :- getOnlineExamList Method");
            ResponseService::errorResponse();
        }
    }

    public function getOnlineExamResult(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'online_exam_id' => 'required|numeric'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;

            $onlineExam = $this->onlineExam->builder()
                ->where('id', $request->online_exam_id)
                ->whereHas('student_attempt', function ($q) use ($student) {
                    $q->where('student_id', $student->user_id);
                })
                ->with([
                    'question_choice:id,online_exam_id,marks',
                    'class_subject.subject:id,name',
                ])
                ->with([
                    'student_answers' => function ($q) {
                        $q->where('student_id', Auth::user()->id)
                            ->with('user_submitted_questions.questions:id', 'user_submitted_questions.questions.options:id,question_id,is_answer');
                    }
                ])
                ->first();

            if (isset($onlineExam) && $onlineExam != null) {


                $totalMarks = $onlineExam->question_choice->sum('marks');
                $totalQuestions = $onlineExam->question_choice->count();

                $correctQuestionData = array();
                $inCorrectQuestionData = array();
                $correctQuestions = 0;
                $incorrectQuestions = 0;
                $totalObtainedMarks = "0";
                $correctQuestionIds = [];
                // Group Student's Answers by question_id
                $grouped_answers = [];
                foreach ($onlineExam->student_answers as $student_answer) {
                    if (isset($student_answer->question_marks)) {
                        if ($student_answer->true_answer == 1) {
                            $correctQuestions++;
                            $correctQuestionData[] = [
                                'question_id' => $student_answer->question_id,
                                'marks' => $student_answer->question_marks
                            ];
                            $correctQuestionIds[] = $student_answer->question_id;
                            $totalObtainedMarks += $student_answer->question_marks;
                        }
                    } else {
                        $grouped_answers[$student_answer['question_id']][] = $student_answer->toArray();
                    }
                }
                $incorrectQuestions = $totalQuestions - $correctQuestions;
                if (!empty($correctQuestionIds)) {
                    $incorrectQuestionsData = $onlineExam->question_choice
                        ->whereNotIn('id', $correctQuestionIds);
                } else {
                    $incorrectQuestionsData = $onlineExam->question_choice;
                }
                foreach ($incorrectQuestionsData as $incorrectData) {
                    $inCorrectQuestionData[] = [
                        'question_id' => $incorrectData->id,
                        'marks' => $incorrectData->marks
                    ];
                }
                // Initialized the variables


                // Loop through Student's Grouped answers
                if (isset($grouped_answers) && $grouped_answers != null) {
                    foreach ($grouped_answers as $student_answers) {

                        // Filter the options whose is_answer values is 1
                        $correct_option_ids = array_filter($student_answers[0]['user_submitted_questions']['questions']['options'], static function ($option) {
                            return $option['is_answer'] == 1;
                        });

                        // Get All Correct Options
                        $correct_option_ids = array_column($correct_option_ids, 'id');

                        // Get Student's Correct Options
                        $student_option_ids = array_column($student_answers, 'option_id');

                        // Check if the student's answers exactly match the correct answers then add marks with totalObtainedMarks
                        if (!array_diff($correct_option_ids, $student_option_ids) && !array_diff($student_option_ids, $correct_option_ids)) {

                            // Sum Question marks with ObtainedMarks
                            $totalObtainedMarks += $student_answers[0]['user_submitted_questions']['marks'];

                            // Get Correct Questions Ids
                            $correctQuestionIds[] = $student_answers[0]['user_submitted_questions']['id'];

                            // Increment Correct Question by 1
                            ++$correctQuestions;

                            // Correct Question Data
                            $correctQuestionData[] = array(
                                'question_id' => $student_answers[0]['user_submitted_questions']['id'],
                                'marks' => $student_answers[0]['user_submitted_questions']['marks']
                            );
                        }
                    }

                    // Check correctQuestionIds exists and not empty
                    if (!empty($correctQuestionIds)) {
                        // Get Incorrect Questions Excluding Correct answer using correctQuestionIds
                        $incorrectQuestionsData = $onlineExam->question_choice->whereNotIn('id', $correctQuestionIds);
                    } else {
                        // Get All Question Choice as incorrectQuestionsData
                        $incorrectQuestionsData = $onlineExam->question_choice;
                    }

                    // Total Incorrect Questions
                    $incorrectQuestions = $incorrectQuestionsData->count();

                    // Incorrect Question Data
                    $inCorrectQuestionData = array();
                    foreach ($incorrectQuestionsData as $incorrectData) {
                        $inCorrectQuestionData[] = array(
                            'question_id' => $incorrectData->id,
                            'marks' => $incorrectData->marks
                        );
                    }
                }

                // Find the exam submitted date (assume it's the latest updated_at from student's answers, or fallback to end_date)
                // $examSubmittedDate = $onlineExam->end_date;
                $examSubmittedDate = null;
                if ($onlineExam->student_answers && count($onlineExam->student_answers) > 0) {
                    // Get the latest updated_at or created_at from answers
                    $examSubmittedDate = collect($onlineExam->student_answers)->max(function ($answer) {
                        return $answer->updated_at ?? $answer->created_at;
                    });
                    try {
                        // $examSubmittedDate = Carbon::createFromFormat('d/m/Y H:i', $examSubmittedDate)->format('Y-m-d H:i:s');
                    } catch (\Exception $e) {
                        try {
                            // $examSubmittedDate = Carbon::parse($examSubmittedDate)->format('Y-m-d H:i:s');
                        } catch (\Exception $e2) {
                            $examSubmittedDate = null; // fallback if both parsers fail
                        }
                    }
                }

                // Get online exam title and subject name
                $examTitle = $onlineExam->title ?? '';
                $subjectName = $onlineExam->class_subject->subject->name;

                // Final Array Data with additional info
                $onlineExamResult = array(
                    'online_exam_name' => $examTitle,
                    'subject_name' => $subjectName,
                    'exam_submitted_date' => $examSubmittedDate,
                    'total_questions' => $totalQuestions,
                    'correct_answers' => array(
                        'total_questions' => $correctQuestions,
                        'question_data' => $correctQuestionData
                    ),
                    'in_correct_answers' => array(
                        'total_questions' => $incorrectQuestions,
                        'question_data' => $inCorrectQuestionData
                    ),
                    'total_obtained_marks' => $totalObtainedMarks,
                    'total_marks' => $totalMarks ?? '0'
                );
                ResponseService::successResponse("", $onlineExamResult);
            } else {
                ResponseService::successResponse("", []);
            }
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e, "StudentApiController getOnlineExamResult Method");
            ResponseService::errorResponse();
        }
    }

    public function getOnlineExamReport(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'class_subject_id' => 'nullable|numeric'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;
            $sessionYear = $this->cache->getDefaultSessionYear();

            $onlineExams = $this->onlineExam->builder()
                ->has('question_choice')
                ->whereHas('online_exam_commons', function ($q) use ($request, $student) {
                    $q->where('class_subject_id', $request->class_subject_id)
                        ->where('class_section_id', $student->class_section_id);
                })

                ->where(['session_year_id' => $sessionYear->id])

                ->with([
                    'student_answers' => function ($q) use ($student) {
                        $q->where('student_id', $student->user_id)
                            ->with('user_submitted_questions.questions:id', 'user_submitted_questions.questions.options:id,question_id,is_answer');
                    }
                ])->with('question_choice:id,online_exam_id,marks', 'class_subject.subject:id,name,type,code,bg_color,image')
                ->paginate(null);

            if ($onlineExams->count() > 0) {
                $totalExamIds = $onlineExams->pluck('id')->toArray();

                $totalExamsAttempted = 0;
                $totalExamsAttempted = $this->studentOnlineExamStatus->builder()->where('student_id', $student->user_id)->whereIn('online_exam_id', $totalExamIds)->where('status', 2)->count();


                $examList = array();
                foreach ($onlineExams->toArray()['data'] as $onlineExam) {


                    $totalMarks = collect($onlineExam['question_choice'])->sum('marks');

                    // Initialized totalObtainedMarks with 0
                    $totalObtainedMarks = "0";

                    // Group Student's Answers by question_id
                    $grouped_answers = [];
                    foreach ($onlineExam['student_answers'] as $student_answer) {
                        if (isset($student_answer['question_marks'])) {
                            if ($student_answer['true_answer'] == 1) {
                                $totalObtainedMarks += $student_answer['question_marks'];
                            }
                        } else {
                            $grouped_answers[$student_answer['question_id']][] = $student_answer;
                        }
                    }

                    // Loop through Student's Grouped answers
                    if (isset($grouped_answers) && count($grouped_answers) > 0) {
                        foreach ($grouped_answers as $student_answers) {

                            // Filter the options whose is_answer values is 1
                            $correct_option_ids = array_filter($student_answers[0]['user_submitted_questions']['questions']['options'], static function ($option) {
                                return $option['is_answer'] == 1;
                            });

                            // Get All Correct Options
                            $correct_option_ids = array_column($correct_option_ids, 'id');

                            // Get Student's Correct Options
                            $student_option_ids = array_column($student_answers, 'option_id');

                            // Convert to integers and sort for proper comparison
                            $correct_option_ids = array_map('intval', $correct_option_ids);
                            $student_option_ids = array_map('intval', $student_option_ids);
                            sort($correct_option_ids);
                            sort($student_option_ids);

                            // Check if the student's answers exactly match the correct answers then add marks with totalObtainedMarks
                            if ($correct_option_ids === $student_option_ids) {
                                $totalObtainedMarks += $student_answers[0]['user_submitted_questions']['marks'];
                            }
                        }
                    }

                    // Add exam to the list
                    $examList[] = [
                        'online_exam_id' => $onlineExam['id'],
                        'title' => $onlineExam['title'],
                        'obtained_marks' => (string) $totalObtainedMarks,
                        'total_marks' => (string) $totalMarks,
                    ];
                }
                $totalExamsMarks = collect($examList)->sum('total_marks');
                $totalExamsObtainedMarks = collect($examList)->sum('obtained_marks');
                //  dd($totalExamsMarks);
                // Calculate Percentage
                if ($totalMarks > 0) {
                    // Avoid division by zero error
                    $percentage = number_format(($totalExamsObtainedMarks * 100) / max($totalExamsMarks, 1), 2);
                } else {
                    // If total marks is zero, then percentage is also zero
                    $percentage = 0;
                }

                // Build the final data array
                $onlineExamReportData = array(
                    'total_exams' => count($totalExamIds),
                    'attempted' => $totalExamsAttempted,
                    'missed_exams' => count($totalExamIds) - $totalExamsAttempted,
                    'total_marks' => (string) $totalExamsMarks,
                    'total_obtained_marks' => (string) $totalExamsObtainedMarks,
                    'percentage' => (string) $percentage,
                    'exam_list' => [
                        'current_page' => (string) $onlineExams->currentPage(),
                        'data' => array_values($examList),
                        'from' => (string) $onlineExams->firstItem(),
                        'last_page' => (string) $onlineExams->lastPage(),
                        'per_page' => (string) $onlineExams->perPage(),
                        'to' => (string) $onlineExams->lastItem(),
                        'total' => (string) $onlineExams->total(),
                    ],
                );
            } else {
                $onlineExamReportData = [];
            }


            // Return the response
            ResponseService::successResponse("", $onlineExamReportData);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getAssignmentReport(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'class_subject_id' => 'nullable|numeric'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }
        try {
            $student = Auth::user()->student;
            $sessionYear = $this->cache->getDefaultSessionYear();

            // Assignment Data
            $assignments = $this->assignment->builder()
                ->where(['session_year_id' => $sessionYear->id])
                ->whereNotNull('points')
                ->whereHas('assignment_commons', function ($q) use ($student, $request) {
                    $q->where('class_section_id', $student->class_section_id)
                        ->where('class_subject_id', $request->class_subject_id);
                })
                ->get();

            // Get the assignment submissions
            $submitted_assignment_ids = $this->assignmentSubmission->builder()->where('student_id', $student->user_id)->whereIn('assignment_id', $assignments->pluck('id'))->pluck('assignment_id');

            // Calculate various statistics
            $total_assignments = $assignments->count();
            $total_submitted_assignments = $submitted_assignment_ids->count();
            $total_assignment_submitted_points = $assignments->sum('points');
            $total_points_obtained = $this->assignmentSubmission->builder()->whereIn('assignment_id', $submitted_assignment_ids)->sum('points');

            // Calculate the percentage
            $percentage = $total_assignment_submitted_points ? number_format(($total_points_obtained * 100) / $total_assignment_submitted_points, 2) : 0;

            // Get the submitted assignment data with points (using pagination manually)
            $perPage = 15;
            $currentPage = $request->input('page', 1);
            $offset = ($currentPage - 1) * $perPage;
            $submitted_assignment_data_with_points = $assignments->filter(function ($assignment) use ($submitted_assignment_ids) {
                return $assignment->points !== null && $submitted_assignment_ids->contains($assignment->id);
            })->slice($offset, $perPage)->map(function ($assignment) {
                return [
                    'assignment_id' => $assignment->id,
                    'assignment_name' => $assignment->name,
                    'obtained_points' => optional($assignment->submission)->points ?? 0,
                    'total_points' => $assignment->points
                ];
            });

            $assignment_report = [
                'assignments' => $total_assignments,
                'submitted_assignments' => $total_submitted_assignments,
                'unsubmitted_assignments' => $total_assignments - $total_submitted_assignments,
                'total_points' => $total_assignment_submitted_points,
                'total_obtained_points' => $total_points_obtained,
                'percentage' => $percentage,
                'submitted_assignment_with_points_data' => [
                    'current_page' => $currentPage,
                    'data' => array_values($submitted_assignment_data_with_points->toArray()),
                    'from' => $offset + 1,
                    'to' => $offset + $submitted_assignment_data_with_points->count(),
                    'per_page' => $perPage,
                    'total' => $total_submitted_assignments,
                    'last_page' => ceil($total_submitted_assignments / $perPage),
                ],
            ];


            ResponseService::successResponse("Data Fetched Successfully", $assignment_report);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getSchoolSettings()
    {
        try {
            if (Auth::user()) {
                $settings = $this->cache->getSchoolSettings();
                $sessionYear = $this->cache->getDefaultSessionYear();
                $semester = $this->cache->getDefaultSemesterData();
                $features = FeaturesService::getFeatures();
                $data = [
                    'school_id' => Auth::user()->school_id,
                    'session_year' => $sessionYear,
                    'semester' => $semester,
                    'settings' => $settings,
                    'features' => (count($features) > 0) ? $features : (object) []
                ];
                ResponseService::successResponse('Settings Fetched Successfully.', $data);
            } else {
                ResponseService::errorResponse(trans('your_account_has_been_deactivated_please_contact_admin'), null, config('constants.RESPONSE_CODE.INACTIVATED_USER'));
            }
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getSliders()
    {
        try {
            $studentData = Auth::user();
            $data = $this->sliders->builder()->where('school_id', $studentData->school_id)->whereIn('type', [1, 3])->get();
            ResponseService::successResponse("Sliders Fetched Successfully", $data);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getStudentDiaries()
    {
        try {
            $student = Students::where('user_id', Auth::id())->first();

            if (!$student) {
                return response()->json(['message' => 'Student record not found.'], 404);
            }

            $diaryStudents = $this->diaryStudent->builder()
                ->where('student_id', $student->id)
                ->with([
                    'diary' => function ($query) {
                        $query->with(['diary_category', 'session_year', 'subject']);
                    }
                ])
                ->get();

            ResponseService::successResponse("Student Diaries Fetched Successfully", $diaryStudents);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function showStudentDiaryDetail(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|nullable'
        ]);

        if ($validator->fails()) {
            ResponseService::validationError($validator->errors()->first());
        }

        try {
            $student = Students::where('user_id', Auth::id())->first();

            if (!$student) {
                return response()->json(['message' => 'Student record not found.'], 404);
            }

            $diaryStudents = $this->diaryStudent->builder()
                ->where('id', $request->id)
                ->where('student_id', $student->id)
                ->with([
                    'diary' => function ($query) {
                        $query->with(['diary_category', 'session_year', 'subject']);
                    }
                ])
                ->firstOrFail();

            ResponseService::successResponse("Student Diary Fetched Successfully", $diaryStudents);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getStudentDiaryCategories()
    {
        try {
            $student = Auth::user();

            // Get unique diary_category_ids for the student's diaries
            $categoryIds = $this->diaryStudent
                ->builder()
                ->where('student_id', $student->id)
                ->with([
                    'diary' => function ($query) {
                        $query->withTrashed();
                    }
                ])
                ->get()
                ->pluck('diary.diary_category_id')
                ->unique()
                ->filter()
                ->values();

            // Fetch the DiaryCategory models with these IDs
            $categories = DiaryCategory::withTrashed()
                ->whereIn('id', $categoryIds)
                ->get();

            ResponseService::successResponse("Student Diary Categories Fetched Successfully", $categories);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }

    public function getWebSliders()
    {
        try {
            $studentData = Auth::user();
            $data = $this->sliders->builder()->where('school_id', $studentData->school_id)->whereIn('type', [1, 3])->get();
            ResponseService::successResponse("Sliders Fetched Successfully", $data);
        } catch (Throwable $e) {
            ResponseService::logErrorResponse($e);
            ResponseService::errorResponse();
        }
    }
}