<?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 App\Models\Setting;


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',
                function ($attribute, $value, $fail) use ($tutor_id, $start_date) {
                    $exists = DB::table('classes')
                        ->where('tutor_id', $tutor_id)
                        ->whereRaw("? BETWEEN start_date AND DATE_ADD(start_date, INTERVAL class_duration MINUTE)", [$start_date])
                        ->where('status', 1)
                        ->whereNull('deleted_at')
                        ->exists();
        
                    if ($exists) {
                        $fail('The selected start date is not unique or conflicts with an existing Class. Please select a different Class Time.');
                    }
                },
           
            ],
        ];

        // '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_time 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) {
                      

                    //         $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!");
            $request->id = $batch->id;
            if($batch->batch_mode == 1){
                $response = $this->meetingCreateBYBatch($request);
                
                if($response){
                    flashSuccess("Batch created successfully! And  Meeting Created.");
                }else{
                    flashWarning("Batch created successfully! Not A  Meeting Created.");
                }
                
            }
            
            
          

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

        // 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,
        //     ]);

        //     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');


        $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',
            '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',
                function ($attribute, $value, $fail) use ($tutor_id, $start_date, $id) {
                    $exists = DB::table('classes')
                        ->where('tutor_id', $tutor_id)
                        ->whereRaw("? BETWEEN start_date AND DATE_ADD(start_date, INTERVAL class_duration MINUTE)", [$start_date])
                        ->where('batch_id', '!=', $id)
                        ->where('status', 1)
                        ->whereNull('deleted_at')
                        ->exists();
        
                    if ($exists) {
                        $fail('The selected start date is not unique or conflicts with an existing Class. Please select a different Class Time.');
                    }
                },
           
            ],

        ];

        $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();
            if($validatedData['status'] != 2){
                Classes::where('batch_id', $batch->id)
                ->whereDate('start_date', '>', $currentDate)
                ->update(['status' => 1, 'class_mode' => $validatedData['batch_mode']]);

       
            }else{

                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!");

            $request->id = $batch->id;
            if($batch->batch_mode == 1){
                $response = $this->meetingCreateBYBatch($request);
                
                if($response){
                    flashSuccess("Batch created successfully! And  Meeting Created.");
                }else{
                    flashWarning("Batch created successfully! Not A  Meeting Created.");
                }
                
            }

            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');
        $plan_id = $request->input('plan_id');

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


    // public function createMeeting(array $data)
    // {
    //     $client = new Client();

    //     $response = $client->request('POST', 'https://api.zoom.us/v2/users/me/meetings', [
    //         'headers' => [
    //             'Authorization' => 'Bearer ' . $this->generateZoomApiJwtToken(),
    //             'Content-Type' => 'application/json',
    //         ],
    //         'json' => [
    //             'topic' => $data['topic'],
    //             'type' => 2, // Scheduled meeting
    //             'start_time' => $data['start_time'],
    //             'duration' => $data['duration'],
    //         ],
    //     ]);

    //     $responseData = json_decode($response->getBody()->getContents(), true);

    //     return [
    //         'meeting_id' => $responseData['id'],
    //         'meeting_password' => $responseData['password'],
    //     ];
    // }

    // protected function generateZoomApiJwtToken()
    // {
    //     $payload = [
    //         'iss' => env('NEXT_PUBLIC_ZOOM_API_KEY'), // Change this to your Zoom API key
    //         'exp' => strtotime('+1 hour'),
    //     ];

    //     return JWT::encode($payload, env('ZOOM_MEETING_SDK_SECRET'), 'HS256');
    //     //                                      ^^^^^^^^^^^
    //     // Add the algorithm here, in this case, it's HS256
    // }

    // function generateZoomSDKJWT($meetingNumber, $role)
    // {
    //     $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'),
    //         'mn' => $meetingNumber,
    //         'role' => $role,
    //         '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 meetingCreateBYBatch(Request $request)
    { 
        $id = @$request->id;
          
        $batch = Batch::where('id', $id)->first();
      
        if ($batch) {
           
            $setting = Setting::first();

            $accessToken =  $setting->zoom_access_token;

            if (!empty($accessToken)) {
                $batchDate = $batch->start_date;
                $batchDate = Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC'));
                $classTime = $batch->class_time;
              
                if ($classTime) {
                    $batchDate = Carbon::parse($batchDate)->tz(env('APP_TIMEZONE', 'UTC'))->setTimeFromTimeString($classTime);
                }
                $formattedBatchDate = $batchDate->format('Y-m-d\TH:i:00\Z');
                // dd($formattedBatchDate);
                $get_zoom_details = $this->create_a_zoom_meeting([
                    'topic'      =>  $batch->batch_name. ' (#'.$batch->batch_code.')',
                    'start_time' => $formattedBatchDate,
                    'agenda'     => "--",
                    'jwtToken'   => $accessToken,
                ]);

               
                if ($get_zoom_details['success']) {
                   
                    if(@$get_zoom_details['response']['code'] == "124"){
                        // flashError("Zoom Access Token not found.");
                        // return back();
                        return false;
                    }
                    $meeting_id = @$get_zoom_details['response']['id'] ? @$get_zoom_details['response']['id'] : null;
                    $meeting_password = @$get_zoom_details['response']['password'] ? @$get_zoom_details['response']['password'] : null;

                    $batch->meeting_id = $meeting_id;
                    $batch->meeting_password = $meeting_password;
                    $batch->save();
                     
                    // flashSuccess("Zoom Metting created successfully!");
                    // return redirect()->route('admin.batch.index');
                    return true;
                } else {
                    // flashError("Something Went Wrong!");
                    // return redirect()->route('admin.batch.index');
                    return false;
                }
            } else {
                // flashError("Zoom Access Token not found.");
                // return back();
                return false;
            }

           
        } else {
           
            // flashError("Batch not found.");
            // return back();
            return false;
           
        }
    }


    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),
            ];
        }
    }


}
