<?php

namespace App\Http\Controllers\Admin;

use App\DataTables\AttendeesDataTable;
use App\DataTables;
use App\DataTables\StudentNotesDataTable;
use App\DataTables\StudyMaterialsDataTable;
use App\DataTables\StudentFinancialRecordsDataTable;
use App\DataTables\StudentsDataTable;
use App\DataTables\StudentGradeDataTable;
use App\Http\Controllers\Controller;
use App\Imports\StudentsImport;
use App\Models\Transportation;
use App\Models\Attendees;
use App\Models\StudentNote;
use App\Models\Cities;
use App\Models\Division;
use App\Models\Language;
use App\Models\StudentExamGrades;
use App\Models\StudentNotesTypes;
use App\Models\Level;
use App\Models\Nationality;
use App\Models\Parents;
use App\Models\Religion;
use App\Models\Role;
use App\Models\Stage;
use App\Models\StudyMaterial;
use App\Models\Student;
use App\Models\StudentHealthRecords;
use App\Models\StudentLanguage;
use App\Models\SemesterExam;
use App\Models\StudentLevels;
use App\Models\StudentNationality;
use App\Models\StudentFinancialRecord;
use App\Models\StudentTransportation;
use App\Models\ParentAccount;
use App\Models\ParentNotification;
use App\Notifications\AttendeesNotification;
use App\Listeners\SendAttendeesNotification;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\Console\Input\Input;
use App\Events\NewAttendees;
use App\Models\StudentCalcGrade;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Kutia\Larafirebase\Facades\Larafirebase;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Events\Dispatchable;


class StudentsController extends Controller
{ 
  
    //
    public function students(StudentsDataTable $student)
    {

        $division_id = request('division_id');
        $noteTypes = DB::table('student_notes_types')->get();

        $allowedDivisions = [];
        $userPermission = Auth::guard('admin')->user()->getUserPermissionByCode('manage-students');
        if ($userPermission) {
            $allowedDivisions = json_decode($userPermission['details'], true)['divisions'];
        }

        $divisions = Division::select('divisions.id', 'divisions.title', 'levels.title as level', 'stages.title as stage')
            ->join('levels', 'levels.id', '=', 'divisions.level_id')
            ->join('stages', 'stages.id', '=', 'levels.stage_id');
        if (in_array('-1', $allowedDivisions)) {
            $divisions = $divisions->get();
        } else {
            $divisions = $divisions->whereIn('divisions.id', $allowedDivisions)->get();
        }

        // $canManageStudentsNotes = Auth::guard('admin')->user()->can('manageAny', [StudentNote::class]);

        return ($student->with(['division_id' => $division_id,])->render('admin.students.students-index', ['noteTypes' => $noteTypes, 'divisions' => $divisions]));
    }

    public function showCreateStudentView()
    {
        $nationalities = Nationality::all();
        $religions = Religion::all();
        $levels = Level::all();
        $languages = Language::all();
        $stages = Stage::all();
        $cities = Cities::orderBy('title')->get();
        $transportations = Transportation::all();

        return view('admin.students.students-create', [
            'stages' => $stages,
             'cities' => $cities,
             'languages' => $languages,
             'nationalities' => $nationalities,
             'religions' => $religions,
             'levels' => $levels,
             'transportations' => $transportations,
        ]);
    }

    public function create(Request $request)
    {

        $data = ($request->all());
        

        $validator = Validator::make($data, [
            'firstName' => ['required', 'max:190'],
            'lastName' => ['required', 'max:190'],
            'gender' => ['required', 'max:190', Rule::in(['male', 'female'])],
            'nationality' => ['required', 'max:190', 'exists:App\Models\Nationality,id'],
            'birth_place' => ['required', 'max:190'],
            'birth_date' => ['required', 'max:190'],
            'religion' => ['required', 'max:190', 'exists:App\Models\Religion,id'],
            'level_to_study' => ['required', 'max:190', 'exists:App\Models\Level,id'],
            'division' => ['required', 'max:190', 'exists:App\Models\Division,id'],
            'phone' => ['required','digits:9', 'regex:/^([1-9][0-9]*)$/', 'max:190'],
            'telephone' => ['required', 'regex:/^([0-9]{9,10})$/'],
            'total_installment' => ['required', 'numeric'],
            'addMotherType' => ['required', 'max:190'],
            'addFatherType' => ['required', 'max:190'],
            // 'transportation' => ['required', 'max:190'],
            'city' => ['required', 'max:190', 'exists:App\Models\Cities,id'],
            'transportation_line' => ['nullable', 'max:190', 'exists:App\Models\Transportation,id'],
            'area' => ['required', 'max:190'],
            'street' => ['required', 'max:2550'],
            'emergency_phone' => ['required','digits:9', 'regex:/^([1-9][0-9]*)$/', 'max:190'],
            'kinship' => ['required', 'max:190'],
        ], [], [])->validate();

        
        if (isset($data['school_sequence'])) {
            foreach ($data['school_sequence'] as $value) {
                Validator::make($value, [
                    'school_name' => ['required', 'max:190'],
                    'status' => ['required', 'max:190', Rule::in([0, 1])],
                    'level' => ['required', 'max:190', 'exists:App\Models\Level,id'],
                ], [], [])->validate();
            }
        }

        if ($data['addMotherType'] == 1) {
            Validator::make($data, [
                'mother_firstName' => ['required', 'max:190'],
                'mother_lastName' => ['required', 'max:190'],
                'mother_job' => ['required', 'max:190'],
                'mother_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/', 'unique:App\Models\Parents,phone', function ($attribute, $value, $fail) use ($data) {
                    if (isset($data['father_phone'])) {
                        if ($value == $data['father_phone']) {
                            $fail('The ' . $attribute . ' must be unique.');
                        }
                    }
                },],
            ], [], [])->validate();
        } else {
            Validator::make($data, [
                'exest_mother_id' => ['required', 'max:190', 'exists:App\Models\Parents,id'],
            ], [], [])->validate();
        }

