HEX
Server: nginx/1.24.0
System: Linux DGT-WORDPRESS-VM-SERVER 6.14.0-1017-azure #17~24.04.1-Ubuntu SMP Mon Dec 1 20:10:50 UTC 2025 x86_64
User: ubuntu (1000)
PHP: 8.4.12
Disabled: NONE
Upload Files
File: /mnt/data/ghayatcom/ghayatcom-api/app/Http/Controllers/Api/DoctorController.php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\{User,AreaSpecialisation,Language,UserDetails,ScheduledAppointment,ScheduledAppointmentDetail,FavouriteDoctors,Payment,Appointment,Diagnosis,Clinic,UserClinic,Country,UserAdditionalInfo};
use App\DoctorUnavailable;
use Auth;
use Config;
use Carbon\Carbon;
use DB;
use DateTime;
use Exception;
use Throwable;
use Illuminate\Database\QueryException;
use App\AppointmentReason;
use App\WaitingRoom;
use App\Http\Requests\DoctorListRequest;
use App\Http\Requests\DoctorNotesRequest;
use App\Http\Requests\SetScheduledAppointmentRequest;
use App\Http\Requests\RemoveScheduledAppointmentRequest;
use App\Http\Requests\SetHomeVisitAvailabilityRequest;
use App\Http\Requests\SetOnDemandRequest;
use App\Http\Requests\DoctorsFavoriteRequest;
use App\Http\Requests\DoctorsProfileRequest;
use App\Http\Requests\UserIdRequest;
use App\Http\Requests\DiscountConfirmationRequest;
use App\Http\Resources\UserCollection;
use App\Http\Resources\ClinicAppointmentResource;
use App\Http\Resources\DiagnosisCollection;
use App\Http\Requests\PatientDoctorListRequest;
use App\Http\Requests\DiagnosisCreateRequest;
use App\Http\Requests\DiagnosisListRequest;
use App\Http\Requests\ClinicAppointmentCreateRequest;
use App\Library\RandomLibrary;
use App\Enums\AppoitmentStatusEnum;
use App\Http\Requests\DoctorUnavailableListRequest;
use App\Http\Requests\DoctorHomeVisitAvailableRequest;
use App\Library\DoctorAvailabilityLibrary;
use App\Enums\{UserRoleTypeEnum, UserAccountStatusEnum};
use App\Helpers\GeneralHelper;

class DoctorController extends Controller
{


    public function doctorAvailabilitiesList(UserIdRequest $request) {
        $validated = $request->validated();

        $authRole = User::find($request->user_id);
        if(!$authRole->hasRole(['doctor'])) {
            return self::sentResponse(401,[], __('digimed_validation.error_response.not_authorized'));
        }
        /**
         * @var array $consultationTypess
         */
        $consultationTypess = Config::get('consultation_type');

        if(count($consultationTypess) != 0) {
            $out = array();
            for ($i=0; $i < count($consultationTypess); $i++) {
                $id = $consultationTypess[$i]['id'];
                $data_consultationTypess = $consultationTypess[$i]['name'];
                $queryAvailabilities = "";
                $name = preg_replace('/\s+/', '_', strtolower($data_consultationTypess));
                $out[$name] = array();
            }

            $queryAvailabilitiesData = UserDetails::withCount('scheduledAppointments')->with('scheduledAppointments.scheduledAppointmentDetail')->where('user_id', $request->user_id);
            /**
             * @var object $queryAvailabilitiesData
             */
            if($queryAvailabilitiesData->count() != 0) {
                $queryAvailabilities = $queryAvailabilitiesData->get()->toArray();
                $queryAvailabilities = $queryAvailabilities[0];

                $scheduledAptArr = [];
                if(!empty($queryAvailabilities['scheduled_appointments'])) {
                    $queryAvailabilitiesSet = $queryAvailabilities['scheduled_appointments'];
                    foreach($queryAvailabilitiesSet AS $val) {
                        $scheduledAptJson['id'] = $val['id'];
                        $scheduledAptJson['from_date'] = $val['from_date'];
                        $scheduledAptJson['date_until'] = $val['date_until'];
                        $scheduledAptJson['week_days'] = $val['week_days'];

                        if(!empty($val['scheduled_appointment_detail'])) {
                            $scheduledAppointmentDetail = $val['scheduled_appointment_detail'];
                            $scheduledAptDArr = array();
                            for ($j=0; $j < count($scheduledAppointmentDetail); $j++) {
                                $scheduledAptDetailsJson['from_time'] = $scheduledAppointmentDetail[$j]['from_time'];
                                $scheduledAptDetailsJson['to_time'] = $scheduledAppointmentDetail[$j]['to_time'];
                                array_push($scheduledAptDArr, $scheduledAptDetailsJson);
                            }

                        } else {
                            $scheduledAptDArr = [];
                        }
                        $scheduledAptJson['from_to_time'] = $scheduledAptDArr;
                        array_push($scheduledAptArr, $scheduledAptJson);
                    }
                } else {
                    $scheduledAptJson['from_date'] = "";
                    $scheduledAptJson['date_until'] = "";
                    $scheduledAptJson['week_days'] = "";
                    $scheduledAptJson['from_to_time'] = [];
                    array_push($scheduledAptArr, $scheduledAptJson);
                }


                $onDemanJson['on_demand_available_status'] = $queryAvailabilities['on_demand_available_status'];
                $onDemanJson['on_demand_time_out'] = $queryAvailabilities['on_demand_time_out'];

                $homeVisitJson['home_visit_from_time'] = $queryAvailabilities['home_visit_from_time'];
                $homeVisitJson['home_visit_to_time'] = $queryAvailabilities['home_visit_to_time'];
                $homeVisitJson['home_visit_weekdays'] = $queryAvailabilities['home_visit_weekdays'];
                $homeVisitJson['home_visit_latitude'] = $queryAvailabilities['home_visit_latitude'];
                $homeVisitJson['home_visit_longitude'] = $queryAvailabilities['home_visit_longitude'];
                $homeVisitJson['home_visit_radius'] = $queryAvailabilities['home_visit_radius'];
            } else {
                $homeVisitJson['home_visit_from_time'] = "";
                $homeVisitJson['home_visit_to_time'] = "";
                $homeVisitJson['home_visit_weekdays'] = "";
                $homeVisitJson['home_visit_latitude'] = "";
                $homeVisitJson['home_visit_longitude'] = "";
                $homeVisitJson['home_visit_radius'] = "";

                $onDemanJson['on_demand_available_status'] = "";
                $onDemanJson['on_demand_time_out'] = "";

                $scheduledAptArr = [];
                $scheduledAptJson['from_date'] = "";
                $scheduledAptJson['date_until'] = "";
                $scheduledAptJson['week_days'] = "";
                $scheduledAptJson['from_to_time'] = [];
                array_push($scheduledAptArr, $scheduledAptJson);
            }
            $out['scheduled_appointment'] = $scheduledAptArr;
            $out['home_visit'] = $homeVisitJson;
            $out['doctor_on_demand'] = $onDemanJson;
        } else {
            $out = array();
        }
        return self::sentResponse(200,$out,__('digimed_validation.success_response.doctor_availabilities_list'));
    }

