<?php

namespace App\Http\Controllers\Admin\LMS;

use App\Http\Controllers\Controller;

use Illuminate\Http\Request;
use App\Helpers\AdminHelper;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use App\Models\Batch;
use App\Models\Admin;
use App\Models\Address;
use App\Models\Classes;
use App\Models\Slot;
use App\Models\Candidate;
use Modules\Plan\Entities\Plan_Category;
use Modules\Plan\Entities\Plan;
use App\Models\TestPreparationCourse;
use App\Models\TestPreparationCourseDayWise;
use App\Models\Task;
use Illuminate\Support\Facades\DB;
use App\Models\Order;
use App\Models\UsersMockTest;
use GuzzleHttp\Client;
use Firebase\JWT\JWT;
use Illuminate\Support\Facades\Http;



class BatchController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:admin');
    }
    public function index(Request $request)
    {

        abort_if(!userCan('batch.view'), 403);



        $query = Batch::query();

        $query->searchQuery($query);

        $totalCount = $query->count();

        $datas = $query->paginate(10)->withQueryString();


        return view('admin.LMS.batch.index', compact('datas', 'totalCount'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        abort_if(!userCan('batch.create'), 403);
        $address = Address::get(['id', 'address', 'office_name']);


        $role_AVAILABLE_TUTOR_ROLES = explode(',', env('AVAILABLE_TUTOR_ROLES', 'Tutor'));
        $admin_list_tutor = Admin::where('id', '!=', 1)
            ->whereHas('roles', function ($query) use ($role_AVAILABLE_TUTOR_ROLES) {
                $query->whereIn('name', $role_AVAILABLE_TUTOR_ROLES);
            })
            ->get()
            ->toArray();
        $planIds = TestPreparationCourse::where('status', 1)->pluck('plan_id')->toArray();
        $plans = Plan::whereIn('id', $planIds)->select('plan_category_id', 'id', 'title')->get()->toArray();


        return view('admin.LMS.batch.create', compact('address', 'admin_list_tutor', 'plans'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

        abort_if(!userCan('batch.create'), 403);
        /////////////////////////default Batch status == 0/////////////////////////////////////////////
        //    $validatedData['status'] = 0;
        $request['status'] = 0;
        $classTime = $request->input('class_time');
        $start_date = null;
        if (!empty($classTime)) {
            $start_date = Carbon::parse($request->input('start_date'))->tz(env('APP_TIMEZONE', 'UTC'))->setTimeFromTimeString($classTime)->format('Y-m-d H:i:s');
        }

        $tutor_id =  $request->input('tutor_id');
        $rules = [
            'batch_mode' => 'required|in:0,1',
            'status' => 'required',
            'batch_name' => 'required|string',
            'batch_code' => 'required|string|unique:batches,batch_code',
            'class_duration' => 'required|integer',
            'class_time' => 'required|date_format:H:i',
            'number_of_classes' => 'required|integer',
            'capacity' => 'required|integer',
            'address_id' => 'required|exists:addresses,id',
            'tutor_id' => 'required|integer',
            'notes' => 'nullable|string',
            'plan_id' => 'required|integer',
            'start_date' => 'required|date',
        ];

        // 'start_date' => [
        //     'required',
        //     'date',
        //     'after_or_equal:'.now(),
        //     function ($attribute, $value, $fail) use ($tutor_id, $start_date) {
        //         $exists = DB::table('batches')
        //             ->where('tutor_id', $tutor_id)
        //             ->whereRaw("? BETWEEN start_date AND DATE_ADD(start_date, INTERVAL class_duration MINUTE)", [$start_date])
        //             ->exists();


        //         if ($exists) {
        //             $fail('The selected start date is not unique or conflicts with an existing class.');
        //         }
        //     },

        // ],


        $validatedData = $request->validate($rules);

        try {

            DB::beginTransaction(); // Start transaction


            $userId =  Auth::User()->id;
            $validatedData['created_by'] = $userId;
            $validatedData['updated_by'] = $userId;
            $user_ids = null;
            if (!empty($request->user_ids)) {
                $user_ids = implode(",", $request->user_ids);

                $userIdsCount = count($request->user_ids);
                if ($userIdsCount > $validatedData['capacity']) {
                    return redirect()->back()->withErrors(['user_ids' => 'Number of users exceeds batch capacity.']);
                }
            }

            $validatedData['user_ids'] = $user_ids;
            $validatedData['meeting_id'] = $request->meeting_id ?? null;
            $validatedData['meeting_password'] = $request->meeting_password ?? null;



            $batch = Batch::create($validatedData);


            $batch->candidates()->detach();

            // Attach new candidates if provided
            if (isset($request->user_ids) && $request->user_ids) {
                $batch->candidates()->attach($request->user_ids);
            }



            if (!empty($batch->number_of_classes)) {

                $old_class = Classes::where("batch_id", $batch->id)->latest()->first();

                $batchDate = @$old_class->start_date ?? $batch->start_date;
                $batchDate = Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC'));
                $classTime = $batch->class_time;
                $courseid = TestPreparationCourse::where('plan_id', $batch->plan_id)->where('status', 1)->pluck('id')->first();
                for ($i = 1; $i <= $batch->number_of_classes; $i++) {

                    $data = null;
                    if ($i != 1) {
                        $batchDate = AdminHelper::getNextWorkingDay(Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC')))->toDateString();
                    }
                    if ($classTime) {
                        $batchDate = Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC'))->setTimeFromTimeString($classTime);
                    }
                    $courseDayWise = [];
                    $courseDayWise = TestPreparationCourseDayWise::where('course_id', $courseid)
                        ->where('day', $i)
                        ->first();


                    $data = [
                        'class_name' => @$courseDayWise->topic ?? $batch->batch_name . " Class" . $i,
                        'class_code' => $batch->batch_code . "Cl00" . $i,
                        'class_mode' => $batch->batch_mode,
                        'batch_id' => $batch->id,
                        'start_date' => $batchDate,
                        'day' => $i,
                        'tutor_id' => $batch->tutor_id,
                        'address_id' => $batch->address_id,
                        'status' => $batch->status,
                        'created_by' => $batch->created_by,
                        'updated_by' => $batch->updated_by,
                        'description' => @$courseDayWise->description ?? null,
                        'document_links' => @$courseDayWise->document_links ?? null,
                        'module_name' => @$courseDayWise->module_name ?? null,
                        'recording_status' => @$courseDayWise->recording_status ?? 0,
                        'class_duration' => @$courseDayWise->duration ?? $batch->class_duration,
                        'task_module' => @$courseDayWise->task_module ?? null,
                        'task_name' => @$courseDayWise->task_name ?? null,
                        'task_description' => @$courseDayWise->task_description ?? null,
                        'task_links' => @$courseDayWise->task_links ?? null,
                        'study_material' => @$courseDayWise->study_material ?? null,
                    ];

                    $classes = Classes::create($data);

                    if (@$classes->module_name && @$batch->user_ids) {
                        $userIds = explode(",", $batch->user_ids);
                        foreach ($userIds as $userId) {
                            // $taskdata = null;
                            // $taskdata = [
                            //     'task_module' => @$classes->task_module ?? null,
                            //     'task_name' => @$classes->task_name ?? null,
                            //     'task_description' => @$classes->task_description ?? null,
                            //     'task_links' => @$classes->task_links ?? null,
                            //     'assign_date' => $batchDate,
                            //     'class_id' => @$classes->id ?? null,
                            //     'created_by' => $batch->created_by,
                            //     'user_id' => $userId
                            // ];

                            // Task::create($taskdata);

                            $decodedDescription = json_decode($classes->task_description, true);
                            if (!empty($decodedDescription)) {
                                // First, delete existing tasks for the current user and class
                                Task::where('class_id', $classes->id)
                                    ->where('user_id', $userId)
                                    ->delete();
                                // Then, create new tasks based on the decoded description
                                foreach ($decodedDescription as $description) {
                                    $taskdata = [
                                        'task_module' => $classes->task_module ?? null,
                                        'assign_date' => $batchDate,
                                        'class_id' => $classes->id ?? null,
                                        'created_by' => $batch->created_by,
                                        'updated_by' => $batch->updated_by,
                                        'user_id' => $userId,
                                        'task_name' => $description['name'] ?? null,
                                        'task_links' => $description['link'] ?? null,
                                        'task_duration' => $description['duration'] ?? null,
                                        'task_type' => $description['type'] ?? null,
                                        'mock_test' => $description['mock_test'] ?? null,
                                        'mock_test_type' => $description['mock_test_type'] ?? null,
                                        'test_type' => @$description['test_type'] ?? null,

                                    ];
                                    $taskGet = Task::create($taskdata);

                                    // Check if the task type is "Mock test"
                                    if (!empty($taskGet) && @$taskGet->task_type == "Mock test" || @$taskGet->task_type == "Practice test") {

                                        $usersMockTests = UsersMockTest::where('class_id', $classes->id)
                                            ->where('user_id', $userId)
                                            ->where('ielts_test_ids',  $taskGet->mock_test)
                                            ->get();
                                        if ($usersMockTests->isNotEmpty()) {
                                            $usersMockTests->each(function ($userMockTest) {
                                                $userMockTest->delete();
                                            });
                                        }

                                        // Create a new UsersMockTest record
                                        $mockTest = [
                                            'test_type' => $taskGet->mock_test_type,
                                            'available_at' => $classes->start_date,
                                            'class_id' => $classes->id,
                                            'user_id' => $userId,
                                            'ielts_test_ids' => $taskGet->mock_test,
                                            'category' => $taskGet->task_type == "Mock test" ? "M" : ($taskGet->task_type == "Practice test" ? "P" : "M"),
                                        ];

                                        UsersMockTest::create($mockTest);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            DB::commit();

            // if ($batch->batch_mode == "1") {
            //     $batchDateAndTime = Carbon::parse($batch->start_date)
            //         ->tz(config('app.timezone', 'UTC'))
            //         ->setTimeFromTimeString($batch->class_time);

            //     // Call Zoom API to create meeting
            //     $meetingData = $this->createMeeting([
            //         'topic' => $batch->batch_name,
            //         'start_time' => $batchDateAndTime->format('Y-m-d\TH:i:s'),
            //         'duration' => $batch->class_duration,
            //     ]);

            //     // Update batch with meeting ID and password
            //     $batch->update([
            //         'meeting_id' => $meetingData['meeting_id'],
            //         'meeting_password' => $meetingData['meeting_password'],
            //     ]);
            // }

            flashSuccess("Batch created successfully!");
            if (userCan('batch.update') && @$batch->id) {
                return redirect()->route('admin.batch.edit', ['batch' => $batch->id]);
            } else {
                return redirect()->route('admin.batch.index');
            }
        } catch (\Exception $e) {
            DB::rollBack(); // Roll back transaction if an exception occurs
            flashError(__('something_went_wrong' . $e->getMessage()));
            return back()->withInput();
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        abort_if(!userCan('batch.update'), 403);
        $batch = Batch::where('id', $id)->first();
        if ($batch) {
            $address = Address::get(['id', 'address', 'office_name']);
            $slots = Slot::where('status', 1)->get(['id', 'name', 'time_to', 'time_from']);

            $role_AVAILABLE_TUTOR_ROLES = explode(',', env('AVAILABLE_TUTOR_ROLES', 'Tutor'));
            $admin_list_tutor = Admin::where('id', '!=', 1)
                ->whereHas('roles', function ($query) use ($role_AVAILABLE_TUTOR_ROLES) {
                    $query->whereIn('name', $role_AVAILABLE_TUTOR_ROLES);
                })
                ->get()
                ->toArray();
            $planIds = TestPreparationCourse::where('status', 1)->pluck('plan_id')->toArray();
            $planIds[] = $batch->plan_id;
            $plans = Plan::whereIn('id', $planIds)->select('plan_category_id', 'id', 'title')->get()->toArray();

            return view('admin.LMS.batch.edit', compact('batch', 'address', 'admin_list_tutor', 'plans'));
        } else {
            flashError("Batch not found.");
            return back();
        }
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {


        abort_if(!userCan('batch.update'), 403);

        $batch = Batch::find($id);
  
        $this->getMeetings();
        dd("edit page");
        if ($batch->batch_mode == "1") {
        // $batchDateAndTime = Carbon::parse($batch->start_date)
        //         ->tz(config('app.timezone', 'UTC'))
        //         ->setTimeFromTimeString($batch->class_time);
        //     $getToken = $this->getZoomAccessToken();
           
        //     if ($getToken) {
        //         $meetingData = $this->create_a_zoom_meeting([
        //             'topic'      => $batch->batch_name,
        //             'start_time' => $batchDateAndTime->format('Y-m-d\TH:i:s'),
        //             'agenda'     => $batch->batch_name,
        //             'jwtToken'   => $getToken,
        //         ]);

        //     }
            // $batchDateAndTime = Carbon::parse($batch->start_date)
            //     ->tz(config('app.timezone', 'UTC'))
            //     ->setTimeFromTimeString($batch->class_time);

            // // Call Zoom API to create meeting
            // $meetingData = $this->createMeeting([
            //     'topic' => $batch->batch_name,
            //     'start_time' => $batchDateAndTime->format('Y-m-d\TH:i:s'),
            //     'duration' => $batch->class_duration,
            // ]);

            //  $meetingData = $this->createMeeting($batch);
            $accessToken = $this->getZoomAccessToken();
            // $getToken = $this->get_oauth_step_2($accessToken);
dd($accessToken);
            if ($getToken['success']) {

                $get_zoom_details = $this->create_a_zoom_meeting([
                    'topic'      => 'Interview With Code-180',
                    'start_time' => date('Y-m-d\TH:i:00') . 'Z',
                    'agenda'     => "We are having interview with @code-180",
                    'jwtToken'   => $getToken['response']['access_token'],
                ]);

                if ($get_zoom_details['success']) {
                    $get_zoom_details['access_token'] = $getToken['response']['access_token'];
                    return view('admin.LMS.zoom.index')->with('respond', json_encode($get_zoom_details));
                } else {
                    // Handle error from create_a_zoom_meeting function
                    return view('admin.LMS.zoom.index')->with('respond', json_encode($get_zoom_details));
                }
            } else {
                // Handle error from get_oauth_step_2 function
                return view('admin.LMS.zoom.index')->with('respond', json_encode($getToken));
            }

            dd($meetingData);

            // Update batch with meeting ID and password
            // $batch->update([
            //     'meeting_id' => $meetingData['meeting_id'],
            //     'meeting_password' => $meetingData['meeting_password'],
            // ]);
        }

        return redirect()->route('admin.batch.index');

        $rules = [
            'batch_mode' => 'required|in:0,1',
            'batch_name' => 'required|string|',
            'batch_code' => 'required|string|unique:batches,batch_code,' . $id,
            'class_duration' => 'required|integer',
            'number_of_classes' => 'required|integer',
            'capacity' => 'required|integer',
            'address_id' => 'required|exists:addresses,id',
            'tutor_id' => 'required|integer',
            'notes' => 'nullable|string',
            'plan_id' => 'required|integer',
            'class_time' => 'required|date_format:H:i',
            'start_date' => 'required|date',

        ];

        $validatedData = $request->validate($rules);
        $validatedData['status'] = @$request->status;

        if ($batch) {

            $userId = Auth::user()->id;

            $validatedData['updated_by'] = $userId;
            $user_ids = null;
            if (!empty($request->user_ids)) {
                $user_ids = implode(",", $request->user_ids);
                $userIdsCount = count($request->user_ids);
                if ($userIdsCount > $validatedData['capacity']) {
                    return redirect()->back()->withErrors(['user_ids' => 'Number of users exceeds batch capacity.']);
                }
            }
            $validatedData['user_ids'] = $user_ids;

            $validatedData['meeting_id'] = $request->meeting_id ?? null;
            $validatedData['meeting_password'] = $request->meeting_password ?? null;


            $batch->update($validatedData);



            if (isset($request->user_ids) && $request->user_ids) {
                DB::table('batch_user')
                    ->where('batch_id', $batch->id)
                    ->update(['updated_at' => now(env('APP_TIMEZONE', 'UTC'))]);
                $batch->candidates()->sync($request->user_ids);
                $batch->candidates()->touch();
            }

            $currentDate = Carbon::now();

            Classes::where('batch_id', $batch->id)
                ->whereDate('start_date', '>', $currentDate)
                ->update(['status' => $validatedData['status'], 'class_mode' => $validatedData['batch_mode']]);

            Classes::where('batch_id', $batch->id)
                ->whereDate('start_date', '<', $currentDate)
                ->update(['status' => 0, 'class_mode' => $validatedData['batch_mode']]);

            for ($i = 1; $i <= $batch->number_of_classes; $i++) {

                $class = Classes::where('batch_id', $batch->id)
                    ->whereDate('start_date', '>', $currentDate)
                    ->where('day', $i)
                    ->first();

                if ($class && $batch->user_ids) {
                    $userIds = explode(",", $batch->user_ids);

                    foreach ($userIds as $userId) {

                        $decodedDescription = json_decode($class->task_description, true);
                        if (!empty($decodedDescription)) {
                            // First, delete existing tasks for the current user and class

                            $tasks = Task::where('class_id', $class->id)
                                ->where('user_id', $userId)
                                ->get();

                            if ($tasks->isNotEmpty()) {
                                $tasks->each(function ($task) {
                                    $task->delete();
                                });
                            }

                            // Then, create new tasks based on the decoded description
                            foreach ($decodedDescription as $description) {
                                $taskdata = [
                                    'task_module' => $class->task_module ?? null,
                                    'assign_date' => $class->start_date,
                                    'class_id' => $class->id ?? null,
                                    'created_by' => $batch->created_by,
                                    'updated_by' => Auth::user()->id,
                                    'user_id' => $userId,
                                    'task_name' => $description['name'] ?? null,
                                    'task_links' => $description['link'] ?? null,
                                    'task_duration' => $description['duration'] ?? null,
                                    'task_type' => $description['type'] ?? null,
                                    'mock_test' => $description['mock_test'] ?? null,
                                    'mock_test_type' => $description['mock_test_type'] ?? null,
                                    'test_type' => @$description['test_type'] ?? null,
                                ];
                                $taskGet = Task::create($taskdata);

                                // Check if the task type is "Mock test"
                                if (!empty($taskGet) && @$taskGet->task_type == "Mock test" || @$taskGet->task_type == "Practice test") {

                                    $usersMockTests = UsersMockTest::where('class_id', $class->id)
                                        ->where('user_id', $userId)
                                        ->where('ielts_test_ids',  $taskGet->mock_test)
                                        ->get();
                                    if ($usersMockTests->isNotEmpty()) {
                                        $usersMockTests->each(function ($userMockTest) {
                                            $userMockTest->delete();
                                        });
                                    }
                                    // Create a new UsersMockTest record
                                    $mockTest = [
                                        'test_type' => $taskGet->mock_test_type,
                                        'available_at' => $class->start_date,
                                        'class_id' => $class->id,
                                        'user_id' => $userId,
                                        'ielts_test_ids' => $taskGet->mock_test,
                                    ];

                                    UsersMockTest::create($mockTest);
                                }
                            }
                        }
                    }
                }
            }

            flashSuccess("Batch Update successfully!");

            return redirect()->route('admin.batch.index');
        } else {
            flashError("Batch not found.");
            return back();
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */

    public function destroy($id)
    {

        try {
            $batch = Batch::findOrFail($id);

            // Delete associated classes
            $deletedClassesCount = Classes::where('batch_id', $id)->delete();

            $batch->deleted_by =  Auth::user()->id;
            $batch->save();

            // Delete the batch
            $batch->delete();

            flashSuccess("Batch Deleted Successfully!");
        } catch (\Exception $e) {
            // Handle any potential exceptions
            flashError("Failed to delete batch: " . $e->getMessage());
        }

        return redirect()->back();
    }



    function generateSlotTime($item)
    {
        $slot_time = null;

        if (isset($item['slot_name'], $item['time_to'], $item['time_from'])) {
            $timeTo = TimeShowHourseMiniteAmPm($item['time_to']);
            $timeFrom = TimeShowHourseMiniteAmPm($item['time_from']);

            if ($timeTo && $timeFrom) {
                $slot_time = "{$item['slot_name']} Time ({$timeTo} to {$timeFrom})";
            } else {
                $slot_time = "Invalid time format";
            }
        } else {
            $slot_time = "Missing keys in item array";
        }

        return $slot_time;
    }
    public function calendarEvent(Request $request)
    {

        $searchName = $request->input('keyword');

        $query = Classes::query();
        $query->where('classes.batch_id', $request->input('batch_id'));
        $query->select([
            'classes.id',
            'classes.class_name AS title',
            'classes.class_code AS class_code',
            'classes.class_mode',
            'classes.status AS class_status',
            'classes.created_at',
            'classes.created_by',
            'classes.tutor_id',
            'classes.class_duration AS classDuration',
            'classes.day AS classDay',
            'classes.start_date AS start',
            DB::raw("CONCAT(DATE(classes.start_date), ' ', TIME(CAST(classes.start_date AS TIME) + INTERVAL classes.class_duration * 60 SECOND)) AS end"),
            'classes.batch_id',
            'batches.batch_name AS batch_name',
            'batches.batch_code AS batch_code',
            'batches.batch_mode',

        ]);

        $query->leftJoin('batches', function ($join) {
            $join->on('batches.id', '=', 'classes.batch_id');
        });



        // if (request('start')) {
        //     $startDate = Carbon::parse(request('start'));
        //     $query->whereDate('followups.datetime', '>=', $startDate->format('Y-m-d'));
        // }

        // if (request('end')) {
        //     $toDate = Carbon::parse(request('end'));
        //     $query->whereDate('followups.datetime', '<=', $toDate->format('Y-m-d'));
        // }

        if (!empty($searchName)) {
            // $query->whereHas('user', function ($userQuery) use ($searchName) {
            //     $userQuery->where('name', 'LIKE', "%$searchName%")
            //     ->orWhere('email', 'LIKE', "%$searchName%")
            //     ->orWhere('id', $searchName)
            //     ->orWhere('phone', 'LIKE', "%$searchName%");
            // });
        }


        $data = $query->get()->toArray();



        $formattedData = [];

        foreach ($data as $item) {
            $formattedItem = [
                'id' => $item['id'],
                'title' => $item['title'],
                'class_code' => $item['class_code'] ?? null,
                'class_mode' => $item['class_mode'] == 1 ? 'Online' : 'Offline',
                'batch_id' => $item['batch_id'] ?? null,
                'batch_name' => $item['batch_name'] ?? null,
                'batch_code' => $item['batch_code'] ?? null,
                'batch_mode' => $item['batch_mode'] ?? null,
                'created_at' => dateMonthTimeFormat($item['created_at']) ?? null,
                'created_by' => adminIdToNameGet($item['created_by']) ?? null,
                'tutor_id' => adminIdToNameGet($item['tutor_id']) ?? null,
                'class_date' => dateMonthTimeFormat($item['start']) ?? null,
                'start' => $item['start'],
                'end' => $item['end'],
                'classDuration' => $item['classDuration'],
                'classDay' => $item['classDay'],
                'class_status' => $item['class_status'] == 1 ? 'Active' : 'Inactive',


            ];

            // Push the formatted item into the result array
            $formattedData[] = $formattedItem;
        }


        return response()->json($formattedData);
    }


    public function calendareventDrop(Request $request, $id)
    {

        try {
            DB::beginTransaction();
            // $batches = Batch::select('start_date','end_date')->where('id', $request->input('batch_id'))->first();
            $batches = Batch::select('*', DB::raw("DATE_ADD(start_date, INTERVAL number_of_classes DAY) AS end_date"))->where('id', $request->input('batch_id'))->first();

            $classes = Classes::where('batch_id', $request->input('batch_id'))->get();

            if (
                null != $batches &&
                null != $batches->start_date &&
                null != $batches->end_date &&
                null != $request->input('start_date')
            ) {
                $startDate = Carbon::parse($batches->start_date)->tz(env('APP_TIMEZONE', 'UTC'))->startOfDay()->format('Y-m-d H:i:s');
                $endDate = Carbon::parse($batches->end_date)->tz(env('APP_TIMEZONE', 'UTC'))->endOfDay()->format('Y-m-d H:i:s');
                $inputDate = Carbon::parse($request->input('start_date'))->tz(env('APP_TIMEZONE', 'UTC'))->startOfDay()->format('Y-m-d H:i:s');


                // if ($inputDate < $startDate || $inputDate > $endDate) {
                //     return response()->json(['success' => false, 'message' => 'Invalid date range'], 200);
                // }

                foreach ($classes as $existingClass) {
                    $existingStartDate = Carbon::parse($existingClass->start_date)->tz(env('APP_TIMEZONE', 'UTC'))->startOfDay()->format('Y-m-d H:i:s');
                    ///////////////////// Check if the new date range overlaps with existing class date range//////////////////////

                    if ($inputDate <= $existingStartDate && $inputDate >= $existingStartDate) {

                        return response()->json(['success' => false, 'message' => 'Class dates overlap with existing classes'], 200);
                    }
                }
            } else {
                return response()->json(['success' => false, 'message' => 'Invalid data provided'], 200);
            }


            $event = Classes::findOrFail($id);
            $event->start_date = $request->input('start_date');

            $event->save();
            $batchDate = @$event->start_date ?? $batches->start_date;

            $batchDate = Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC'));

            if ($event->day && @$batches->id) {
                $classTime = $batches->class_time;
                for ($i = $event->day; $i <= $batches->number_of_classes; $i++) {

                    $data = null;
                    $taskGet = null;
                    if ($i != $event->day) {

                        $batchDate = AdminHelper::getNextWorkingDay(Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC')))->toDateString();
                    }
                    if ($classTime) {
                        $batchDate = Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC'))->setTimeFromTimeString($classTime);
                    }


                    $data['start_date'] = $batchDate;
                    $data['day'] = $i;
                    $data['updated_by'] = Auth::user()->id;

                    $class = Classes::where('batch_id', $batches->id)
                        ->where('day', $i)
                        ->first();

                    if ($class) {
                        $class->update($data);
                    }


                    if ($class && $batches->user_ids) {
                        $userIds = explode(",", $batches->user_ids);

                        foreach ($userIds as $userId) {

                            $decodedDescription = json_decode($class->task_description, true);
                            if (!empty($decodedDescription)) {
                                // First, delete existing tasks for the current user and class

                                $tasks = Task::where('class_id', $class->id)
                                    ->where('user_id', $userId)
                                    ->get();





                                if ($tasks->isNotEmpty()) {
                                    $tasks->each(function ($task) {
                                        $task->delete();
                                    });
                                }

                                // Then, create new tasks based on the decoded description
                                foreach ($decodedDescription as $description) {
                                    $taskdata = [
                                        'task_module' => $class->task_module ?? null,
                                        'assign_date' => $batchDate,
                                        'class_id' => $class->id ?? null,
                                        'created_by' => $batches->created_by,
                                        'updated_by' => Auth::user()->id,
                                        'user_id' => $userId,
                                        'task_name' => $description['name'] ?? null,
                                        'task_links' => $description['link'] ?? null,
                                        'task_duration' => $description['duration'] ?? null,
                                        'task_type' => $description['type'] ?? null,
                                        'mock_test' => $description['mock_test'] ?? null,
                                        'mock_test_type' => $description['mock_test_type'] ?? null,
                                        'test_type' => @$description['test_type'] ?? null,
                                    ];
                                    // Create a new Task record
                                    $taskGet = Task::create($taskdata);

                                    // Check if the task type is "Mock test"
                                    if (!empty($taskGet) && @$taskGet->task_type == "Mock test" || @$taskGet->task_type == "Practice test") {

                                        $usersMockTests = UsersMockTest::where('class_id', $class->id)
                                            ->where('user_id', $userId)
                                            ->where('ielts_test_ids',  $taskGet->mock_test)
                                            ->get();
                                        if ($usersMockTests->isNotEmpty()) {
                                            $usersMockTests->each(function ($userMockTest) {
                                                $userMockTest->delete();
                                            });
                                        }
                                        // Create a new UsersMockTest record
                                        $mockTest = [
                                            'test_type' => $taskGet->mock_test_type,
                                            'available_at' => $class->start_date,
                                            'class_id' => $class->id,
                                            'user_id' => $userId,
                                            'ielts_test_ids' => $taskGet->mock_test,
                                            'category' => $taskGet->task_type == "Mock test" ? "M" : ($taskGet->task_type == "Practice test" ? "P" : "M"),
                                        ];

                                        UsersMockTest::create($mockTest);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            DB::commit();
            return response()->json(['success' => true, 'message' => 'Event updated successfully'], 200);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }


    public function searchCandidate(Request $request)
    {

        $user_name = $request->input('term');
        $list = [];

        if (isset($user_name['term']) && $user_name['term'] != "") {
            $list = Candidate::join('users', 'candidates.user_id', '=', 'users.id')
                ->where(function ($query) use ($user_name) {
                    $query->whereNull('users.deleted_at')
                        ->where(function ($query) use ($user_name) {
                            $query->where('users.name', 'like', '%' . $user_name['term'] . '%')
                                ->orWhere('users.id', 'like', '%' . $user_name['term'] . '%');
                        });
                })
                ->orderBy('users.name', 'asc')
                ->select('candidates.id', 'users.name as name', 'candidates.user_id')
                ->whereNull('candidates.deleted_at')
                ->limit(100)
                ->get();
        }

        if (isset($request->id)) {
            $list = Candidate::join('users', 'candidates.user_id', '=', 'users.id')
                ->whereIn('candidates.user_id', $request->id) // Use whereIn for multiple selections
                ->select('candidates.id', 'users.name as name', 'candidates.user_id')
                ->get();
        }

        return response()->json($list);
    }


    public function getplanByCategoryId(Request $request)
    {

        $category_id = $request->input('category_id');
        $list = [];
        if ($category_id) {
            $list = Plan::where('plan_category_id', $category_id)
                ->select('plan_category_id', 'id', 'title')
                ->get()->toArray();
        }

        return response()->json($list);
    }

    public function planGetBacthData(Request $request)
    {
        $plan_id = $request->input('plan_id');
        $data = [
            'number_of_classes' => null,
            'class_duration' => null
        ];

        if ($plan_id) {
            $testPreparationCourse = TestPreparationCourse::where('status', 1)
                ->where('plan_id', $plan_id)
                ->leftJoin('test_preparation_course_day_wises', 'test_preparation_course_day_wises.course_id', '=', 'test_preparation_courses.id')
                ->select('test_preparation_courses.id', 'test_preparation_courses.duration as number_of_classes', 'test_preparation_course_day_wises.duration as class_duration')
                ->first();

            if ($testPreparationCourse) {
                $data['number_of_classes'] = @$testPreparationCourse->number_of_classes ?? null;
                $data['class_duration'] = @$testPreparationCourse->class_duration ?? null;
            }
        }

        return response()->json($data);
    }


    // public function getUserByPlanId(Request $request)
    // {

    //     $plan_id = $request->input('planId');
    //     $list = [];
    //     $lists = [];
    //     $user_ids = [];

    //     if ($plan_id) {
    //         // Retrieve user IDs associated with the specified plan ID and status "paid"
    //         $user_ids = Order::where('plan_id', $plan_id)
    //             ->where('status', 'paid')
    //             ->with('candidate:id,user_id') // Eager load the 'candidate' relationship and select only the 'user_id' column
    //             ->get()
    //             ->pluck('candidate.user_id') // Pluck the 'user_id' from the loaded candidate relationship
    //             ->toArray();

    //         // Retrieve user IDs associated with batches of the specified plan ID
    //         $batchUserids = Batch::where('plan_id', $plan_id)
    //             ->pluck('user_ids')
    //             ->toArray();

    //         // Process batch user IDs
    //         if (!empty($batchUserids)) {
    //             // Loop through each batch user IDs array and explode it
    //             foreach ($batchUserids as $batchUserid) {
    //                 if (!empty($batchUserid)) {
    //                     $batchUserIdsArray = explode(",", $batchUserid);
    //                     $list = array_merge($list, $batchUserIdsArray);
    //                 }
    //             }
    //         }

    //         $uncommonUserIds = array_merge(array_diff($list, $user_ids) + array_diff($user_ids, $list));

    //         if (!empty($request->userIds)) {
    //             $uncommonUserIds  = array_merge($uncommonUserIds, $request->userIds);
    //         }


    //         $lists = User::whereIn('id', $uncommonUserIds)
    //             ->select('id', 'name')
    //             ->get()->toArray();
    //     }

    public function getUserByPlanId(Request $request)
    {

        $plan_id = $request->input('planId');
        $list = [];
        $lists = [];
        $user_ids = [];


        if ($plan_id) {
            // Retrieve user IDs associated with the specified plan ID and status "paid"
            $user_ids = Order::where('plan_id', $plan_id)
                ->where('status', 'paid')
                ->with('candidate:id,user_id') // Eager load the 'candidate' relationship and select only the 'user_id' column
                ->get()
                ->pluck('candidate.user_id') // Pluck the 'user_id' from the loaded candidate relationship
                ->toArray();



            // Retrieve user IDs associated with batches of the specified plan ID
            // $batchUserids = Batch::where('plan_id', $plan_id)
            //     ->pluck('user_ids')
            //     ->toArray();

            $batchids = Batch::where('plan_id', $plan_id)
                ->where('status', 1)
                ->pluck('id')
                ->toArray();

            $batchUserids =  DB::table('batch_user')->whereIn('batch_id', $batchids)
                ->pluck('user_id')
                ->toArray();

            // Process batch user IDs
            if (!empty($batchUserids)) {
                // Loop through each batch user IDs array and explode it
                $list = $batchUserids;
                // foreach ($batchUserids as $batchUserid) {
                //     if (!empty($batchUserid)) {
                //         $batchUserIdsArray = explode(",", $batchUserid);
                //         $list = array_merge($list, $batchUserIdsArray);
                //     }
                // }
            }

            $uncommonUserIds = array_merge(array_diff($list, $user_ids) + array_diff($user_ids, $list));

            $uncommonUserIds = array_diff($uncommonUserIds, $list);

            if (!empty($request->userIds)) {
                $uncommonUserIds  = array_merge($uncommonUserIds, @$request->userIds);
            }
            $uncommonUserIds = array_map('intval', array_filter($uncommonUserIds, 'is_numeric'));
            //   dd($uncommonUserIds);

            $lists = User::whereIn('id', $uncommonUserIds)
                ->select('id', 'name')
                ->get()->toArray();
        }

        // You can do additional processing here if needed

        return response()->json($lists);
    }


    public function getBatchCode(Request $request)
    {

        $address_id = $request->input('address_id');

        // Call the helper function to get the batch code
        $batch_code = AdminHelper::getBatchCode($address_id);
        if ($request->ajax()) {
            // Return the batch code as JSON response
            return response()->json($batch_code);
        } else {
            return $batch_code;
        }
    }

    // public function getZoomAccessToken()
    // {
    //     $clientId = env("ZOOM_CLIENT_ID");
    //     $clientSecret = env("ZOOM_CLIENT_SECRECT");
    
    //     $url = 'https://zoom.us/oauth/token';
    
    //     $data = [
    //         'grant_type' => 'client_credentials',
    //         'client_id' => $clientId,
    //         'client_secret' => $clientSecret,
    //     ];
    
    //     $ch = curl_init($url);
    //     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    //     curl_setopt($ch, CURLOPT_POST, true);
    //     curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    
    //     $response = curl_exec($ch);
    
    //     curl_close($ch);
    
    //     return json_decode($response, true)['access_token'];
    // }

    //++++++++++++++++++++++++++++++++++++++++++++++++
    //++++++++++++++++++++++++++++++++++++++++++++++++
    // private function get_oauth_step_1()
    // {
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     $redirectURL  = 'https://beta.teamgradding.com/admin/LMS/zoom/meetingCreate';
    //     $authorizeURL = 'https://zoom.us/oauth/authorize';
    //     //++++++++++++++++++++++++++++++++++++++++++++++++++
    //     $clientID     = env("ZOOM_CLIENT_ID");
    //     $clientSecret = env("ZOOM_CLIENT_SECRECT");
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     $authURL = $authorizeURL . '?client_id=' . $clientID . '&redirect_uri=' . $redirectURL . '&response_type=code&scope=&state=xyz';
    //     // $authURL = $authorizeURL . '?client_id=' . $clientID . '&redirect_uri=' . urlencode('https://beta.gradding.com/admin/LMS/zoom/meetingCreate') . '&response_type=code&scope=meeting:write meeting:write:admin&state=xyz';
    //     // $authURL = $authorizeURL . '?client_id=' . $clientID . '&redirect_uri=' . urlencode('https://beta.gradding.com/admin/LMS/zoom/meetingCreate') . '&response_type=code&scope=meeting:write meeting:write:admin&state=xyz';

    //     header('Location: ' . $authURL);
    //     exit;
    // }


    // private function create_a_zoom_meeting($meetingConfig = [])
    // {
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     $requestBody = [
    //         'topic'      => $meetingConfig['topic'] ?? 'New Meeting General Talk',
    //         'type'       => $meetingConfig['type'] ?? 2,
    //         'start_time' => $meetingConfig['start_time'] ?? date('Y-m-dTh:i:00') . 'Z',
    //         'duration'   => $meetingConfig['duration'] ?? 30,
    //         'password'   => $meetingConfig['password'] ?? mt_rand(),
    //         'timezone'   => 'Asia/Kolkata',
    //         'agenda'     => $meetingConfig['agenda'] ?? 'Interview Meeting',
    //         'settings'   => [
    //             'host_video'        => false,
    //             'participant_video' => true,
    //             'cn_meeting'        => false,
    //             'in_meeting'        => false,
    //             'join_before_host'  => true,
    //             'mute_upon_entry'   => true,
    //             'watermark'         => false,
    //             'use_pmi'           => false,
    //             'approval_type'     => 0,
    //             'registration_type' => 0,
    //             'audio'             => 'voip',
    //             'auto_recording'    => 'none',
    //             'waiting_room'      => false,
    //         ],
    //     ];
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     $curl = curl_init();
    //     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // Skip SSL Verification
    //     curl_setopt_array($curl, array(
    //         CURLOPT_URL            => "https://api.zoom.us/v2/users/me/meetings",
    //         CURLOPT_RETURNTRANSFER => true,
    //         CURLOPT_ENCODING       => "",
    //         CURLOPT_MAXREDIRS      => 10,
    //         CURLOPT_SSL_VERIFYHOST => 0,
    //         CURLOPT_SSL_VERIFYPEER => 0,
    //         CURLOPT_TIMEOUT        => 30,
    //         CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
    //         CURLOPT_CUSTOMREQUEST  => "POST",
    //         CURLOPT_POSTFIELDS     => json_encode($requestBody),
    //         CURLOPT_HTTPHEADER     => array(
    //             "Authorization: Bearer " . $meetingConfig['jwtToken'],
    //             "Content-Type: application/json",
    //             "cache-control: no-cache",
    //         ),
    //     ));
    //     $response = curl_exec($curl);
    //     $err      = curl_error($curl);
    //     curl_close($curl);
    //     //++++++++++++++++++++++++++++++++++++++++++++++++
    //     if ($err) {
    //         return [
    //             'success'  => false,
    //             'msg'      => 'cURL Error #:' . $err,
    //             'response' => null,
    //         ];
    //     } else {
         
    //         return [
    //             'success'  => true,
    //             'msg'      => 'success',
    //             'response' => json_decode($response, true),
    //         ];
    //     }
    // }


    // public function getMeetings()
    // {
    //     // Replace 'your-zoom-api-key' and 'your-zoom-api-secret' with your actual API Key and API Secret
  

    //     $zoomApiKey = env('NEXT_PUBLIC_ZOOM_API_KEY');
    //     $zoomApiSecret = env('ZOOM_MEETING_SDK_SECRET');

    //     // Base URL for Zoom API
    //     $baseUrl = 'https://api.zoom.us/v2/';
      
    //     // Generate JWT token for authentication
    //     $token = $this->generateJWTToken($zoomApiKey, $zoomApiSecret);
       
    //     // Set headers for the request
    //     $headers = [
    //         'Authorization' => 'Bearer ' . $token,
    //         'Content-Type' => 'application/json',
    //     ];

    //     try {
    //         // Make a GET request to retrieve all meetings
    //         $response = Http::withHeaders($headers)->get($baseUrl . 'users/me/meetings');

    //         // Check if the request was successful
    //         if ($response->status() === 200) {
    //             $data = $response->json();
    //             // Output the list of meetings
    //             echo "List of Meetings:\n";
    //             foreach ($data['meetings'] as $meeting) {
    //                 echo "- {$meeting['topic']} (ID: {$meeting['id']})\n";
    //             }
    //         } else {
    //             // Output error message if request was not successful
    //             echo "Failed to retrieve meetings. Status Code: {$response->status()}\n";
    //         }
    //     } catch (\Exception $e) {
    //         // Handle exceptions
    //         echo "An error occurred: " . $e->getMessage() . "\n";
    //     }
    // }

    public function getMeetings()
    {
        // Replace 'your-zoom-api-key' and 'your-zoom-api-secret' with your actual API Key and API Secret
        $zoomApiKey = "qDgCY0g4T2uvQSZhZUICwQ";
        $zoomApiSecret = "x2jF7svixu4MlJsi4R2FN4W3K14x3ZNR";



        // Base URL for Zoom API
        $baseUrl = 'https://api.zoom.us/v2/';
      
        // Generate JWT token for authentication
        // $token = $this->generateJWTToken($zoomApiKey, $zoomApiSecret);
      $token = "eyJzdiI6IjAwMDAwMSIsImFsZyI6IkhTNTEyIiwidiI6IjIuMCIsImtpZCI6IjU1NDYwNjNkLWUzNDItNDYwYi04OWNhLWIwZThhYWY2YmI5NiJ9.eyJ2ZXIiOjksImF1aWQiOiJkOGJhOWZkMWE1ZDIwZjY2ZGRiYTQ1OTgwMjliMDk0NyIsImNvZGUiOiJUMlIwRWtKNE54dkRvTnRuZDNKUnhDclg3TnhJanhMOUEiLCJpc3MiOiJ6bTpjaWQ6cURnQ1kwZzRUMnV2UVNaaFpVSUN3USIsImdubyI6MCwidHlwZSI6MCwidGlkIjowLCJhdWQiOiJodHRwczovL29hdXRoLnpvb20udXMiLCJ1aWQiOiJFSk9mTW5KclRHT1pEeDBZZGpTUHBBIiwibmJmIjoxNzEzNDQxMTU1LCJleHAiOjE3MTM0NDQ3NTUsImlhdCI6MTcxMzQ0MTE1NSwiYWlkIjoiODRKYU5adXZTdEd1LVdkRkFEbE56USJ9.QBSVVn_lV0GSDpbB6f-4oLqleFv6CbgZ5nKmUWKA9amne72uIN8PXISI-24u3pMmYLB705hDd9zB1nrcnswNuA";
        // dd($token);
        // Set headers for the request
        $headers = [
            'Authorization' => 'Bearer ' . $token,
            'Content-Type' => 'application/json',
        ];
    
        try {
            // Make a GET request to retrieve all meetings
            $response = Http::withHeaders($headers)->get($baseUrl . 'users/me/meetings');
            dd($response->json(), $response->status());
            // Check if the request was successful
            if ($response->status() === 200) {
                $data = $response->json();
                // Return the list of meetings
                return $data['meetings'];
            } else {
                // Log error message if request was not successful
              
                echo "Failed to retrieve meetings. Status Code: " . $response->status() . "\n";
                return [];
            }
        } catch (\Exception $e) {
            echo "An error occurred: " . $e->getMessage() . "\n";
            return [];
        }
    }

    // Function to generate JWT token
    private function generateJWTToken($apiKey, $apiSecret)
    {
        $payload = [
            'iss' => $apiKey,
            'exp' => strtotime('+1 hour'), // Token expiration time (1 hour from now)
        ];

        return JWT::encode($payload, $apiSecret, 'HS256');
    }

    // function generateJWTToken()
    // {
    //     $iat = time();
    //     $exp = $iat + (60 * 60 * 2); // Expire after 2 hours

    //     $payload = [
    //         'appKey' => env('NEXT_PUBLIC_ZOOM_API_KEY'),
    //         'sdkKey' => env('NEXT_PUBLIC_ZOOM_API_KEY'),
    //         'iss' => env('NEXT_PUBLIC_ZOOM_API_KEY'),
    //         'iat' => $iat,
    //         'exp' => $exp,
    //         'tokenExp' => $exp
    //     ];

    //     // Encode JWT with the appropriate key
    //     $jwt = JWT::encode($payload, env('ZOOM_MEETING_SDK_SECRET'), 'HS256');

    //     return $jwt;
    // }




    // public function meetingCreate(Request $request)
    // {
    //     $this->getMeetings();
    //     dd("edit page");
      
    // }


}