        if ($data['addFatherType'] == 1) {
            Validator::make($data, [
                'father_firstName' => ['required', 'max:190'],
                'father_lastName' => ['required', 'max:190'],
                'father_job' => ['required', 'max:190'],
                'father_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/', 'unique:App\Models\Parents,phone', function ($attribute, $value, $fail) use ($data) {
                    if (isset($data['mother_phone'])) {
                        if ($value == $data['mother_phone']) {
                            $fail('The ' . $attribute . ' must be unique.');
                        }
                    }
                }],
            ], [], [])->validate();
        } else {
            Validator::make($data, [
                'exest_father_id' => ['required', 'max:190', 'exists:App\Models\Parents,id'],
            ], [], [])->validate();
        }

        if (isset($data['health-problems'])) {
            foreach ($data['health-problems'] as $value) {
                Validator::make($value, [
                    'health_problem' => ['required', 'max:190'],
                ], [], [])->validate();
            }
        }
        if (isset($data['languages'])) {
            foreach ($data['languages'] as $value) {
                Validator::make($value, [
                    'level' => ['required', 'max:190', Rule::in([0, 1, 2])],
                    'language' => ['required', 'max:190', 'exists:App\Models\Language,id'],
                ], [], [])->validate();
            }
        }


        DB::transaction(function () use ($data) {
            $studRes;
            $mother_id = null;
            $father_id = null;
            if ($data['addMotherType'] == 1) {
                $mother_id = Parents::createAndGetId([
                    'first_name' => $data['mother_firstName'],
                    'last_name' => $data['mother_lastName'],
                    'job' => $data['mother_job'],
                    'phone' => $data['mother_phone'],
                    'gender' => 'female',
                ]);
            } else {
                $mother_id = $data['exest_mother_id'];
            }

            if ($data['addFatherType'] == 1) {
                $father_id = Parents::createAndGetId([
                    'first_name' => $data['father_firstName'],
                    'last_name' => $data['father_lastName'],
                    'job' => $data['father_job'],
                    'phone' => $data['father_phone'],
                    'gender' => 'male',
                ]);
            } else {
                $father_id = $data['exest_father_id'];
            }

            // $divisionId = null;
            // $divisions = Division::getDivisionStudentsByLevelId($data['level_to_study']);

            // foreach ($divisions as $value) {
            //     if ($value->capacity >= $value->students) {
            //         $divisionId = $value->id;
            //         break;
            //     }
            //     $divisionId = $value->division;
            // }

            $studRes = Student::createAndGetId([
                'first_name' => $data['firstName'],
                'last_name' => $data['lastName'],
                'birth_date' => \Carbon\Carbon::create($data['birth_date']),
                'birth_place' => $data['birth_place'],
                'gender' => $data['gender'],
                'city_id' => $data['city'],
                'street' => $data['street'],
                'area' => $data['area'],
                'transportation_id' => $data['transportation_line'],
                'phone' => $data['phone'],
                'telephone' => $data['telephone'],
                'total_installment' => $data['total_installment'],
                'emergency_phone' => $data['emergency_phone'],
                'emergency_kinship' => $data['kinship'],
                'religion_id' => $data['religion'],
                'division_id' =>  $data['division'],
                'mother_id' => $mother_id,
                'father_id' => $father_id,
            ]);

            StudentNationality::create([
                "nationality_id" => $data['nationality'],
                "student_id" => $studRes,
            ]);


            if (isset($data['school_sequence'])) {
                foreach ($data['school_sequence'] as $value) {
                    StudentLevels::create([
                        'school' => $value['school_name'],
                        'status' => $value['status'],
                        'year' => $value['year'],
                        'level_id' => $value['level'],
                        'student_id' => $studRes,
                    ]);
                }
            }
            if (isset($data['health-problems'])) {
                foreach ($data['health-problems'] as $value) {
                    StudentHealthRecords::create([
                        'title' => $value['health_problem'],
                        'description' => $value['description'],
                        'student_id' => $studRes,
                    ]);
                }
            }
            if (isset($data['languages'])) {
                foreach ($data['languages'] as $value) {
                    StudentLanguage::create([
                        'level' => $value['level'],
                        'language_id' => $value['language'],
                        'student_id' => $studRes,
                    ]);
                }
            }
            // if ($data['transportation'] == 1) {
            //     foreach ($data['languages'] as $value) {
            //         StudentTransportation::create([
            //             'student_id' => $studRes,
            //         ]);
            //     }
            // }
        });

        return back()->with('success', trans('general.New student added Successfully'));
    }


    public function showUpdateStudentView($id)
    {
        // $roles = Role::all();
        $validator = Validator::make(['id' => $id], [
            'id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
        ], [], []);

        $transportations = Transportation::all();
        $nationalities = Nationality::all();
        $religions = Religion::all();

        $languages = Language::all();
        $cities = Cities::orderBy('title')->get();
        $student = Student::select(
            'students.id as student_id',
            'students.first_name',
            'students.last_name',
            'students.birth_date',
            'students.birth_place',
            'students.gender',
            'students.city_id',
            'students.street',
            'students.area',
            'students.transportation_id',
            'students.phone',
            'students.telephone',
            'students.total_installment',
            'students.emergency_phone',
            'students.emergency_kinship',
            'students.religion_id',
            'students.mother_id',
            'students.father_id',
            'students.division_id',
            'divisions.level_id',
            // 'student_transportations.id as transportation',
        )
            ->leftJoin('divisions', 'divisions.id', '=', 'students.division_id')
            // ->leftJoin('student_transportations', 'student_transportations.student_id', '=', 'students.id')
            ->where("students.id", $id)->first();

        $this->authorize('manage', $student);


        $stages = Stage::all();
        $currentStage = Level::select('stage_id as id')->where('id', $student->level_id)->first();
        $levels = Level::select('levels.*')->where('stage_id', $currentStage->id)->distinct()
            ->join('divisions', 'divisions.level_id', '=', 'levels.id')->get();
        $mother = Parents::find($student->mother_id);
        $father = Parents::find($student->father_id);
        $schoolSequence = StudentLevels::where('student_id', $student->student_id)->get();
        $studentLanguages = StudentLanguage::where('student_id', $student->student_id)->get();
        $studentHealthRecords = StudentHealthRecords::where('student_id', $student->student_id)->get();
        $studentNationalities = StudentNationality::where('student_id', $id)->get();
        $studentNationalitiesIDs = [];
        foreach ($studentNationalities as $value) {
            $studentNationalitiesIDs[] = $value->nationality_id;
        }

        return view('admin.students.students-edit', [
            'stages' => $stages,
            'currentStage' => $currentStage,
            'student' => $student,
            'mother' => $mother,
            'transportations' => $transportations,
            'father' => $father,
            'cities' => $cities,
            'schoolSequence' => $schoolSequence,
            'studentNationalitiesIDs' => $studentNationalitiesIDs,
            'studentLanguages' => $studentLanguages,
            'studentHealthRecords' => $studentHealthRecords,
            'languages' => $languages,
            'nationalities' => $nationalities,
            'religions' => $religions,
            'levels' => $levels,
        ]);
    }


    public function updateStudent(Request $request)
    {
        $data = ($request->all());
        $data['nationality'] = explode(',', $data['nationality']);
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'firstName' => ['required', 'max:190'],
            'lastName' => ['required', 'max:190'],
            'gender' => ['required', 'max:190', Rule::in(['male', 'female'])],
            'nationality' => ['required', 'array'],
            'nationality.*' => ['exists:App\Models\Nationality,id'],
            'birth_place' => ['required', 'max:190'],
            'division' => ['required', 'max:190', 'exists:App\Models\Division,id'],
            'birth_date' => ['required', 'max:190'],
            'religion' => ['required', 'max:190', 'exists:App\Models\Religion,id'],
            'level_to_study' => ['required', 'max:190', 'exists:App\Models\Level,id'],
            'phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/',],
            'telephone' => ['required', 'regex:/^([0-9]{9,10})$/',],
            'total_installment' => ['required', 'numeric'],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        } else {
            $student = Student::find($data['student_id']);

            $this->authorize('manage', $student);

            if ($student) {
                $student->first_name = $data['firstName'];
                $student->last_name = $data['lastName'];
                $student->birth_date = $data['birth_date'];
                $student->birth_place = $data['birth_place'];
                $student->gender = $data['gender'];
                $student->phone = $data['phone'];
                $student->telephone = $data['telephone'];
                $student->total_installment = $data['total_installment'];
                $student->religion_id = $data['religion'];
                $student->division_id = $data['division'];

                // $studentDivision = Division::find($student->division_id);
                // if ($studentDivision->level_id != $data['level_to_study']) {
                //     $divisionId = null;
                //     $divisions = Division::getDivisionStudentsByLevelId($data['level_to_study']);
                //     foreach ($divisions as $value) {
                //         if ($value->capacity >= $value->students) {
                //             $divisionId = $value->id;
                //             break;
                //         }
                //         $divisionId = $value->division;
                //     }
                // }
                $student->save();


                $studentNationalities = StudentNationality::where('student_id', $student->id)->get();
                $studentOldNationalitiesIDs = [];
                foreach ($studentNationalities as $value) {
                    $studentOldNationalitiesIDs[] = $value->nationality_id;
                }
                $studentNationalitiesToDelete = array_diff($studentOldNationalitiesIDs, $data['nationality']);
                $studentNationalitiesToAdd = array_diff($data['nationality'], $studentOldNationalitiesIDs);

                StudentNationality::where('student_id', $student->id)->whereIn('nationality_id', $studentNationalitiesToDelete)->delete();
                foreach ($studentNationalitiesToAdd as $value) {
                    StudentNationality::create([
                        'student_id' => $student->id,
                        'nationality_id' => $value,
                    ]);
                }


                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }

            $response = [
                'error' => trans('general.record_not_found')
            ];
            return new JsonResponse($response, 400);
        }
    }


    public function updateMother(Request $request)
    {
        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'editMotherType' => ['required', 'max:190', Rule::in(['0', '1', '2'])],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        }

        if ($data['editMotherType'] == 2) {

            $this->authorize('manageAny', Parents::class);

            $validator = Validator::make($data, [
                'mother_firstName' => ['required', 'max:190'],
                'mother_lastName' => ['required', 'max:190'],
                'mother_job' => ['required', 'max:190'],
                'mother_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/', 'unique:App\Models\Parents,phone'],
            ], [], []);

            if ($validator->fails()) {
                $response['error'] = $validator->messages();
                return new JsonResponse($response, 400);
            } else {
                # create new parent account
                $newMother = Parents::createAndGetId([
                    'first_name' => $data['mother_firstName'],
                    'last_name' => $data['mother_lastName'],
                    'job' => $data['mother_job'],
                    'phone' => $data['mother_phone'],
                    'gender' => 'female',
                ]);

                $student = Student::find($data['student_id']);
                $student->mother_id = $newMother;
                $student->save();

                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }
        } else if ($data['editMotherType'] == 0) {
            $validator = Validator::make($data, [
                'mother_id' => ['required', 'max:190'],
                'mother_firstName' => ['required', 'max:190'],
                'mother_lastName' => ['required', 'max:190'],
                'mother_job' => ['required', 'max:190'],
                'mother_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/', 'unique:App\Models\Parents,phone,' . ($data['mother_id'] ?? 0)],
            ], [], []);

            if ($validator->fails()) {
                $response['error'] = $validator->messages();
                return new JsonResponse($response, 400);
            } else {
                # edit current account
                $mother = Parents::find($data['mother_id']);

                $this->authorize('manage', $mother);

                $mother->first_name = $data['mother_firstName'];
                $mother->last_name = $data['mother_lastName'];
                $mother->job = $data['mother_job'];
                $mother->phone = $data['mother_phone'];
                $mother->save();

                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }
        } else if ($data['editMotherType'] == 1) {
            $validator = Validator::make($data, [
                'mother_id' => ['required', 'max:190', 'exists:App\Models\Parents,id'],
            ], [], []);

            if ($validator->fails()) {
                $response['error'] = $validator->messages();
                return new JsonResponse($response, 400);
            } else {
                $student = Student::find($data['student_id']);
                $student->mother_id = $data['mother_id'];
                $student->save();

                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }
        }

        $response = [
            'error' => trans('general.error')
        ];
        return new JsonResponse($response, 400);
    }


    public function updateFather(Request $request)
    {
        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'editFatherType' => ['required', 'max:190', Rule::in(['0', '1', '2'])],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        }

        if ($data['editFatherType'] == 2) {

            $this->authorize('manageAny', Parents::class);

            $validator = Validator::make($data, [
                'father_firstName' => ['required', 'max:190'],
                'father_lastName' => ['required', 'max:190'],
                'father_job' => ['required', 'max:190'],
                'father_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/', 'unique:App\Models\Parents,phone'],
            ], [], []);

            if ($validator->fails()) {
                $response['error'] = $validator->messages();
                return new JsonResponse($response, 400);
            } else {
                # create new parent account
                $newFather = Parents::createAndGetId([
                    'first_name' => $data['father_firstName'],
                    'last_name' => $data['father_lastName'],
                    'job' => $data['father_job'],
                    'phone' => $data['father_phone'],
                    'gender' => 'male',
                ]);

                $student = Student::find($data['student_id']);
                $student->father_id = $newFather;
                $student->save();

                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }
        } else if ($data['editFatherType'] == 0) {
            $validator = Validator::make($data, [
                'father_id' => ['required', 'max:190'],
                'father_firstName' => ['required', 'max:190'],
                'father_lastName' => ['required', 'max:190'],
                'father_job' => ['required', 'max:190'],
                'father_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/', 'unique:App\Models\Parents,phone,' . ($data['father_id'] ?? 0)],
            ], [], []);

            if ($validator->fails()) {
                $response['error'] = $validator->messages();
                return new JsonResponse($response, 400);
            } else {
                # edit current account
                $father = Parents::find($data['father_id']);
                $this->authorize('manage', $father);

                $father->first_name = $data['father_firstName'];
                $father->last_name = $data['father_lastName'];
                $father->job = $data['father_job'];
                $father->phone = $data['father_phone'];
                $father->save();

                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }
        } else if ($data['editFatherType'] == 1) {
            $validator = Validator::make($data, [
                'father_id' => ['required', 'max:190', 'exists:App\Models\Parents,id'],
            ], [], []);

            if ($validator->fails()) {
                $response['error'] = $validator->messages();
                return new JsonResponse($response, 400);
            } else {
                $student = Student::find($data['student_id']);
                $student->father_id = $data['father_id'];
                $student->save();

                $response = [
                    'data' => '',
                    'message' => trans('general.student_updated_successfully')
                ];
                return new JsonResponse($response, 201);
            }
        }

        $response = [
            'error' => trans('general.error')
        ];
        return new JsonResponse($response, 400);
    }

    public function updateAddress_Transportation_Emergency(Request $request)
    {
        $data = ($request->all());

        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'transportation' => ['required', 'max:190'],
            'transportation_line' => ['nullable', 'max:190', 'exists:App\Models\Transportation,id'],
            'city' => ['required', 'max:190', 'exists:App\Models\Cities,id'],
            'area' => ['required', 'max:190'],
            'street' => ['required', 'max:2550'],
            'emergency_phone' => ['required', 'max:190'],
            'kinship' => ['required', 'max:190'],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        }

        $student = Student::find($data['student_id']);

        $this->authorize('manage', $student);

        $student->city_id = $data['city'];
        $student->area = $data['area'];
        $student->street = $data['street'];
        $student->emergency_phone = $data['emergency_phone'];
        $student->emergency_kinship = $data['kinship'];
        $student->transportation_id = $data['transportation_line'];
        $student->save();
        
        // $studentTransportation = StudentTransportation::where('student_id', $data['student_id'])->get();

        // if ($data['transportation'] == 1 && count($studentTransportation) <= 1) {
        //     StudentTransportation::create([
        //         'student_id' => $data['student_id'],
        //     ]);
        // } elseif ($data['transportation'] == 0 && count($studentTransportation) >= 1) {
        //     StudentTransportation::where('student_id', $data['student_id'])->delete();
        // }

        $response = [
            'data' => '',
            'message' => trans('general.student_updated_successfully')
        ];
        return new JsonResponse($response, 201);
    }


    public function updateSequence(Request $request)
    {

        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'school_sequence' => ['required', 'array'],
            'school_sequence.*.sequence_id' => ['max:190'],
            'school_sequence.*.level' => ['required', 'max:190', 'exists:App\Models\Level,id'],
            'school_sequence.*.school_name' => ['required', 'max:190'],
            'school_sequence.*.year' => ['required', 'max:190'],
            'school_sequence.*.status' => ['required', 'max:190', Rule::in(['0', '1'])],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        }

        $student = Student::find($data['student_id']);
        $this->authorize('manage', $student);

        $studentLevels = StudentLevels::where('student_id', $data['student_id'])->get();
        $currentStudentsLevels = [];

        foreach ($studentLevels as $value) {
            $currentStudentsLevels[] = $value->id;
        }


        $newStudentsLevels = [];

        foreach ($data['school_sequence'] as $value) {
            $newStudentsLevels[] = $value['sequence_id'];
        }

        $levelsToAdd = array_diff($newStudentsLevels, $currentStudentsLevels);
        $levelsToDelete = array_diff($currentStudentsLevels, $newStudentsLevels);
        $levelsToEdit = array_diff($newStudentsLevels, array_merge($levelsToAdd, $levelsToDelete));

        foreach ($data['school_sequence'] as $value) {
            if ($value['sequence_id'] == null) {
                StudentLevels::create([
                    'student_id' => $data['student_id'],
                    'school' => $value['school_name'],
                    'status' => $value['status'],
                    'year' => $value['year'],
                    'level_id' => $value['level'],
                ]);
            } else {
                $stLevel = StudentLevels::find($value['sequence_id']);
                if ($stLevel) {
                    $stLevel->school = $value['school_name'];
                    $stLevel->status = $value['status'];
                    $stLevel->year = $value['year'];
                    $stLevel->level_id = $value['level'];
                    $stLevel->save();
                }
            }
        }

        StudentLevels::whereIn('id', $levelsToDelete)->delete();

        $response = [
            'data' => '',
            'message' => trans('general.student_updated_successfully')
        ];
        return new JsonResponse($response, 201);
    }


    public function updateLanguages(Request $request)
    {
        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'languages' => ['required', 'array'],
            'languages.*.language' => ['required', 'max:190', 'exists:App\Models\Language,id'],
            'languages.*.level' => ['required', 'max:190'],
            'languages.*.student_lang_id' => ['max:190'],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        }

        $student = Student::find($data['student_id']);
        $this->authorize('manage', $student);


        $studentLanguage = StudentLanguage::where('student_id', $data['student_id'])->get();
        $currentStudentsLanguage = [];

        foreach ($studentLanguage as $value) {
            $currentStudentsLanguage[] = $value->id;
        }

        $newStudentsLanguage = [];

        foreach ($data['languages'] as $value) {
            $newStudentsLanguage[] = $value['student_lang_id'];
        }

        // $languageToAdd = array_diff($newStudentsLanguage, $currentStudentsLanguage);
        $languageToDelete = array_diff($currentStudentsLanguage, $newStudentsLanguage);
        // $languageToEdit = array_diff($newStudentsLanguage, array_merge($languageToAdd, $languageToDelete));


        foreach ($data['languages'] as $value) {
            print_r($value['student_lang_id']);
            if ($value['student_lang_id'] == null) {
                StudentLanguage::create([
                    'level' => $value['level'],
                    'language_id' => $value['language'],
                    'student_id' => $data['student_id'],
                ]);
            } else {
                $stLang = StudentLanguage::find($value['student_lang_id']);
                if ($stLang) {
                    $stLang->level = $value['level'];
                    $stLang->language_id = $value['language'];
                    $stLang->save();
                }
            }
        }

        StudentLanguage::whereIn('id', $languageToDelete)->delete();

        $response = [
            'data' => '',
            'message' => trans('general.student_updated_successfully')
        ];
        return new JsonResponse($response, 201);
    }


    public function updateHealth(Request $request)
    {

        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'health-problems' => ['required', 'array'],
            'health-problems.*.health_problem' => ['required', 'max:190'],
            'health-problems.*.description' => ['required', 'max:190'],
            'health-problems.*.student_health_id' => ['max:190'],
        ], [], []);

        if ($validator->fails()) {
            $response['error'] = $validator->messages();
            return new JsonResponse($response, 400);
        }

        $student = Student::find($data['student_id']);
        $this->authorize('manage', $student);


        $studentHealthRecords = StudentHealthRecords::where('student_id', $data['student_id'])->get();
        $currentStudentsHealthRecords = [];

        foreach ($studentHealthRecords as $value) {
            $currentStudentsHealthRecords[] = $value->id;
        }

        $newStudentsHealthRecords = [];

        foreach ($data['health-problems'] as $value) {
            $newStudentsHealthRecords[] = $value['student_health_id'];
        }


        // $healthRecordsToAdd = array_diff($newStudentsHealthRecords, $currentStudentsHealthRecords);
        $healthRecordsToDelete = array_diff($currentStudentsHealthRecords, $newStudentsHealthRecords);
        // $healthRecordsToEdit = array_diff($newStudentshealthRecords, array_merge($healthRecordsToAdd, $healthRecordsToDelete));


        foreach ($data['health-problems'] as $value) {
            if ($value['student_health_id'] == null) {
                StudentHealthRecords::create([
                    'title' => $value['health_problem'],
                    'description' => $value['description'],
                    'student_id' => $data['student_id'],
                ]);
            } else {
                $stLang = StudentHealthRecords::find($value['student_health_id']);
                if ($stLang) {
                    $stLang->title = $value['health_problem'];
                    $stLang->description = $value['description'];
                    $stLang->save();
                }
            }
        }

        StudentHealthRecords::whereIn('id', $healthRecordsToDelete)->delete();

        $response = [
            'data' => '',
            'message' => trans('general.student_updated_successfully')
        ];
        return new JsonResponse($response, 201);
    }

    public function delete(Request $request)
    {
        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
        ], [], [])->validate();


        $student = Student::find($data['student_id']);
        $this->authorize('manage', $student);


        Student::where('id', $data['student_id'])->delete();

        return back()->with('success', trans('general.student_was_deleted'));
    }



    public function showDetailsView($id)
    {
        $validator = Validator::make(['id' => $id], [
            'id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
        ], [], []);
      

        $nationalities = Nationality::all();
        $religion = Religion::all();

        $languages = Language::all();
        $cities = Cities::orderBy('title')->get();
        $student = Student::select(
            'students.id as student_id',
            'students.first_name',
            'students.last_name',
            'students.birth_date',
            'students.birth_place',
            'students.gender',
            'students.city_id',
            'students.street',
            'students.area',
            'students.phone',
            'students.telephone',
            'students.emergency_phone',
            'students.emergency_kinship',
            'students.religion_id',
            'students.mother_id',
            'students.father_id',
            'students.division_id',
            'divisions.level_id',
            'student_transportations.id as transportation',
        )
            ->leftJoin('divisions', 'divisions.id', '=', 'students.division_id')
            ->leftJoin('student_transportations', 'student_transportations.student_id', '=', 'students.id')
            ->where("students.id", $id)->first();

        $this->authorize('manage', $student);


        $division = Division::find($student->division_id);
        $level = Level::find($division->level_id);
        $stage = Stage::find($level->stage_id);
        $city = Cities::find($student->city_id);
        $stages = Stage::all();
        $currentStage = Level::select('stage_id as id')->where('id', $student->level_id)->first();
        $levels = Level::select('levels.*')->where('stage_id', $currentStage->id)->distinct()
            ->join('divisions', 'divisions.level_id', '=', 'levels.id')->get();
        $mother = Parents::find($student->mother_id);
        $father = Parents::find($student->father_id);
        $schoolSequence = StudentLevels::where('student_id', $student->student_id)->get();
        $studentLanguages = StudentLanguage::where('student_id', $student->student_id)->get();
        $studentHealthRecords = StudentHealthRecords::where('student_id', $student->student_id)->get();
        $studentNationalities = StudentNationality::where('student_id', $id)->get();
        $studentNationalitiesIDs = [];
        foreach ($studentNationalities as $value) {
            $studentNationalitiesIDs[] = $value->nationality_id;
        }
    
        $religion = Religion::find($student->religion_id);
        $health=StudentHealthRecords::all()->where('student_id', $student->student_id);
        $record= StudentFinancialRecord::all()->where('student_id', $student->student_id);
        $studentexamgrades= StudentExamGrades::all()->where('student_id', $student->student_id);
                      
      $note=DB::table('student_notes')
     ->Join('student_notes_types','student_notes_types.id' , '=','student_notes.type_id')
     ->select('student_notes_types.type','student_notes_types.code','student_notes.*')
     ->where('student_id', $student->student_id)->get();          
                      
     $studentexamgrades=DB::table('student_exam_grades')
     ->Join('semester_exams','semester_exams.id' , '=','student_exam_grades.semester_exam_id')
     ->select('student_exam_grades.*' , 'semester_exams.*')
     ->where('student_id', $student->student_id)->get();

         return
       view('admin.students.students-view',[
            'students.id as student_id',
            'students.first_name'.'students.last_name',
            'students.last_name',
            'students.birth_date',
            'students.birth_place',
            'students.gender',
            'students.city_id',
            'students.street',
            'students.area',
            'students.phone',
            'students.telephone',
            'students.emergency_phone',
            'students.emergency_kinship',
            'students.religion_id',
            'students.mother_id',
            'students.father_id',
            'students.division_id',
            'divisions.level_id',
            'student_transportations.id as transportation'],
       compact('record','health','studentexamgrades','note','nationalities','religion','languages','cities','student'
       ,'division','level','stage','city','stages','currentStage','levels','mother','father','studentNationalitiesIDs'));
    }


    public function showStudentAbsenceView(AttendeesDataTable $attendeesDataTable, $student_id)
    {
        $student = Student::find($student_id);

        return $attendeesDataTable->with('student_id', $student_id)->render('admin.students.absence.student-absence', ['student' => $student]);
    }


    public function addAbsence(Request $request)
    {
        $data = ($request->all());
        $validator = Validator::make($data, [
            'student_id' => ['required', 'max:190', 'exists:App\Models\Student,id'],
            'status' => ['required', 'max:190'],
            'details' => ['required', 'max:190'],
            'date' => ['required', 'date'],
        ], [], [])->validate();

        $atendees = Attendees::create($validator);
        
        event(new NewAttendees($validator['student_id']));  
        
        $data = [
            "code" => 1,
            "data" => [],
            "msg" => trans('general.record_added_successfully')
        ];
         return  response($data, 200);
       
        
          /*  $student_id = $validator['student_id'];
            $parentsAccounts = ParentAccount::getParentsAccountsByStudent($student_id);
            $parentsAccounts->each(function ($parent) {
                $ddd = [
                    'parent_account_id' => $parent->id,
                    'message' => trans('general.attendees_notification_message',['student' => $parent->student_name]),
                    'title' => trans('general.attendees_title'),
                    'payload' => '{"page": "attendees", "student":"'.$parent->student_id.'"}',
                ];
                ParentNotification::create($ddd);
                $parent=new SendAttendeesNotification($parent->student_name);
                return new PrivateChannel('channel-name');
               
                    });*/
     }
   
    
    public function deleteAbsence(Request $request)
    {
        $data = ($request->all());
        $validator = Validator::make($data, [
            'record_id' => ['required', 'max:190', 'exists:App\Models\Attendees,id'],
        ], [], [])->validate();

        $record = Attendees::find($data['record_id']);

        try {
            $record->delete();
            return back()->with('success', trans('general.record_deleted_successfully'));
        } catch (\Illuminate\Database\QueryException $th) {
            return back()->withErrors(trans('general.record_foreign_key_delete_error'));
        } catch (\Throwable $th) {
            return back()->withErrors(trans('general.record_delete_error'));
        }
    }

    public function showStudentGradeView(StudentGradeDataTable $gradeTable, $student_id)
    {
        $result = DB::table('student_exam_grades')
        ->select('student_exam_grades.student_id as student_id',DB::raw('SUM(student_exam_grades.grade) as grade,semester_exams.quiz_type as quize_type'))
        ->join('semester_exams','semester_exams.id','=','student_exam_grades.semester_exam_id')
        ->where('student_exam_grades.student_id',$student_id)
        ->groupBy('semester_exams.quiz_type')->get();
    
   StudentCalcGrade::upsert([[
    
    'student_id'=>$result[0]->student_id,
    'quiz_one'=>$result[0]->grade??'',
    'quiz_final_one'=>$result[1]->grade??'',
    'quiz_two'=>$result[2]->grade??'',
    'quiz_final_two'=>$result[3]->grade??'',
   ]],
   ['student_id'],
   ['student_id','quiz_one','quiz_final_one','quiz_two','quiz_final_two']
);


       $student = Student::find($student_id);

    return $gradeTable->with('student_id', $student_id)->render('admin.students.students-grade', ['student' => $student]);
    }