    public function index(DoctorListRequest $request)
    {
        $validated = $request->validated();
        try {
            $paginate = $request->count_per_page ? $request->count_per_page : 10;
            $pageNumber = $request->page ? $request->page : 1;
            /**
             * @var int|null $paginate
             * @var int|null $pageNumber
             */
            $sort_by_col = (isset($request->sort_by)) ? $request->sort_by : 'id';
            /** @var string $data_order_by */
            $data_order_by = $request->order_by;
            $orderBy = $request->order_by ? strtoupper($data_order_by) : strtoupper('asc');

            $data = $request->all();

            $audio_call = $data['audio_call'];
            $chat = $data['chat'];
            $video_call = $data['video_call'];
            $hospital_visit = $data['hospital_visit'];
            $language = trim($data['language'], ',');
            $is_demand = $data['is_demand'];
            $is_homevisit = $data['is_homevisit'];
            $is_schedule = $data['is_schedule'];
            $is_favorite = $request->is_favorite;
            $auth_id = auth()->user()->id;
            $languageArr = explode(',', $language);
            $search_key = $request->search;
           
            $get_area_specialization = trim($data['area_specialization'], ',');
            $idsArrAreaSpecialization = explode(',',$get_area_specialization);
            $arrAreaSpecialization = array_filter($idsArrAreaSpecialization);

            $get_clinic = trim($data['clinic'], ',');
            $idsArrclinic = explode(',',$get_clinic);
            $arrclinic = array_filter($idsArrclinic);
            
            $get_country = trim($data['country'], ',');
            $idsArrCountry = explode(',',$get_country);
            $arrCountry = array_filter($idsArrCountry);
       
            $get_gender = trim($data['gender'], ',');
            $idsArrGender = explode(',',$get_gender);
            $arrGender = array_filter($idsArrGender);

            $get_experience = trim($data['experience'], ',');
            $idsArrExperience = explode(',',$get_experience);
            $arrExperience = array_filter($idsArrExperience);

            $availability =[];

            //fetch auth id
            $authRole = GeneralHelper::authUser();
            $auth_id = GeneralHelper::authId();
            
            $date = Carbon::now()->format('Y-m-d');
            $dayName = Carbon::now()->format('D');

            $query = User::select('users.*','cp.price','cp.currency_code','cp.type AS consultation_id')->role('doctor')
            ->leftJoin('consultation_prices AS cp', 'users.id', '=', 'cp.user_id')
            ->with(['roles','doctorDocument','userDetail','sumSub', 'favouriteDoctors'])
            ->has('consultationPrice')
            ->where('users.type',UserRoleTypeEnum::doctor())
            ->whereIn('user_completion', GeneralHelper::userCompliation())
            ->where('status', UserAccountStatusEnum::approved());

            $query = $query->whereHas('scheduledAppointment', function($q) use($date, $dayName) {
                // $q->where('from_date', '<=', $date);
                $q->where('date_until', '>=', $date);
                $q->whereRaw("FIND_IN_SET(?, week_days) > 0", [$dayName]);
            });

            if($authRole->type == UserRoleTypeEnum::clinic_admin()){
                
                $clinicId = Clinic::select('id')->where('user_id',$auth_id)->first();
               
                //get users from user detail id 
                $userDetailId = UserClinic::where('clinic_id',$clinicId->id)->whereNull('deleted_at')->distinct()->pluck('user_detail_id')->toArray();
               

                $userId = UserDetails::whereIn('id',$userDetailId)->distinct()->pluck('user_id')->toArray();
                $query = $query->whereIn('users.id',$userId);

            }

            if(!empty($search_key)) {
                /** @var string $search_key */
                $query->where(function ($query) use ($search_key) {
                    
                    $query->orWhere('first_name', 'LIKE', "%{$search_key}%")
                          ->orWhere('last_name', 'LIKE', "%{$search_key}%")
                          ->orWhere(DB::raw("CONCAT(first_name, ' ', last_name)"), 'LIKE', "%{$search_key}%")
                          ->orWhereHas('userDetail.UserAreaSpecialization.areaSpecialisation', function ($q) use ($search_key) {
                              $q->where('area_specialisation_name', 'LIKE', "%{$search_key}%");
                          });
                });
            }

            if(!empty($arrExperience)) {
                if(count($arrExperience) > 1) {
                    $query->WhereHas('userDetail', function($q) {
                        $q->where('experience', '>', 0);
                    });
                } else {
                    if($request->experience == '1-5') {
                        $query->WhereHas('userDetail', function($q) {
                            $q->where('experience', '<=', 5);
                            $q->where('experience', '>=', 1);
                        });
                    } else if($request->experience == '5+') {
                        $query->WhereHas('userDetail', function($q) {
                            $q->where('experience', '>=', 5);
                        });
                    }
                }
            }
            
            if(!empty($is_schedule)) {
                $query->where('cp.type', '1');
            }
            if(!empty($is_homevisit)) {
                $query->where('cp.type', '2');
            }
            if(!empty($is_demand)) {
                $query->where('cp.type', '3');
            }

            if(!empty($is_demand)){
                $query->whereHas('userDetail', function($q) {
                    $q->where('on_demand_available_status', 1);
                });
            }

            if(!empty($is_homevisit)){
                $doctorArr = [];
                if(isset($request->lat_long)){
                    /** @var string $data_lat_long */
                    $data_lat_long = $request->lat_long;
                    $decode = json_decode(str_replace('\\', '', $data_lat_long), TRUE);//json_decode($data_lat_long);
                    /** @var object|array $decode */
                    if(!empty((array)$decode)){
                        $dataLat = $decode['lat'];
                        $dataLong = $decode['long'];
                        $queryLocation = DB::table("user_details")->select("user_details.id",'user_details.user_id',"user_details.home_visit_radius"
                            ,DB::raw("6371 * acos(cos(radians(" . $dataLat . "))
                            * cos(radians(user_details.home_visit_latitude))
                            * cos(radians(user_details.home_visit_longitude) - radians(" . $dataLong . "))
                                + sin(radians(" .$dataLat. "))
                            * sin(radians(user_details.home_visit_latitude))) AS distance"))
                                ->get();
                        /**
                         * @var object $queryLocation
                         */
                        for ($i=0; $i < count($queryLocation); $i++) {
                            if($queryLocation[$i]->distance < $queryLocation[$i]->home_visit_radius) {
                                $doctorArr[] = $queryLocation[$i]->user_id;
                            }
                        }
                        if(count($doctorArr) > 0){
                            $query->whereIn('users.id',$doctorArr);
                        }
                    }
                }

                if(isset($request->home_visit_dt)){
                    /** @var string $data_decode */
                    $data_decode = json_encode($request->home_visit_dt);

                    $decode = json_decode(str_replace('\\', '', $data_decode), TRUE);//json_decode($data_decode);

                    /** @var object|array $decode */
                    if(($decode) != "") {
                        $dataDate = $decode['date'];
                        $current = Carbon::now()->format("Y-m-d");
                        $date = Carbon::parse($dataDate)->format('Y-m-d');

                        if($date >= $current){
                            $day = Carbon::parse($dataDate)->format('D');

                            $list = UserDetails::whereRaw("find_in_set('".$day."',home_visit_weekdays)")->whereIn('user_id',$doctorArr)->where('home_visit',1)->get();
                            $doctors = [];
                            foreach($list as $row){
                                $request_from_time = Carbon::make($row['home_visit_from_time']);
                                $from_time = Carbon::parse($request_from_time)->format("H:i:s");
                                $request_to_time = Carbon::make($row['home_visit_to_time']);
                                $to_time = Carbon::parse($request_to_time)->format("H:i:s");
                                $user_id = $row['user_id'];

                                $range = $decode['range'];//$decode->range;
                                foreach ($range as $key => $value) {
                                    $dtFrom = $value['from'];
                                    $dtTo = $value['to'];
                                    $range_from = Carbon::parse($dtFrom)->format("H:i:s");
                                    $range_to = Carbon::parse($dtTo)->format("H:i:s");
                                    if(strtotime($range_from) > strtotime($from_time) && strtotime($range_from) < strtotime($to_time) ) {
                                        $doctors[] = $user_id;
                                    }
                                    if(strtotime($range_to) > strtotime($from_time) && strtotime($range_to) < strtotime($to_time) ) {
                                        $doctors[] = $user_id;
                                    }
                                }
                            }
                            $final_doctors = array_unique($doctors);
                            $query->whereIn('users.id',$final_doctors);
                        }
                    }
                }

            }
            if(!empty($is_favorite)) {
                if($is_favorite == "1") {
                    $query->whereHas('favouriteDoctors',function($q) use($auth_id) {
                        $q->where('patient_id', $auth_id);
                    });
                }
            }

            if(!empty(array_filter($languageArr))) {
                $query->whereHas('userDetail.UserLanguage', function($q) use($languageArr) {
                    foreach ($languageArr as $key => $value) {
                        if($key == 0) {
                            $q->where('language_id', $value);
                        } else {
                            $q->orWhere('language_id', $value);
                        }
                    }
                });
            }

            if(!empty(array_filter($idsArrAreaSpecialization))) {
                $query->WhereHas('userDetail.UserAreaSpecialization', function($q) use($idsArrAreaSpecialization) {
                    foreach ($idsArrAreaSpecialization as $key => $value) {
                        if($key == 0) {
                            $q->where('area_specialisation_id', $value);
                        } else {
                            $q->orWhere('area_specialisation_id', $value);
                        }
                    }
                });
            }

            if(!empty(array_filter($arrclinic))) {
                $query->WhereHas('userDetail.UserClinic', function($q) use($arrclinic) {
                    // foreach ($arrclinic as $key => $value) {
                    //     if($key == 0) {
                    //         $q->where('clinic_id', $value);
                    //     } else {
                            $q->whereIn('clinic_id', $arrclinic);
                    //     }
                    // }
                });
            }

            if(!empty(array_filter($arrCountry))) {
                $query->whereIn('country_id', $arrCountry);
            }

            if(!empty(array_filter($arrGender))) {
                $query->whereIn('gender', $arrGender);
            }

            //orWhereHas
            if($audio_call != "") {
                $query->WhereHas('userDetail', function($q) use($audio_call) {
                    $q->where('audio_call', '=', $audio_call);
                });
            }

            if($chat != "") {
                $query->WhereHas('userDetail', function($q) use($chat) {
                    $q->where('chat', '=', $chat);
                });
            }

            if($video_call != "") {
                $query->WhereHas('userDetail', function($q) use($video_call) {
                    $q->where('video_call', '=', $video_call);
                });
            }

            if($hospital_visit != "") {
                $query->WhereHas('userDetail', function($q) use($hospital_visit) {
                    $q->where('hospital_visit', '=', $hospital_visit);
                });
            }

            if($is_demand != "") {
                $query->WhereHas('userDetail', function($q) use($is_demand) {
                    $q->where('on_demand', '=', $is_demand);
                });
            }

            if($is_schedule != "") {
                $query->WhereHas('userDetail', function($q) use($is_schedule) {
                    $q->where('schedule_appointment', '=', $is_schedule);
                });
            }

            if($is_homevisit != "") {
                $query->WhereHas('userDetail', function($q) use($is_homevisit) {
                    $q->where('home_visit', '=', $is_homevisit);
                });
            }
            //new code
            if(isset($request->visit_dt)){
                // $data_decode = json_encode($request->visit_dt);
                // $decode = json_decode(str_replace('\\', '', $data_decode), TRUE);//json_decode($data_decode);
                // dd($data_decode);
                $decode = json_decode($request->visit_dt, true);
                /** @var object|array $decode */
                if ($decode !== null && is_array($decode)) {
                // if(($decode) != "") {
                    $dataDate = $decode['date'];
                    $date = Carbon::parse($dataDate)->format('Y-m-d');
                    /*if(!empty($dataDate) && !empty($decode['range'][0]) ) {
                        if($decode['range'][0]['from']!='' && $decode['range'][0]['to']!='') {
                          $availability = $this->getDoctorAvailability($decode);
                          if(!empty($availability )) {
                                $final_doctors = array_unique(array_column($availability,'doctor_id'));
                                $query->whereIn('users.id',$final_doctors);
                          }
                        }
                    }*/

                    if(!empty($dataDate)) {
                        $availability = $this->getDoctorAvailability($decode);
                        if(!empty($availability )) {
                            $final_doctors = array_unique(array_column($availability,'doctor_id'));
                            $query->whereIn('users.id',$final_doctors);
                        } else {
                            $query->whereIn('users.id',[]);
                        }
                    }
                }
            }
            //new code
            if($sort_by_col == "price" || $sort_by_col == "id") {
                $prefixCol = ($sort_by_col == "id") ? 'users.id' : 'cp.price';
                $query->orderBy($prefixCol, $orderBy);
            }
            $users = $query->get();

            // Sort by Avg Rating (ascending or descending)
            if ($sort_by_col == "rating") {
                if ($orderBy == "ASC") {
                    $sortedUsers = $users->sortBy(function($user) use ($orderBy) {
                        // Calculate the average rating and rating count from the 'ratings' table
                        $avgRating = $user->userDoctorRatings()->avg('doctor_rating'); // Average rating
                        $ratingCount = $user->userDoctorRatings()->count(); // Rating count
                        return [$avgRating, $ratingCount]; // Sort by avg rating, then by rating count
                    });
                }
                if ($orderBy == "DESC") {
                    $sortedUsers = $users->sortByDesc(function($user) use ($orderBy) {
                        // Calculate the average rating and rating count from the 'ratings' table
                        $avgRating = $user->userDoctorRatings()->avg('doctor_rating'); // Average rating
                        $ratingCount = $user->userDoctorRatings()->count(); // Rating count
                        return [$avgRating, $ratingCount]; // Sort by avg rating (descending), then by rating count
                    });
                }
            } else {
                $sortedUsers = $users;
            }
            
          //  $paginateData = $sortedUsers->forPage($pageNumber, $paginate); // Paginate the sorted collection

            // if ($sort_by_col == "rating") {
            //     if ($orderBy == "ASC") {
            //         $paginateData->setCollection(
            //             $paginateData->getCollection()->sortBy(function ($q) {
            //                 return $q->avgratingdoctor;
            //             })
            //         );
            //     }
            //     if ($orderBy == "DESC") {
            //         $paginateData->setCollection(
            //             $paginateData->getCollection()->sortByDesc(function ($q) {
            //                 return $q->avgratingdoctor;
            //             })
            //         );
            //     }
            // }
            
            $list = collect()->unique('id');
      
            $sortedUsers->each(function ($data) use (&$list){
                
                $list->push($data);
            });
            $result['doctors_availability'] = $availability;
           
            $result['list'] =  $sortedUsers->forPage($pageNumber, $paginate)->values();
            $result['total_count'] = $sortedUsers->count();
            $result['last_page'] = ceil($sortedUsers->count() / $paginate);
            $result['current_page'] = $pageNumber;
            return self::sentResponse(200, $result, __('digimed_validation.success_response.data_fetch_success'));

        } catch(\Exception | Throwable | QueryException $e) {
            return self::sentResponse(500, [], $e->getMessage());
        }
    }
    public function getDoctorAvailability($decode)
    {
        $scheduledAptJson = [];

            /** @var object|array $decode */
            if(($decode) != "") {
                $dataDate = $decode['date'];
                $range = $decode['range'][0];//$decode->range;
                $current = Carbon::now()->format("Y-m-d");
                $date = Carbon::parse($dataDate)->format('Y-m-d');

                if($date >= $current) {
                    $dayName = Carbon::parse($dataDate)->format('D');
                    $dtFrom = $range['from'];
                    $dtTo = $range['to'];
                    // $startTime = Carbon::parse($dtFrom)->format("H:i:s");
                    // $endTime = Carbon::parse($dtTo)->format("H:i:s");

                    if($dtFrom !='' && $dtTo !='' && $date != '') {
                        $startTime = Carbon::parse($dtFrom)->format("H:i:s");
                        $endTime = Carbon::parse($dtTo)->format("H:i:s");
                        $availability = ScheduledAppointment::where('from_date', '<=', $date)
                        ->where('date_until', '>=', $date)
                        ->whereRaw("FIND_IN_SET(?, week_days) > 0", [$dayName])
                        ->whereHas('scheduledAppointmentDetail', function ($query) use ($startTime, $endTime) {
                            if ($startTime && $endTime) {
                                $query->where('from_time', '<=', $startTime)
                                    ->where('to_time', '>=', $endTime);
                            }
                        })
                        ->with(['scheduledAppointmentDetail' => function ($query) use ($startTime, $endTime) {
                            if ($startTime && $endTime) {
                                $query->where('from_time', '<=', $startTime)
                                    ->where('to_time', '>=', $endTime);
                            }
                        }])
                        ->get();
                    } else {
                        $availability = ScheduledAppointment::where('from_date', '<=', $date)
                        ->where('date_until', '>=', $date)
                        ->whereRaw("FIND_IN_SET(?, week_days) > 0", [$dayName])
                        ->get();
                        // $sql = $availability->toSql();
                        // $bindings = $availability->getBindings();
                        // dd(vsprintf(str_replace('?', '%s', $sql), $bindings));
                    }

                    if($availability->count()>0) {
                        foreach($availability as $row) {
                            $avails['id'] = $row['id'];
                            $avails['doctor_id'] = $row['doctor_id'];
                            $avails['from_date'] = $row['from_date'];
                            $avails['date_until'] = $row['date_until'];
                            $avails['from_time'] = !empty($row->scheduledAppointmentDetail)?$row->scheduledAppointmentDetail[0]->from_time:'';
                            $avails['to_time'] = !empty($row->scheduledAppointmentDetail)?$row->scheduledAppointmentDetail[0]->to_time:'';
                            $avails['week_days'] = $row['week_days'];
                            $scheduledAptJson[] = $avails;
                        }
                    }
                    return $scheduledAptJson;
                }
                return $scheduledAptJson;
            }

            return $scheduledAptJson;
        // $dayName = Carbon::parse($date)->format('D'); // Get the day name for the specified date (e.g., Mon, Tue)


    }
    public function filterList(Request $request) {
        try {
            $specialization = AreaSpecialisation::select('id', 'area_specialisation_name')->get()->toArray();
            $channels = Config::get('channel_list.channels');
            $languages = Language::select('id', 'name', 'code')->whereNull('deleted_at')->get()->toArray();
            $clinics = Clinic::whereNull('deleted_at')->get()->toArray();
            $countries = Country::where('iso3', 'USA')->whereNull('deleted_at')->get()->toArray();
            $json['specialization'] = $specialization;
            $json['experience'] = array();
            $json['channels'] = $channels;
            $json['languages'] = $languages;
            $json['clinics'] = $clinics;
            $json['countries'] = $countries;

            return self::sentResponse(200, $json, __('digimed_validation.success_response.data_fetch_success'));
        } catch(Exception | Throwable | QueryException $e) {
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function setOndemand(SetOnDemandRequest $request, DoctorAvailabilityLibrary $DoctorAvailabilityLibrary) {

        try {
            $validated = $request->validated();
            $data = $request->all();
            if($data['is_online'] == 1) {
                //Home Visit Conflict
                $conflictHomeVisit = $DoctorAvailabilityLibrary->consultationHomeVisitConflict($request->user_id, $request->all(), 'from_ondemand');
                if($conflictHomeVisit) {
                    return self::sentResponse(500, [], __('digimed_validation.error_response.conflict_issue_for_homevisit'));
                }

                // Schedule Conflict
                $conflictSchedule = $DoctorAvailabilityLibrary->consultationScheduleConflict($request->user_id, $request->all(), 'from_ondemand');
                if($conflictSchedule) {
                    return self::sentResponse(500, [], __('digimed_validation.error_response.conflict_issue_for_schedule'));
                }
            }

            $user = User::with('roles')->find($request->user_id);
            if(!$user->hasRole(['doctor'])) {
                return self::sentResponse(401, [], __('digimed_validation.error_response.not_authorized'));
            }
            $online_until = Carbon::parse($data['online_until'])->format('Y-m-d H:i:s');
            $is_online = $data['is_online'];
            $user_id = $data['user_id'];

            $checkAppointmentExist = Appointment::where('appointment_start_dt','<=', $online_until)->where('appointment_end_dt','>', $online_until)->whereIn('appointment_status', [AppoitmentStatusEnum::NEW(),AppoitmentStatusEnum::ACCEPTED()])->where('doctor_id', $user_id)->count();

            if($checkAppointmentExist > 0) {
                return self::sentResponse(401, [], __('digimed_validation.error_response.doctor_available_cannot_mark'));
            }

            DB::beginTransaction();
            if($is_online == 1) {
                UserDetails::where('user_id', $user_id)->update(['on_demand_available_status'=>$is_online, 'on_demand_time_out'=>$online_until, 'updated_at'=>new DateTime, 'updated_by'=>$user_id]);
            } else {
                UserDetails::where('user_id', $user_id)->update(['on_demand_available_status'=>$is_online, 'on_demand_time_out'=>NULL, 'updated_at'=>new DateTime, 'updated_by'=>$user_id]);
            }

            DB::commit();
            return self::sentResponse(200, [], __('digimed_validation.success_response.on_demand_update_success'));
        } catch(Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function homeVisitAvailability(SetHomeVisitAvailabilityRequest $request, DoctorAvailabilityLibrary $DoctorAvailabilityLibrary) {

        try {
            $validated = $request->validated();

            //On Demand Conflict
            $conflictOnDemand = $DoctorAvailabilityLibrary->consultationOndemandConflict($request->user_id, $request->all(), 'from_homevisit');
            if($conflictOnDemand) {
                return self::sentResponse(500, [], __('digimed_validation.error_response.conflict_issue_for_ondemand'));
            }

            // Schedule Conflict
            $conflictSchedule = $DoctorAvailabilityLibrary->consultationScheduleConflict($request->user_id, $request->all(), 'from_homevisit');
            if($conflictSchedule) {
                return self::sentResponse(500, [], __('digimed_validation.error_response.conflict_issue_for_schedule'));
            }

            $user = User::with('roles')->find($request->user_id);
            // if(!$user->hasRole(['doctor'])) {
            //     return self::sentResponse(401, [], __('digimed_validation.error_response.not_authorized'));
            // }
            $data = $request->all();
            $home_visit_from_time = Carbon::parse($data['home_visit_from_time'])->format('H:i:s');
            $home_visit_to_time = Carbon::parse($data['home_visit_to_time'])->format('H:i:s');
            $request['home_visit_from_time'] = $home_visit_from_time;
            $request['home_visit_to_time'] = $home_visit_to_time;
            $user_id = $data['user_id'];

            $str = @$data['home_visit_weekdays'];
            if(isset($str)) {
                $arr = array();
                foreach (explode(",", $str) AS $val) {
                    array_push($arr, ucfirst(strtolower($val)));
                }
            }
            if(!empty($arr)) {
                $home_visit_weekdays = implode(',', $arr);
            } else {
                $home_visit_weekdays = 'Mon,Tue,Wed,Thu,Fri,Sat,Sun';
            }
            DB::beginTransaction();

            UserDetails::where('user_id', $user_id)->update(['home_visit_weekdays'=>$home_visit_weekdays, 'home_visit_from_time'=>$home_visit_from_time, 'home_visit_to_time'=>$data['home_visit_to_time'], 'home_visit_latitude'=>$data['home_visit_latitude'], 'home_visit_longitude'=>$data['home_visit_longitude'], 'home_visit_radius'=>$data['home_visit_radius'], 'updated_at'=>new DateTime, 'updated_by'=>$user_id]);
            DB::commit();
            return self::sentResponse(200, [], __('digimed_validation.success_response.data_update_success'));
        } catch(Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function doctorsFavourite(DoctorsFavoriteRequest $request)
    {
        try
        {
            $validated = $request->validated();
            DB::beginTransaction();
            $patient_id = auth()->user()->id;
            $user = FavouriteDoctors::where('doctor_id',$request->doctor_id)->where('patient_id',$patient_id)->withTrashed()->first();

            if($user!='' && $user->deleted_at!=null) {
                $user->updated_by = $patient_id;
                $user->deleted_at = null;
                $user->deleted_by = null;

            } else if($user!='' && $user->deleted_at == null) {
                $user->updated_by = $patient_id;
                $user->deleted_at = now();
                $user->deleted_by = $patient_id;
            } else {
                $user = New FavouriteDoctors();
                $user->patient_id = $patient_id;
                $user->doctor_id = $request->doctor_id;
                $user->created_at = now();
                $user->created_by = $patient_id;
            }
            $user->save();
            DB::commit();

            $response_array = [
                "patient_id" => $user->patient_id,
                "doctor_id" => $user->doctor_id
            ];
            return self::sentResponse(200,$response_array,__('digimed_validation.success_response.favourite_doctors_update_success'));
        }
        catch(\Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500,[], $e->getMessage());
        }
    }

    public function setScheduledAppointment(SetScheduledAppointmentRequest $request, DoctorAvailabilityLibrary $DoctorAvailabilityLibrary)
    {
        try {
            $validated = $request->validated();
            $data = $request->all();
            $successArr = [];
            $failedArr = [];
            $innerDateCondition = date('Y-m-d');

            for ($i=0; $i < count($data); $i++) {

                $unique_id = $data[$i]['unique_id'];
                $update_id = $data[$i]['update_id'];
                $doctor_id = $data[$i]['doctor_id'];
                $from_date_init = $data[$i]['from_date'];
                $date_until_init = $data[$i]['date_until'];
                $from_to_time_init = $data[$i]['from_to_time'];
                $week_days_init = $data[$i]['week_days'];

                if($from_date_init >= $innerDateCondition && $innerDateCondition <= $date_until_init) {

                    //On Demand Conflict
                    $conflictOnDemand = $DoctorAvailabilityLibrary->consultationOndemandConflict($doctor_id, $data[$i], 'from_schedule');
                    if($conflictOnDemand) {
                        $failedArr[] = $unique_id;
                        $response_array = ['success' => $successArr, 'faild' => $failedArr];
                        return self::sentResponse(500, $response_array, __('digimed_validation.error_response.conflict_issue_for_ondemand'));
                    }

                    //Home Visit Conflict
                    $conflictHomeVisit = $DoctorAvailabilityLibrary->consultationHomeVisitConflict($doctor_id, $data[$i], 'from_schedule');
                    if($conflictHomeVisit) {
                        $failedArr[] = $unique_id;
                        $response_array = ['success' => $successArr, 'faild' => $failedArr];
                        return self::sentResponse(500, $response_array, __('digimed_validation.error_response.conflict_issue_for_homevisit'));
                    }

                    //Schedule Conflict
                    $conflictSchedule = $DoctorAvailabilityLibrary->consultationScheduleConflict($doctor_id, $data[$i], 'from_schedule', $update_id);
                    if($conflictSchedule) {
                        $failedArr[] = $unique_id;
                        $response_array = ['success' => $successArr, 'faild' => $failedArr];
                        return self::sentResponse(500, $response_array, __('digimed_validation.error_response.conflict_issue_for_schedule'));
                    }

                }


                $from_date = Carbon::parse($from_date_init)->format('Y-m-d');
                $date_until = Carbon::parse($date_until_init)->format('Y-m-d');
                $decodeFrmToTimeArr = $from_to_time_init;
                $decodeFrmToTimeCnt = count($decodeFrmToTimeArr);

                $str = @$week_days_init;
                if(isset($str)) {
                    $arr = array();
                    foreach (explode(",", $str) AS $val) {
                        array_push($arr, ucfirst(strtolower($val)));
                    }
                }

                if(!empty($arr)) { $week_days = implode(',', $arr); } else { $week_days = 'Mon,Tue,Wed,Thu,Fri,Sat,Sun'; }

                if(empty($update_id)) {
                    DB::beginTransaction();
                    $ScheduledApt = new ScheduledAppointment();

                    $queryScheduledApt = $ScheduledApt->where('doctor_id', $doctor_id)
                                            ->where('from_date', '=', date('Y-m-d', strtotime($from_date)))
                                            ->where('date_until', '=', date('Y-m-d', strtotime($date_until)))
                                            ->first();

                    if (is_null($queryScheduledApt)) {
                        $ScheduledApt->doctor_id = $doctor_id;
                        $ScheduledApt->from_date = $from_date;
                        $ScheduledApt->date_until = $date_until;
                        $ScheduledApt->week_days = $week_days;
                        $ScheduledApt->created_by = $doctor_id;
                        $ScheduledApt->save();
                        $LastScheduledAptId = $ScheduledApt->id;
                    } else {
                        $queryWeekDays = $queryScheduledApt->week_days;
                        $queryWeekDays = explode(",", $queryWeekDays);
                        $queryWeekDays = array_filter($queryWeekDays);
                        $week_days_input = explode(",", $week_days_init);
                        $week_days_input = array_filter($week_days_input);
                        $weekDaysConflict = array_intersect($week_days_input,$queryWeekDays);
                        $lvl = array_values($weekDaysConflict);

                        if(count($lvl) > 0) {
                            $LastScheduledAptId = $queryScheduledApt->id;
                        } else {
                            $ScheduledApt->doctor_id = $doctor_id;
                            $ScheduledApt->from_date = $from_date;
                            $ScheduledApt->date_until = $date_until;
                            $ScheduledApt->week_days = $week_days;
                            $ScheduledApt->created_by = $doctor_id;
                            $ScheduledApt->save();
                            $LastScheduledAptId = $ScheduledApt->id;
                        }
                    }

                    for ($k=0; $k < count($decodeFrmToTimeArr); $k++) {
                        $ScheduledAptDtls = new ScheduledAppointmentDetail();
                        $ScheduledAptDtls->scheduled_appointment_id = $LastScheduledAptId;
                        $dataFrmToTim = $decodeFrmToTimeArr[$k];
                        if($dataFrmToTim['from'] != "" && $dataFrmToTim['to']) {
                            $ScheduledAptDtls->from_time =$dataFrmToTim['from'];
                            $ScheduledAptDtls->to_time =$dataFrmToTim['to'];
                        }
                        $ScheduledAptDtls->created_by = $doctor_id;
                        $ScheduledAptDtls->save();
                    }
                    $successArr[] = $unique_id;
                    DB::commit();
                } else {
                    //Update
                    DB::beginTransaction();
                    $ScheduledApt = new ScheduledAppointment();
                    $queryScheduledApt = $ScheduledApt->where('id', $update_id)->first();
                    if (!is_null($queryScheduledApt)) {
                        $LastScheduledAptId = $queryScheduledApt->id;
                        $ScheduledApt->where('id', $update_id)->update(['from_date' => $from_date,'date_until' => $date_until,'week_days' => $week_days,'updated_by' => $doctor_id]);
                    }
                    if(!empty($LastScheduledAptId)) {
                        $ScheduledAptDtls = new ScheduledAppointmentDetail();
                        $ScheduledAptDtls->where('scheduled_appointment_id', '=', $LastScheduledAptId)->update(['deleted_by' => $doctor_id]);
                        $ScheduledAptDtls->where('scheduled_appointment_id', '=', $LastScheduledAptId)->delete();

                        for ($k=0; $k < count($decodeFrmToTimeArr); $k++) {
                            $ScheduledAptInner = new ScheduledAppointmentDetail();
                            $ScheduledAptInner->scheduled_appointment_id = $LastScheduledAptId;
                            $dataFrmToTim = $decodeFrmToTimeArr[$k];
                            $ScheduledAptInner->from_time =$dataFrmToTim['from'];
                            $ScheduledAptInner->to_time =$dataFrmToTim['to'];
                            $ScheduledAptInner->created_by = $doctor_id;
                            $ScheduledAptInner->save();
                        }
                    }
                    $successArr[] = $unique_id;
                    DB::commit();
                }

            }

            $response_array = ['success' => $successArr, 'faild' => $failedArr];
            return self::sentResponse(200, $response_array, __('digimed_validation.success_response.data_update_success'));

        } catch (Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function removeScheduledAppointment(RemoveScheduledAppointmentRequest $request)
    {
        try {
            $validated = $request->validated();
            $authRole = Auth::user();
            $auth_id = auth()->user()->id;
            $scheduledAppointment = ScheduledAppointment::find($request->id);
            $scheduledAppointment->deleted_by = $auth_id;
            $scheduledAppointment->save();
            $scheduledAppointment->delete();
            return self::sentResponse(200, [], __('digimed_validation.success_response.data_delete_success'));
        } catch (Exception | Throwable | QueryException $e) {
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function doctorNotes(DoctorNotesRequest $request)
    {
        try {
            $validated = $request->validated();
            $authRole = Auth::user();
            $auth_id = auth()->user()->id;
            // if(!$authRole->hasRole(['doctor'])) {
            //     return self::sentResponse(401, [], __('digimed_validation.error_response.not_authorized'));
            // }
            DB::beginTransaction();
            $appointmentDetails = Appointment::find($request->appointment_id);
            if($appointmentDetails->appointment_status == AppoitmentStatusEnum::NEW()) {
                return self::sentResponse(401, [], __('digimed_validation.error_response.invalid_appointment'));
            }
            if($appointmentDetails->appointment_status != AppoitmentStatusEnum::ACCEPTED()) {
                return self::sentResponse(401, [], __('digimed_validation.error_response.not_valid_appointment'));
            }
            $appointmentDetails->notes = $request->notes;
            $appointmentDetails->updated_by = auth()->user()->id;
            $appointmentDetails->save();
            DB::commit();
            return self::sentResponse(200, (object)[], __('digimed_validation.success_response.notes_stored_success'));
        } catch (Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function getDoctorNotes(DoctorNotesRequest $request)
    {
        try {
            $validated = $request->validated();
            $authRole = Auth::user();
            $auth_id = auth()->user()->id;
            $appointmentDetails = Appointment::select('id','notes')->find($request->appointment_id);
            return self::sentResponse(200, $appointmentDetails, __('digimed_validation.success_response.data_fetch_success'));
        } catch (Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function discountConfirmation(DiscountConfirmationRequest $request)
    {
        try {
            $validated = $request->validated();

            $authRole = Auth::user();
            $auth_id = auth()->user()->id;
            // if(!$authRole->hasRole(['doctor'])) {
            //     return self::sentResponse(401, [], __('digimed_validation.error_response.not_authorized'));
            // }
            DB::beginTransaction();
            $paymentDetails = Payment::where('appointment_id',$request->appointment_id)->first();

            $amount = $paymentDetails->consultation_fee;
            if(!empty($paymentDetails->voucher_code)) {
                if ($paymentDetails->voucher_code < $amount) {
                    $amount = $amount - $paymentDetails->voucher_code;
                }
            }

            $chargeAmount = $amount;

            if(!empty($request->discount) || $request->discount == 0)
            {
                $discountAmount = $amount * $request->discount * 0.01;

                if ($discountAmount > $amount) {
                    $discount = $amount;
                } elseif ($discountAmount <= 0) {
                    $discount = 0;
                } else {
                    $discount = $discountAmount;
                }

                if($discount < 1 && $discount > 0) {
                    DB::rollback();
                    return self::sentResponse(500, [], __('digimed_validation.error_response.discount_cost_greater').' '.number_format($discount, 2, '.', ''));
                }

                $chargeAmount = $chargeAmount - $discount;
                $chargeAmount = number_format($chargeAmount, 2, '.', '');

                $paymentDetails->discount = $request->discount;
                // $paymentDetails->total_amount = $paymentDetails->total_amount - $chargeAmount;
                $paymentDetails->updated_by = $auth_id;
                $paymentDetails->save();
            }
            // /**
            //  * @var array $stripeSecret
            //  */
            // $stripeSecret = Config::get('stripe.stripe_secret_key');
            // $stripe = new \Stripe\StripeClient($stripeSecret);
            // $intent = $stripe->paymentIntents->retrieve($paymentDetails->stripe_payment_id,[]);
            // $adminFees = $paymentDetails->platform_fee + $paymentDetails->transaction_fee + $paymentDetails->tax_amount;
            // $chargeAmount = number_format($chargeAmount, 2, '.', '');
            // $capture = [
            //     'application_fee_amount' => $adminFees * 100,
            //     'amount_to_capture' => ($chargeAmount + $adminFees) * 100
            // ];
            // $intent->capture($capture);
            $paymentDetails->payment_status = '1';
            $paymentDetails->fees_paid = $paymentDetails->total_amount;
            $paymentDetails->payment_details = $paymentDetails->total_amount;
            $paymentDetails->save();

            // $appointment = Appointment::find($request->appointment_id);
            // $appointment->appointment_status = AppoitmentStatusEnum::COMPLETED();
            // $appointment->save();

            DB::commit();
            return self::sentResponse(200, [], __('digimed_validation.success_response.discount_charges_success'));

        } catch (Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function patientDoctorList(PatientDoctorListRequest $request){
        $validated = $request->validated();
        try{
            $paginate = $request->count_per_page ? $request->count_per_page : 10;
            $pageNumber = $request->page ? $request->page : 1;
            /**
             * @var int|null $paginate
             * @var int|null $pageNumber
             */
            $sort_by_col = (isset($request->sort_by)) ? $request->sort_by : 'id';
            /** @var string $data_order_by */
            $data_order_by = $request->order_by;
            $orderBy = $request->order_by ? strtoupper($data_order_by) : strtoupper('asc');

            $auth_id = auth()->user()->id;
            $authRole = Auth::user();
            $data = $request->all();
            $specialisation = trim($data['area_specialisation'], ',');
            $experience = trim($data['experience'], ',');
            $audio_call = $data['audio_call'];
            $chat = $data['chat'];
            $video_call = $data['video_call'];
            $hospital_visit = $data['hospital_visit'];
            $language = trim($data['language'], ',');
            $type = $data['type'];
            $is_homevisit = $data['is_homevisit'];
            $is_schedule = $data['is_schedule'];
            $is_demand = $data['is_demand'];

            if($type == "1"){
                $list = User::role('doctor')->with(['roles','doctorDocument'])->whereHas('favouriteDoctors',function($q) use($auth_id){
                    $q->where('patient_id', $auth_id);
                })->where('status',['2']);
            }
            else{
                $list = User::role('doctor')->with(['roles','doctorDocument','userDetail'])->where('status',['2']);
            }
            if(!empty($language)){
                $languageArr = explode(',', $language);
                $list = $list->whereHas('userDetail.UserLanguage', function($q) use($languageArr) {
                    if(!empty(array_filter($languageArr))) {
                        foreach ($languageArr as $key => $value) {
                            if($key == 0) {
                                $q->where('language_id', $value);
                            } else {
                                $q->orWhere('language_id', $value);
                            }
                        }
                    }
                });
            }
            if(!empty($specialisation)){
                $idsArrAreaSpecialization = explode(',',$specialisation);
                $arrAreaSpecialization = array_filter($idsArrAreaSpecialization);
                $list = $list->whereHas('userDetail.UserAreaSpecialization', function($q) use($idsArrAreaSpecialization) {
                    if(!empty(array_filter($idsArrAreaSpecialization))) {
                        foreach ($idsArrAreaSpecialization as $key => $value) {
                            if($key == 0) {
                                $q->where('area_specialisation_id', $value);
                            } else {
                                $q->orWhere('area_specialisation_id', $value);
                            }
                        }
                    }
                });
            }
            if(!empty($audio_call)){
                $list = $list->whereHas('userDetail', function($q) use($audio_call){
                    $q->where('audio_call', '=', $audio_call);
                });
            }
            if(!empty($video_call)){
                $list = $list->whereHas('userDetail', function($q) use($video_call){
                    $q->where('video_call', '=', $video_call);
                });
            }
            if(!empty($hospital_visit)){
                $list = $list->whereHas('userDetail', function($q) use($hospital_visit){
                    $q->where('hospital_visit', '=', $hospital_visit);
                });
            }
            if(!empty($chat)){
                $list = $list->whereHas('userDetail', function($q) use($chat){
                    $q->where('chat', '=', $chat);
                });
            }
            if($sort_by_col == "id") {
                /**
                 * @var string|null $sort_by_col
                 * @var string|null $orderBy
                 */
                $list = $list->orderBy($sort_by_col, $orderBy);
            }
            $paginateData = $list->paginate($paginate, ['*'], 'page', $pageNumber);
            if($sort_by_col == "rating") {
                if($orderBy == "ASC") {
                    $paginateData->setCollection(
                        $paginateData->sortBy(function ($q) { return $q->avgratingdoctor; })
                    );
                }
                if($orderBy == "DESC") {
                    $paginateData->setCollection(
                        $paginateData->sortByDesc(function ($q) { return $q->avgratingdoctor; })
                    );
                }
            }

            if($sort_by_col == "price") {

                if($orderBy == "ASC") {
                    if($is_homevisit != "") {
                        $paginateData->setCollection(
                            $paginateData->sortBy(function ($q) { return $q->userDetail->home_visit_price; })
                        );
                    }
                    if($is_demand != "") {
                        $paginateData->setCollection(
                            $paginateData->sortBy(function ($q) { return $q->userDetail->on_demand_price; })
                        );
                    }
                    if($is_schedule != "") {
                        $paginateData->setCollection(
                            $paginateData->sortBy(function ($q) { return $q->userDetail->schedule_appointment_price; })
                        );
                    }
                }

                if($orderBy == "DESC") {
                    if($is_homevisit != "") {
                        $paginateData->setCollection(
                            $paginateData->sortByDESC(function ($q) { return $q->userDetail->home_visit_price; })
                        );
                    }
                    if($is_demand != "") {
                        $paginateData->setCollection(
                            $paginateData->sortByDESC(function ($q) { return $q->userDetail->on_demand_price; })
                        );
                    }
                    if($is_schedule != "") {
                        $paginateData->setCollection(
                            $paginateData->sortByDESC(function ($q) { return $q->userDetail->schedule_appointment_price; })
                        );
                    }
                }
            }

            $list = collect();
            $paginateData->getCollection()->each(function ($data) use (&$list){
                $list->push($data);
            });

            $result['doctors'] = $list;
            $result['total_count'] = $paginateData->total();
            $result['last_page'] = $paginateData->lastPage();
            $result['current_page'] = $paginateData->currentPage();

            return self::sentResponse(200, $result, __('digimed_validation.success_response.data_fetch_success'));
        }
        catch (Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function doctorUnavailableList(DoctorUnavailableListRequest $request) {
        try {
            $validated = $request->validated();
            $auth_id = $request->doctor_id;
            $unavailableQ = DoctorUnavailable::select('unavailables_at')->where('user_id', $auth_id)->get();
                $unavailableArr = [];
            foreach($unavailableQ AS $val) {
                $jsonQ['title'] = 'Unavailable';
                $jsonQ['start'] = $val->unavailables_at;
                $jsonQ['end'] = $val->unavailables_at;
                $jsonQ['type'] = 0;
                $jsonQ['display'] = "background";
                array_push($unavailableArr, $jsonQ);
            }
            $response_array = ["unavailable" => $unavailableArr];
                return self::sentResponse(200, $response_array, __('digimed_validation.success_response.data_fetch_success'));
        } catch(Exception | Throwable | QueryException $e) {
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    public function doctorClinicList(Request $request, UserClinic $userClinic, UserDetails $userDetails)
    {
        $auth_id = auth()->user()->id;
        $userDetail = $userDetails->where('user_id', $auth_id)->first()->id;
        $clinics = $userClinic->where('user_detail_id', $userDetail)->pluck('clinic_id');
        $resultSet = Clinic::select('id','name')->find($clinics);
        if(count($resultSet) > 0) {
            $out['clinics'] = $resultSet;
        } else {
            $out['clinics'] = array();
        }
        return self::sentResponse(200, $out, __('digimed_validation.success_response.data_fetch_success'));
    }

    public function homevisitDoctorAvailable(DoctorHomeVisitAvailableRequest $request)
    {
        $validated = $request->validated();
        try {
            $is_homevisit = $request->is_homevisit;
            $is_demand = $request->is_on_demand;
            $auth_id = auth()->user()->id;
            $doctor_id = $request->doctor_id;

            $query = User::select('users.*','cp.price','cp.currency_code','cp.type AS consultation_id')->role('doctor')
            ->leftJoin('consultation_prices AS cp', 'users.id', '=', 'cp.user_id')
            ->with(['roles','doctorDocument','userDetail','sumSub', 'favouriteDoctors'])
            ->whereIn('users.user_completion', [6,7])
            ->where('users.id',$doctor_id);

            // Doctor Availability On Demand Check
            if(!empty($is_demand)) {
                $query->where('cp.type', '3');
            }

            if(!empty($is_demand)){
                $query->whereHas('userDetail', function($q) {
                    $q->where('on_demand_available_status', 1);
                });
            }

            if($is_demand != 0) {
                $query->WhereHas('userDetail', function($q) use($is_demand) {
                    $q->where('on_demand', '=', $is_demand);
                });
            }
            // Doctor Availability On Demand Check

            // Doctor Availability Home Visit Check
            if(!empty($is_homevisit)) {
                $query->where('cp.type', '2');
            }

            if(!empty($is_homevisit)){
                $doctorArr = [];
                if(isset($request->lat_long)){
                    /** @var string $data_lat_long */
                    $data_lat_long = $request->lat_long;
                    $decode = json_decode(str_replace('\\', '', $data_lat_long), TRUE);//json_decode($data_lat_long);
                    /** @var object|array $decode */
                    if(!empty((array)$decode)){
                        $dataLat = $decode['lat'];
                        $dataLong = $decode['long'];
                        $queryLocation = DB::table("user_details")->select("user_details.id",'user_details.user_id',"user_details.home_visit_radius"
                            ,DB::raw("6371 * acos(cos(radians(" . $dataLat . "))
                            * cos(radians(user_details.home_visit_latitude))
                            * cos(radians(user_details.home_visit_longitude) - radians(" . $dataLong . "))
                                + sin(radians(" .$dataLat. "))
                            * sin(radians(user_details.home_visit_latitude))) AS distance"))
                                ->get();
                        /**
                         * @var object $queryLocation
                         */
                        for ($i=0; $i < count($queryLocation); $i++) {
                            if($queryLocation[$i]->distance < $queryLocation[$i]->home_visit_radius) {
                                $doctorArr[] = $queryLocation[$i]->user_id;
                            }
                        }
                        if(count($doctorArr) > 0){
                            $query->whereIn('users.id',$doctorArr);
                        }
                    }
                }
                if(isset($request->home_visit_dt)){
                    /** @var string $data_decode */
                    $data_decode = $request->home_visit_dt;
                    $decode = json_decode(str_replace('\\', '', $data_decode), TRUE);//json_decode($data_decode);
                    /** @var object|array $decode */
                    if(($decode) != "") {
                        $dataDate = $decode['date'];
                        $current = Carbon::now()->format("Y-m-d");
                        $date = Carbon::parse($dataDate)->format('Y-m-d');

                        if($date >= $current){
                            $day = Carbon::parse($dataDate)->format('D');

                            $list = UserDetails::whereRaw("find_in_set('".$day."',home_visit_weekdays)")->whereIn('user_id',$doctorArr)->where('home_visit',1)->get();
                            $doctors = [];
                            foreach($list as $row){
                                $request_from_time = Carbon::make($row['home_visit_from_time']);
                                $from_time = Carbon::parse($request_from_time)->format("H:i:s");
                                $request_to_time = Carbon::make($row['home_visit_to_time']);
                                $to_time = Carbon::parse($request_to_time)->format("H:i:s");
                                $user_id = $row['user_id'];

                                $range = $decode['range'];//$decode->range;
                                foreach ($range as $key => $value) {
                                    $dtFrom = $value['from'];
                                    $dtTo = $value['to'];
                                    $range_from = Carbon::parse($dtFrom)->format("H:i:s");
                                    $range_to = Carbon::parse($dtTo)->format("H:i:s");
                                    if(strtotime($range_from) > strtotime($from_time) && strtotime($range_from) < strtotime($to_time) ) {
                                        $doctors[] = $user_id;
                                    }
                                    if(strtotime($range_to) > strtotime($from_time) && strtotime($range_to) < strtotime($to_time) ) {
                                        $doctors[] = $user_id;
                                    }
                                }
                            }
                            $final_doctors = array_unique($doctors);
                            $query->whereIn('users.id',$final_doctors);
                        }
                    }
                }
            }

            $query->where('users.status','2');

            if($is_homevisit != 0) {
                $query->WhereHas('userDetail', function($q) use($is_homevisit) {
                    $q->where('home_visit', '=', $is_homevisit);
                });
            }
            // Doctor Availability Home Visit Check

            $list = $query->count();
            $result['status'] = $list;

            return self::sentResponse(200, $result, __('digimed_validation.success_response.data_fetch_success'));
        } catch(Exception | Throwable | QueryException $e) {
            return self::sentResponse(500, [], $e->getMessage());
        }
    }

    //Update Doctors Additional Info
    public function additionalInfoSave(DoctorsProfileRequest $request)
    {
        try
        {
            $validated = $request->validated();
            DB::beginTransaction();
            $user = UserAdditionalInfo::where('user_id',$request->user_id)->first();
            if($user){
                UserAdditionalInfo::where('user_id', $request->user_id)->update([
                'education_data' => json_encode($request->education),
                'experience_data' => json_encode($request->experience),
                'awards_data' => json_encode($request->awards),
                'memberships_data' => json_encode($request->memberships),
                'registrations_data' => json_encode($request->registrations)
                ]);

            }else{
                UserAdditionalInfo::create([
                'user_id' => $request->user_id,
                'education_data' => json_encode($request->education),
                'experience_data' => json_encode($request->experience),
                'awards_data' => json_encode($request->awards),
                'memberships_data' => json_encode($request->memberships),
                'registrations_data' => json_encode($request->registrations)
                ]);
            }
            if ($request->has('experience') && is_array($request->experience) && !empty($request->experience)) {
                $totalExperience = 0;
                $experienceData = $request->input('experience');
                foreach ($experienceData as $experience) {
                    $fromYear = (int) $experience['from_year'];
                    $toYear = (int) $experience['to_year'];
                    $totalExperience += ($toYear - $fromYear);
                }
                $totalDoctorExperience = $totalExperience;
                UserDetails::where('user_id', $request->user_id)->update([
                    'experience' => $totalDoctorExperience
                ]);
            }
            DB::commit();
            $response_array = [];
            return self::sentResponse(200,$response_array,__('digimed_validation.success_response.additional_info_update_success'));
        }
        catch(\Exception | Throwable | QueryException $e) {
            DB::rollback();
            return self::sentResponse(500,[], $e->getMessage());
        }
    }
}