public function createFromExcel(Request $request)
    {
        $data = ($request->all());
        $headerRowsNumber = 2;

        $validator = Validator::make($data, [
            'studentsExcel' => ['required', 'file'],
        ], [], [])->validate();


        $excelAsArray = (new StudentsImport)->toArray($request->file('studentsExcel'));

        $studentsData = [];
        foreach ($excelAsArray[0] as $key => $row) {

            //to ignore header rows
            if ($key < $headerRowsNumber) {
                continue;
            }

            //check if the row is empty
            $empty = true;
            foreach ($row as $value) {
                if ($value != null) {
                    $empty = false;
                    break;
                }
            }

            //if the row is empty it will be ignored
            if ($empty) {
                continue;
            }

            // store Excel file data in array orderly
            $studentsData[] = [
                'first_name' => $row[0],
                'last_name' => $row[1],
                'gender' => $row[2],
                'nationality' => $row[3],
                'birth_place' => $row[4],
                'birth_date' => $row[5],
                'religion' => $row[6],
                'stage' => $row[7],
                'division' =>$row[8],
                'level' => $row[9],
                'phone' => $row[10],
                'telephone' => $row[11],
                'total_installment' => $row[12],
                'mother_first_name' => $row[13],
                'mother_last_name' => $row[14],
                'mother_job' => $row[15],
                'mother_phone' => $row[16],
                'father_first_name' => $row[17],
                'father_last_name' => $row[18],
                'father_job' => $row[19],
                'father_phone' => $row[20],
                'emergency_phone' => $row[21],
                'emergency_kinship' => $row[22],
                'city' => $row[23],
                'area' => $row[24],
                'street' => $row[25],
            ];
        }


        $nationalities = Nationality::all();
        $religions = Religion::all();
        $stages = Stage::all();
        $levels = Level::all();
        $divisions = Division::all();
        $cities = Cities::all();
        $nationalitiesArray = [];
        $religionsArray = [];
        $divisionsArray = [];
        $stagesArray = [];
        $levelsArray = [];
        $citiesArray = [];

        foreach ($nationalities as $key => $nationality) {
            $nationalitiesArray[$nationality->id] = $nationality->title;
        }
        
        foreach ($religions as $key => $religion) {
            $religionsArray[$religion->id] = $religion->name;
        }

        foreach ($stages as $key => $stage) {
            $stagesArray[$stage->id] = $stage->code;
        }
        foreach ($divisions as $key => $division) {
            $divisionsArray[$division->id] = strtolower($division->code);
        }
        foreach ($levels as $key => $level) {
            $levelsArray[$level->id] = strtolower($level->code);
        }

        foreach ($cities as $key => $city) {
            $citiesArray[$city->id] = $city->code;
        }

        $escapedRows = [];
        $validationMessages = [];

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

            $currentExcelRow = $key + $headerRowsNumber + 1;

            //check data validation for excel file
            $validator = Validator::make($data, [
                'first_name' => ['required', 'max:190'],
                'last_name' => ['required', 'max:190'],
                'gender' => ['required', 'max:190', Rule::in(['m', 'f'])],
                'nationality' => ['required', 'max:190', function ($attribute, $value, $fail) use ($nationalitiesArray, &$studentsData, $key, $currentExcelRow) {
                    if ($res = array_search($value, $nationalitiesArray)) {
                        $studentsData[$key]['nationality'] = $res;
                    } else {
                        $fail(trans('general.excel_validation_rule_msg', ['attribute' => trans('general.' . $attribute), 'value' => $value, 'row' => $currentExcelRow]));
                    }
                }],
                'birth_place' => ['required', 'max:190'],
                'birth_date' => ['required', 'max:190'],
                'religion' => ['required', 'max:190', function ($attribute, $value, $fail) use ($religionsArray, &$studentsData, $key, $currentExcelRow) {
                    if ($res = array_search($value, $religionsArray)) {
                        $studentsData[$key]['religion'] = $res;
                    } else {
                        $fail(trans('general.excel_validation_rule_msg', ['attribute' => trans('general.' . $attribute), 'value' => $value, 'row' => $currentExcelRow]));
                    }
                }],
                'level' => ['required', 'max:190', function ($attribute, $value, $fail) use ($levelsArray, &$studentsData, $key, $currentExcelRow) {
                    if ($res = array_search(strtolower(trim($value)),  $levelsArray)) {
                        $studentsData[$key]['level'] = $res;
                    } else {
                        $fail(trans('general.excel_validation_rule_msg', ['attribute' => trans('general.' . $attribute), 'value' => $value, 'row' => $currentExcelRow]));
                    }
                }],
                'division' => ['required','max:190', function ($attribute, $value, $fail) use ($divisionsArray, &$studentsData, $key, $currentExcelRow) {
                    if ($res = array_search(strtolower(trim($value)), $divisionsArray)) {
                        $studentsData[$key]['division'] = $res;
                    } else {
                        $fail(trans('general.excel_validation_rule_msg', ['attribute' => trans('general.' . $attribute), 'value' => $value, 'row' => $currentExcelRow]));
                    }
                }],
                
                'stage' => ['required', 'max:190', function ($attribute, $value, $fail) use ($stagesArray, &$studentsData, $key, $currentExcelRow) {
                    if ($res = array_search($value, $stagesArray)) {
                        $studentsData[$key]['stage'] = $res;
                    } else {
                        $fail(trans('general.excel_validation_rule_msg', ['attribute' => trans('general.' . $attribute), 'value' => $value, 'row' => $currentExcelRow]));
                    }
                }],
                'phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/'],
                'telephone' => ['required', 'regex:/^([0-9]{9,10})$/',],
                'total_installment' => ['required', 'numeric'],

                'city' => ['required', 'max:190', function ($attribute, $value, $fail) use ($citiesArray, &$studentsData, $key, $currentExcelRow) {
                    if ($res = array_search($value, $citiesArray)) {
                        $studentsData[$key]['city'] = $res;
                    } else {
                        $fail(trans('general.excel_validation_rule_msg', ['attribute' => trans('general.' . $attribute), 'value' => $value, 'row' => $currentExcelRow]));
                    }
                }],
                'area' => ['required', 'max:190'],
                'street' => ['required', 'max:2550'],
                'emergency_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/'],
                'emergency_kinship' => ['required', 'max:190'],
                'mother_first_name' => ['required', 'max:190'],
                'mother_last_name' => ['required', 'max:190'],
                'mother_job' => ['required', 'max:190'],
                'mother_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/'],
                'father_first_name' => ['required', 'max:190'],
                'father_last_name' => ['required', 'max:190'],
                'father_job' => ['required', 'max:190'],
                'father_phone' => ['required', 'digits:9', 'regex:/^([1-9][0-9]*)$/'],
            ], [], []);


            if ($validator->fails()) {
                $validationMessages[] = $validator->messages();
                $escapedRows[] = $key;
                continue;
            }
           

            //check if parents are stored before in DB by phone number and get there id's
            $father = Parents::where('phone', $data['father_phone'])
                ->where('gender', 'male')->first();
            $mother = Parents::where('phone', $data['mother_phone'])
                ->where('gender', 'female')->first();
            if ($father) {
                $studentsData[$key]['father_id'] = $father->id;
            }
            if ($mother) {
                $studentsData[$key]['mother_id'] = $mother->id;
            }
        } // end $studentsData foreach


        $successCounter = 0;
   

        foreach ($studentsData as $key => $student) {

            if (in_array(($key), $escapedRows)) {
                continue;
            }

            DB::transaction(function () use ($student, &$successCounter, $escapedRows, $key) {
                $studRes;
                $mother_id = null;
                $father_id = null;
                if (isset($student['mother_id'])) {
                    $mother_id = $student['mother_id'];
                } else {
                    $mother_id = Parents::createAndGetId([
                        'first_name' => $student['mother_first_name'],
                        'last_name' => $student['mother_last_name'],
                        'job' => $student['mother_job'],
                        'phone' => $student['mother_phone'],
                        'gender' => 'female',
                    ]);
                }

                if (isset($student['father_id'])) {
                    $father_id = $student['father_id'];
                } else {
                    $father_id = Parents::createAndGetId([
                        'first_name' => $student['father_first_name'],
                        'last_name' => $student['father_last_name'],
                        'job' => $student['father_job'],
                        'phone' => $student['father_phone'],
                        'gender' => 'female',
                    ]);
                }



                // $divisionId = null;
                // $divisions = Division::getDivisionStudentsByLevelId($student['level']);

                // foreach ($divisions as $value) {
                //     if ($value->capacity >= $value->students) {
                //         $divisionId = $value->id;
                //         break;
                //     }
                //     $divisionId = $value->division;
                // }
                  try{
                $studRes = Student::createAndGetId([
                    'first_name' => $student['first_name'],
                    'last_name' => $student['last_name'],
                    'birth_date' => \Carbon\Carbon::create($student['birth_date']),
                    'birth_place' => $student['birth_place'],
                    'gender' => $student['gender'] == 'f'? 'female': 'male',
                    'city_id' => $student['city'],
                    'street' => $student['street'],
                    'area' => $student['area'],
                    'phone' => $student['phone'],
                    'telephone' => $student['telephone'],
                    'total_installment' => $student['total_installment'],
                    'emergency_phone' => $student['emergency_phone'],
                    'emergency_kinship' => $student['emergency_kinship'],
                    'religion_id' => $student['religion'],
                    'mother_id' => $mother_id,
                    'father_id' => $father_id,
                    'division_id' => $student['division'],
                    'transportation_id'=>null
                ]);
                
                $successCounter++;

                StudentNationality::create([
                    "nationality_id" => $student['nationality'],
                    "student_id" => $studRes,
                ]);
                 } catch(\Throwable $th){
                    dd($th, $student, $key, $escapedRows );
                }
                
            });
        }

        
        $validationMessages = json_decode(json_encode($validationMessages), true);

        $validationMessage = null;
        foreach ($validationMessages as $vms) {
            foreach ($vms as $messagesArray) {
                foreach ($messagesArray as  $messageText) {
                    $validationMessage .= $messageText . ' <br> ';
                }
            }
        }

        
        $data = [
            'success' => trans('general.students_excel_upload_res', ['success' => $successCounter, 'fail' => count($escapedRows)])
        ];

        if ($validationMessage) {
            $data['validation_msg'] = $validationMessage;
        }

        return back()->with($data);

    }


 
}
