<?php

namespace App\Traits;
use DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use App\Models\User;

use App\Jobs\SendEmailJob;
use App\Models\RosterAssign;
use Illuminate\Http\Request;
use App\Models\PublicHoliday;
use App\Models\RosterHistory;
use App\Models\LinkManagement;
use App\Models\RosterTemplate;
use Illuminate\Validation\Rule;
use App\Models\EmpCompanyDetails;
use App\Models\EmpPersonalDetails;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Traits\EmailTrait;
use App\Models\Sites;
trait RosterTemplateTrait
{
    use EmailTrait;
    public function exampleFunction()
    {
        return response()->json([
            'message' => 'Shift Create Successfully this is eampale of simple trait'
        ],200);
    }

    public function handleRosterTemplate($request)
    {
        $validator = Validator::make($request->all(), [
            'user_id' => 'required',
            'date' => 'required',
            'template_id' => $request->edit == "edit" ? 'required' : 'nullable',
            'publish' => 'required',
            'start_time' => 'required',
            'end_time' => 'required',
            'break_minutes' => 'nullable|integer|min:0',
            'color_code' => 'required',
            'shift_notes' => 'nullable',
            'repeat_shift' => 'nullable',
            'repeat_every' => 'nullable',
            'end_date' => 'required',
            'save_shift' => 'required',
            'edit' => 'nullable',
            'working_hours' => 'required|min:1',
            'site_id' => 'nullable|integer|exists:sites,id',
            'project_id' => 'nullable|integer|exists:projects,id'
        ],[
            'working_hours.required' => 'Working hours is required',
            'working_hours.min' => 'Working hours must be greater than 0',
            'site_id.exists' => 'Selected site does not exist',
            'break_minutes.integer' => 'Break minutes must be an integer',
            'break_minutes.min' => 'Break minutes must be greater than 0',
            'project_id.exists' => 'Selected project does not exist'
        ]);

        if ($validator->fails()) {
            return $this->handleValidationFailure($validator); 
        }

        // Get user and workspace details
        $userTable = $this->getUserTable();
        $auth_id = 0;
        $workspace_id = 0;
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;  
            $authPersonalDetails = User::where('id', Auth::user()->id)->first();
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
            $authPersonalDetails = EmpPersonalDetails::where('emp_id', Auth::user()->id)->first();  
        }

        $validatedData = $validator->validated();
        
        // Initialize changes array
        $changes = [];
        
        // Calculate required minutes
        $start_ = Carbon::parse($request->start_time);
        $end_ = Carbon::parse($request->end_time);
        
        // Handle next day scenario (e.g., 11:00 PM to 7:00 AM)
        if ($end_->lessThan($start_)) {
            $end_->addDay(); // Add 24 hours if end time is next day
        }
        
        $required_minutes = $end_->diffInMinutes($start_);
        $required_minutes -= $request->break_minutes ?? 0;

        // Calculate required hours from time difference
        $required_hours = round($required_minutes / 60, 2);

        // Validate that we have positive working time
        if ($required_minutes <= 0) {
            return $this->message(
                'Invalid time range. End time must be after start time, and break time cannot exceed the total time between start and end time.',
                422
            );
        }

        // Validate working_hours if provided against calculated time difference
        $working_hours = null;
        if (isset($request->working_hours) && !empty($request->working_hours)) {
            $working_hours_input = floatval($request->working_hours);
            
            // Check if working hours is positive
            if ($working_hours_input <= 0) {
                return $this->message('Working hours must be greater than 0.', 422);
            }
            
            // Check if working hours is greater than the calculated time difference
            // Working hours should be less than or equal to the time difference between start and end time
            if ($working_hours_input > $required_hours) {
                return $this->message(
                    'Total Required Hours between start time (' . $request->start_time . ') and end time (' . $request->end_time . ') is ' . $required_hours . ' hours. Please enter ' . $required_hours . ' or less hours in Total Required Hours field.',
                    422
                );
            }
            
            $working_hours = $working_hours_input * 60; // Convert hours to minutes
        } else {
            $working_hours = $required_minutes; // Use calculated minutes
        }

        // Validate dates
        if (date('Y-m-d', strtotime($request->date)) < date('Y-m-d')) {
            return $this->message('Scheduler does not allow changes to be made for past dates.', 422); 
        }

        if (date('Y-m-d', strtotime($request->end_date)) < date('Y-m-d', strtotime($request->date))) {
            return $this->message('End Date must be bigger than or equal to ' . date('d-m-Y', strtotime($request->date)) . ' date.', 422);
        }

        // Validate that end time is greater than start time
        if (Carbon::parse($request->end_time)->lte(Carbon::parse($request->start_time))) {
            return $this->message('End time must be greater than start time.', 422);
        }

        // Handle edit case first
        if ($request->edit == "edit") {
            $existingTemplate = RosterTemplate::where(['id' => $request->template_id])->first();
            if (!$existingTemplate) {
                return $this->message('Template not found', 404);
            }

            // Compare fields for changes
            $fieldsToCompare = ['start_time', 'end_time', 'break_minutes', 'color_code','working_hours','site_id','project_id'];            
            foreach ($fieldsToCompare as $field) {
                if ($existingTemplate->$field != $validatedData[$field]) {
                    $changes[$field] = [
                        'old' => $existingTemplate->$field,
                        'new' => $validatedData[$field]
                    ];
                }
            }

            if (empty($changes)) {
                return $this->message('No Data Changed', 200);
            }

            // Delete existing assignments for this user on this date
            RosterAssign::where([
                'assign_to' => $request->user_id,
                'roster_template_id' => $request->template_id,
                'schedule_date' => $request->date,
                'customer_id' => $auth_id,
                'workspace_id' => $workspace_id,
            ])->delete();

            // Create a new template with updated settings
            $templateData = [
                'start_time' => $request->start_time,
                'end_time' => $request->end_time,
                'break_minutes' => $request->break_minutes ?? 0,
                'color_code' => $request->color_code,
                'shift_notes' => $request->shift_notes,
                'repeat_shift' => $request->repeat_shift ?? '0',
                'repeat_every' => $request->repeat_shift == '1' ? $request->repeat_every : '',
                'end_date' => $request->end_date,
                'working_hours' => $working_hours,
                'created_by' => $auth_id,
                'customer_id' => $auth_id,
                'workspace_id' => $workspace_id,
                'is_saved' => $request->save_shift == '1' ? $request->save_shift : '0',
                'site_id' => $request->site_id ?? null,
                'project_id' => $request->project_id ?? null,
            ];

            $insert_id = RosterTemplate::insertGetId($templateData);

        } else {
            // Check for shift overlaps only for new shifts
            $fixedStartTime = $request->start_time; 
            $fixedEndTime = $request->end_time; 
            
            $overlapExists = RosterAssign::where('assign_to', $request->user_id)
                ->where('schedule_date', $request->date)
                ->where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->where('site_id', $request->site_id ?? null)
                ->where('project_id', $request->project_id ?? null)
                ->pluck('roster_template_id');

            if ($overlapExists->isNotEmpty()) {
                $matchingTemplates = RosterTemplate::whereIn('id', $overlapExists)->get();
                foreach ($matchingTemplates as $range) {
                    if ($this->isOverlap($fixedStartTime, $fixedEndTime, $range->start_time, $range->end_time)) {
                        return $this->message('Shift Conflict: already assigned a shift during this time. Please choose a different time slot.', 422);
                    }
                }
            }

            // Create new template
            $templateData = [
                'start_time' => $request->start_time,
                'end_time' => $request->end_time,
                'break_minutes' => $request->break_minutes ?? 0,
                'color_code' => $request->color_code,
                'shift_notes' => $request->shift_notes,
                'repeat_shift' => $request->repeat_shift ?? '0',
                'repeat_every' => $request->repeat_shift == '1' ? $request->repeat_every : '',
                'end_date' => $request->end_date,
                'working_hours' => $working_hours,
                'created_by' => $auth_id,
                'customer_id' => $auth_id,
                'workspace_id' => $workspace_id,
                'is_saved' => $request->save_shift == '1' ? $request->save_shift : '0',
                'site_id' => $request->site_id ?? null,
                'project_id' => $request->project_id ?? null,
            ];

            $insert_id = RosterTemplate::insertGetId($templateData);
        }

        // Create assignment
        RosterAssign::insertGetId([
            'assign_to' => $request->user_id,
            'roster_template_id' => $insert_id,
            'schedule_date' => $request->date,
            'customer_id' => $auth_id,
            'workspace_id' => $workspace_id,
            'site_id' => $request->site_id ?? null,
            'project_id' => $request->project_id ?? null,
        ]);

        // Store history
        $empPersonalDetails = EmpPersonalDetails::where('emp_id', $request->user_id)->first();

        if ($userTable === "customer") {
            $history_arr = [
                'description' => "<a href='".url('/')."/user-profile/".Auth::user()->id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> ".($authPersonalDetails->name ?? '')."</a> assigned shift '{$insert_id}' template to '".($empPersonalDetails ? $empPersonalDetails->first_name.' '.$empPersonalDetails->middle_name.' '.$empPersonalDetails->last_name : 'Unknown Employee')."' at '".date('d-m-Y', strtotime($request->date))."' date.",
                'roster_template_id' => $insert_id
            ];
        }
        if ($userTable === "emp") {
            $history_arr = [
                'description' => "<a href='".url('/')."/user-profile/".Auth::user()->id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> ".($authPersonalDetails ? $authPersonalDetails->first_name.' '.$authPersonalDetails->middle_name.' '.$authPersonalDetails->last_name : 'Unknown User')."</a> assigned shift '{$insert_id}' template to '".($empPersonalDetails ? $empPersonalDetails->first_name.' '.$empPersonalDetails->middle_name.' '.$empPersonalDetails->last_name : 'Unknown Employee')."' at '".date('d-m-Y', strtotime($request->date))."' date.",
                'roster_template_id' => $insert_id
            ];
        }
        $this->storeHistory($history_arr);

        // Send email notification to the assigned user
        $requestUserEmail = $empPersonalDetails->companyDetails->employee_email ?? null;
        if ($requestUserEmail) {
            try {
                // Get the roster template details for email
                $rosterTemplate = RosterTemplate::find($insert_id);
        
                $emailData = [
                    'name' => $empPersonalDetails->first_name . ' ' . ($empPersonalDetails->middle_name ? $empPersonalDetails->middle_name . ' ' : '') . $empPersonalDetails->last_name,
                    'subject' => ($request->edit == "edit" ? 'Work Schedule Updated' : 'Work Schedule Assignment') . ' - ' . env('APP_NAME'),
                    'schedule_date' => date('d-m-Y', strtotime($request->date)),
                    'day_name' => date('l', strtotime($request->date)),
                    'start_time' => date('h:i A', strtotime($request->start_time)),
                    'end_time' => date('h:i A', strtotime($request->end_time)),
                    'break_minutes' => $request->break_minutes ?? 0,
                    'shift_notes' => $request->shift_notes ?? '',
                    'roster_template_name' => 'Work Shift',
                    'assigned_by' => $userTable === "customer" 
                        ? ($authPersonalDetails->name ?? 'Admin') 
                        : ($authPersonalDetails ? $authPersonalDetails->first_name . ' ' . $authPersonalDetails->last_name : 'Admin'),
                    'is_edit' => $request->edit == "edit",
                    'changes' => isset($changes) ? $changes : null,
                    'working_hours' => round($working_hours / 60, 2) // Convert back to hours for display
                ];
        
                // Prepare email parameters
                $emailParams = [
                    'to' => $requestUserEmail,
                    'subject' => $emailData['subject'],
                    'msg' => view('Emails.roster_notification', $emailData)->render()
                ];
        
                // Send the email
                $this->SendInstantEmail($emailParams);
        
                // Log success
                \Log::info('Roster email sent successfully', [
                    'to' => $requestUserEmail,
                    'subject' => $emailData['subject'],
                    'insert_id' => $insert_id
                ]);
        
            } catch (\Throwable $e) {
                // Log the error with details
                \Log::error('Failed to send roster email', [
                    'to' => $requestUserEmail,
                    'insert_id' => $insert_id,
                    'error_message' => $e->getMessage(),
                    'error_trace' => $e->getTraceAsString()
                ]);
            }
        }
        

        // Publish if requested
        if ($request->publish) {
            $this->publish_specific_person($request->user_id);
        }

        // Return appropriate message based on operation type
        if ($request->edit == "edit") {
            return $this->message('Shift Updated Successfully', 200);
        } else {
            return $this->message('Shift Created Successfully', 200);
        }
    }

    public function rosterTemplateAssign($request)
    {
      
        if(date('Y-m-d', strtotime($request->date)) < date('Y-m-d'))
        {
            return $this->message('Scheduler does not allow changes to be made for past dates',422);
           
        }
        $userTable = $this->getUserTable();
        $auth_id =0;
        $workspace_id = 0;
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;  
            $authPersonalDetails = User::where('id', Auth::user()->id)->first();
          
            
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
            $authPersonalDetails = EmpPersonalDetails::where('emp_id', Auth::user()->id)->first();  
        }
         $requestUser = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $request->user_id)->first();
         
        if ($requestUser->customer_id != $auth_id)
        {
            return $this->message("Don't have access",403);
          
        }
          
        $RosterTemplate =   RosterTemplate::find($request->template_id);
        if (!$RosterTemplate)
        {
            return $this->message("Roster not found",403);
          
        }
       
        $start_ = Carbon::parse($RosterTemplate->start_time);
        $end_ = Carbon::parse($RosterTemplate->end_time);
        $site_id = $RosterTemplate->site_id;
        $required_minutes =  $end_->diffInMinutes($start_); 
        $required_minutes = $required_minutes - $RosterTemplate->break_minutes ?? 0;
        $fixedStartTime = $RosterTemplate->start_time;
        $fixedEndTime = $RosterTemplate->end_time;
        $overlapExists = RosterAssign::where('assign_to',$request->user_id)->where('schedule_date',$request->date)->where('customer_id',$auth_id)->where('workspace_id',$workspace_id)->where('site_id',$site_id)->pluck('roster_template_id');
        if($overlapExists)
        {
            $matchingTemplates = RosterTemplate::whereIn('id', $overlapExists)->get();
            foreach ($matchingTemplates as $range) {
                $start = $range->start_time; 
                $end =  $range->end_time; 
                if ($this->isOverlap($fixedStartTime, $fixedEndTime, $start, $end)) {
                    return $this->message("Shift Conflict :already assigned a shift during this time. Please choose a different time slot.",422);
                   
                   
                }
                else{
                    // return response()->json([
                    //     'message' => 'Done  Please choose a different time slot. '
                    // ],422);
                }
            }
            
        }
       
        RosterAssign::insert([
            'assign_to' => $request->user_id,
            'roster_template_id' => $request->template_id,
            'schedule_date' => $request->date,
            'customer_id' =>  $auth_id,
            'workspace_id' =>  $workspace_id,
            'site_id' => $site_id,
        ]);
        // $authPersonalDetails = EmpPersonalDetails::where('emp_id', Auth::user()->id)->first();
        $empPersonalDetails  = EmpPersonalDetails::where('emp_id', $request->user_id)->first();
        if ($userTable === "customer") {
            $history_arr = [
                'description' => "<a href='".url('/')."/user-profile/".Auth::user()->id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$authPersonalDetails->name} </a> assigned  shift '{$request->template_id}' template to '{$empPersonalDetails->first_name} {$empPersonalDetails->middle_name} {$empPersonalDetails->last_name}'  at '".date('d-m-Y', strtotime($request->date))."' date .",
                'roster_template_id' => $request->template_id
            ];
        }
        if ($userTable === "emp") {
            $history_arr = [
                'description' => "<a href='".url('/')."/user-profile/".Auth::user()->id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$authPersonalDetails->first_name} {$authPersonalDetails->middle_name} {$authPersonalDetails->last_name}</a> assigned  shift '{$request->template_id}' template to '{$empPersonalDetails->first_name} {$empPersonalDetails->middle_name} {$empPersonalDetails->last_name}'  at '".date('d-m-Y', strtotime($request->date))."' date .",
                'roster_template_id' => $request->template_id
            ];
    
        }
        $this->storeHistory($history_arr);
        
        // Send email notification to the assigned user
        $siteName = Sites::where('id', $site_id)->first();
        $siteName = $siteName ? $siteName->title : null;
        $requestUserEmail = $requestUser->employee_email ?? null;
        if ($requestUserEmail) {
            $emailData = [
                'name' => $empPersonalDetails->first_name . ' ' . ($empPersonalDetails->middle_name ? $empPersonalDetails->middle_name . ' ' : '') . $empPersonalDetails->last_name,
                'subject' => 'Work Schedule Assignment Notification - ' . env('APP_NAME'),
                'schedule_date' => date('d-m-Y', strtotime($request->date)),
                'day_name' => date('l', strtotime($request->date)),
                'start_time' => date('h:i A', strtotime($RosterTemplate->start_time)),
                'end_time' => date('h:i A', strtotime($RosterTemplate->end_time)),
                'break_minutes' => $RosterTemplate->break_minutes ?? 0,
                'shift_notes' => $RosterTemplate->shift_notes ?? '',
                'roster_template_name' => $RosterTemplate->name ?? 'Work Shift',
                'assigned_by' => $userTable === "customer" ? $authPersonalDetails->name : $authPersonalDetails->first_name . ' ' . $authPersonalDetails->last_name,
                'site_name' => $siteName ?? null
            ];
            
            // Send the email
            $emailParams = [
                'to' => $requestUserEmail,
                'subject' => $emailData['subject'],
                'msg' => view('Emails.roster_notification', $emailData)->render()
            ];
            $this->SendInstantEmail($emailParams);
        }
        
        return response()->json([
            'message' => 'Template Assign Successfully'
        ],200);


    }
    public function bulkScheduleRoasterCreate($validatedData,$request)
    {      
            $days_array =  explode(",", $validatedData['working_days_hidden']);
            $start_ = Carbon::parse($request['start_time']);
            $end_ = Carbon::parse($request['end_time']);

            if ($end_->lessThan($start_)) {
                $end_->addDay();
            }

            $required_minutes = $end_->diffInMinutes($start_);
            $required_minutes -= $request['break_minutes'] ?? 0;

            if ($required_minutes <= 0) {
                return $this->message(
                    'Invalid time range. End time must be after start time, and break time cannot exceed the total time between start and end time.',
                    422
                );
            }

            $required_hours = round($required_minutes / 60, 2);

            $working_hours = null;
            if (isset($request['working_hours']) && !empty($request['working_hours'])) {
                $working_hours_input = floatval($request['working_hours']);

                if ($working_hours_input <= 0) {
                    return $this->message('Working hours must be greater than 0.', 422);
                }

                if ($working_hours_input > $required_hours) {
                    return $this->message(
                        'Total Required Hours between start time (' . $request['start_time'] . ') and end time (' . $request['end_time'] . ') is ' . $required_hours . ' hours. Please enter ' . $required_hours . ' or less hours in Total Required Hours field.',
                        422
                    );
                }

                $working_hours = $working_hours_input * 60;
            } else {
                $working_hours = $required_minutes  * 60;
            }
            $getDatesBetweens = $this->getDatesBetween($request['start_date'], $request['end_date']);

            foreach($getDatesBetweens as $for_this_date)
            {
               if(!in_array(Carbon::parse($for_this_date)->format('D'), $days_array))
               {
                   continue;
               }
               foreach($request['users_ids'] as  $user_id)
               {         
                   $fixedStartTime = $request['start_time']; 
                   $fixedEndTime = $request['end_time']; 
                   $overlapExists = RosterAssign::where('assign_to', $user_id)
                           ->where('schedule_date', $for_this_date)
                           ->pluck('roster_template_id');
                   if ($overlapExists->isNotEmpty()) {
                       // Fetch the matching templates
                       $matchingTemplates = RosterTemplate::whereIn('id', $overlapExists)->get();
                       // Iterate through the matching templates to check for overlaps
                       foreach ($matchingTemplates as $range) {
                           $start = $range->start_time; 
                           $end = $range->end_time; 
                           // Check if there is an overlap
                           if ($this->isOverlap($fixedStartTime, $fixedEndTime, $start, $end)) {
                               $emp= EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->find($user_id);
                               return $this->message('Shift Conflict'.' '
                                   . $emp->empPersonalDetails->first_name . ' '
                                   . ($emp->empPersonalDetails->middle_name ? $emp->empPersonalDetails->middle_name . ' ' : '') // Check if middle name exists
                                   . $emp->empPersonalDetails->last_name.' '
                                   .':is already assigned a shift during this time. Please choose a different time slot.',422);  
                           }
                           else{
                               // return response()->json([
                               //     'message' => 'Done  Please choose a different time slot. '
                               // ],422);
                           }    
                       }
                   }  
               }

            } 
            $insert_id = 0;
            $shiftAlreadyCreated = false;
            $userTable = $this->getUserTable();
            $auth_id =0;
            $workspace_id = 0;
            if ($userTable === "customer") {
                $auth_id = Auth::user()->id;
                $workspace_id = Auth::user()->current_workspace_id;  
                $authPersonalDetails = User::where('id', Auth::user()->id)->first();
                
            }
            if ($userTable === "emp") {
                $auth_id = auth()->user()->customer_id;
                $workspace_id = auth()->user()->workspace_id;
                $authPersonalDetails = EmpPersonalDetails::where('emp_id', Auth::user()->id)->first();  
            } 
            foreach($getDatesBetweens as $for_this_date)
            {
                if(!in_array(Carbon::parse($for_this_date)->format('D'), $days_array))
                {
                    continue;
                }
                foreach($request['users_ids'] as  $user_id)
                {         
                    if (!$shiftAlreadyCreated) {
                        $insert_id =   RosterTemplate::insertGetId([
                            'start_time' => $request['start_time'],
                            'end_time' => $request['end_time'],
                            'break_minutes' => $request['break_minutes'],
                            'color_code' => $request['color_code'],
                            'shift_notes' => $request['shift_notes'],
                            'repeat_shift' => 0,
                            'repeat_every' => 0,
                            'end_date' => $for_this_date,
                            'working_hours' => $working_hours,
                            'is_saved' => '0',
                           'created_by' => Auth::check() ? Auth::user()->id : 1,
                           'customer_id' => $auth_id,
                           'workspace_id' => $workspace_id,
                           'site_id' => $request['site_id'] ?? null,
                           'project_id' => $request['project_id'] ?? null,
                        ]);
                        $shiftAlreadyCreated = true;
                    }
                    RosterAssign::insertGetId([
                        'assign_to' => $user_id,
                        'roster_template_id' =>  $insert_id,
                        'schedule_date' => $for_this_date,
                        'customer_id' => $auth_id,
                        'workspace_id' => $workspace_id,
                        'site_id' => $request['site_id'] ?? null,
                        'project_id' => $request['project_id'] ?? null,
                        ]);

                }
            }
            if(Auth::check() )
            {
                if ($userTable === "customer") {
                    $history_arr = [
                        'description' => "<a href='".url('/')."/user-profile/".Auth::user()->id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$authPersonalDetails->name} </a> created a bulk schedule at ".date('d-m-Y')." date",
                        'roster_template_id' => 0
                    ];  
                }
                if ($userTable === "emp") {
                    $history_arr = [
                        'description' => "<a href='".url('/')."/user-profile/".Auth::user()->id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$authPersonalDetails->first_name} </a> created a bulk schedule at ".date('d-m-Y')." date",
                        'roster_template_id' => 0
                    ];
                }
                $this->storeHistory($history_arr);
            }
            else
            {
                $authPersonalDetails = EmpPersonalDetails::where('emp_id', 1)->first();
                $history_arr = [
                    'description' => "<a href='".url('/')."/user-profile/1"."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$authPersonalDetails->first_name} {$authPersonalDetails->middle_name} {$authPersonalDetails->last_name}</a> created a bulk schedule at ".date('d-m-Y')." date",
                    'roster_template_id' => 0
                ];
                $this->storeHistory($history_arr);

            }
            return $this->message("Bulk Schedule Created Successfully",200);
    }
    public function externalbulkScheduleRoasterCreate($validatedData,$request,$key)
    {      
            $days_array =  explode(",", $validatedData['working_days_hidden']);
            $start_ = Carbon::parse($request['start_time']);
            $end_ = Carbon::parse($request['end_time']);
            
            // Use working_hours from LinkManagement if available, otherwise calculate from times
            if (isset($request['working_hours']) && !empty($request['working_hours'])) {
                $required_minutes = $request['working_hours'] * 60; // Convert hours to minutes
            } else {
                $required_minutes =  $end_->diffInMinutes($start_); 
                $required_minutes = $required_minutes - ($request['break_minutes'] ?? 0);
            }
            $getDatesBetweens = $this->getDatesBetween($request['start_date'], $request['end_date']);

            foreach($getDatesBetweens as $for_this_date)
            {
               if(!in_array(Carbon::parse($for_this_date)->format('D'), $days_array))
               {
                   continue;
               }
               foreach($request['users_ids'] as  $user_id)
               {         
                   $fixedStartTime = $request['start_time']; 
                   $fixedEndTime = $request['end_time']; 
                   $overlapExists = RosterAssign::where('assign_to', $user_id)
                           ->where('schedule_date', $for_this_date)
                           ->pluck('roster_template_id');
                   if ($overlapExists->isNotEmpty()) {
                       // Fetch the matching templates
                       $matchingTemplates = RosterTemplate::whereIn('id', $overlapExists)->get();
                       // Iterate through the matching templates to check for overlaps
                       foreach ($matchingTemplates as $range) {
                           $start = $range->start_time; 
                           $end = $range->end_time; 
                           // Check if there is an overlap
                           if ($this->isOverlap($fixedStartTime, $fixedEndTime, $start, $end)) {
                               $emp= EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->find($user_id);
                               return $this->message('Shift Conflict'.' '
                                   . $emp->empPersonalDetails->first_name . ' '
                                   . ($emp->empPersonalDetails->middle_name ? $emp->empPersonalDetails->middle_name . ' ' : '') // Check if middle name exists
                                   . $emp->empPersonalDetails->last_name.' '
                                   .':is already assigned a shift during this time. Please choose a different time slot.',422);  
                           }
                           else{
                               // return response()->json([
                               //     'message' => 'Done  Please choose a different time slot. '
                               // ],422);
                           }    
                       }
                   }  
               }

            } 
            $insert_id = 0;
            $shiftAlreadyCreated = false;
            $link_detail=LinkManagement::where('secret_key',$key)->first();
            $auth_id=$link_detail->customer_id;
            $workspace_id=$link_detail->workspace_id;
            foreach($getDatesBetweens as $for_this_date)
            {
                if(!in_array(Carbon::parse($for_this_date)->format('D'), $days_array))
                {
                    continue;
                }
                foreach($request['users_ids'] as  $user_id)
                {         
                    if (!$shiftAlreadyCreated) {
                        $insert_id =   RosterTemplate::insertGetId([
                            'start_time' => $request['start_time'],
                            'end_time' => $request['end_time'],
                            'break_minutes' => $request['break_minutes'],
                            'color_code' => $request['color_code'],
                            'shift_notes' => $request['shift_notes'],
                            'repeat_shift' => 0,
                            'repeat_every' => 0,
                            'end_date' => $for_this_date,
                            'working_hours' => $required_minutes,
                            'is_saved' => '0',
                           'created_by' => $auth_id,
                           'customer_id' => $auth_id,
                           'workspace_id' => $workspace_id,
                           'site_id' => $request['site_id'] ?? null,
                           'project_id' => $request['project_id'] ?? null,
                        ]);
                        $shiftAlreadyCreated = true;
                    }
                    RosterAssign::insertGetId([
                        'assign_to' => $user_id,
                        'roster_template_id' =>  $insert_id,
                        'schedule_date' => $for_this_date,
                        'customer_id' => $auth_id,
                        'workspace_id' => $workspace_id,
                        'site_id' => $request['site_id'] ?? null,
                        'project_id' => $request['project_id'] ?? null,
                    ]);

                }
            }
                $authPersonalDetails = User::where('id', $auth_id)->first();
                $history_arr = [
                    'description' => "<a href='".url('/')."/customer-profile/".$auth_id."' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$authPersonalDetails->name} </a> created a bulk schedule at ".date('d-m-Y')." date",
                    'roster_template_id' => 0
                ];
                $this->externalstoreHistory($history_arr,$auth_id,$workspace_id);
                
            return $this->message("Bulk Schedule Created Successfully",200);
    }

    function getDatesBetween($start_date, $end_date)
    {
        $dates = [];

        $start = Carbon::parse($start_date);
        $end = Carbon::parse($end_date);

        while ($start->lte($end)) {
            $dates[] = $start->toDateString();
            $start->addDay();
        }

        return $dates;
    }

    public function storeHistory($arr)
    {
        $userTable = $this->getUserTable();
        if ($userTable === "customer") {
            $auth_id = Auth::user()->id;
            $workspace_id = Auth::user()->current_workspace_id;      
        }
        if ($userTable === "emp") {
            $auth_id = auth()->user()->customer_id;
            $workspace_id = auth()->user()->workspace_id;
        }
        RosterHistory::create([
            'roster_template_id' => $arr['roster_template_id'],
            'updated_by' => Auth::check() ? Auth::user()->id : 1,
            'description' => $arr['description'],
            'customer_id' =>  $auth_id,
            'workspace_id' =>  $workspace_id,
        ]);

    }
    public function externalstoreHistory($arr,$auth_id,$workspace_id)
    {
        RosterHistory::create([
            'roster_template_id' => $arr['roster_template_id'],
            'updated_by' => $auth_id,
            'description' => $arr['description'],
            'customer_id' =>  $auth_id,
            'workspace_id' =>  $workspace_id,
        ]);

    }
    private function isOverlap($start1, $end1, $start2, $end2)
    {
        // Normalize the intervals by checking if they cross midnight
        if ($start1 > $end1) {
            $end1 = date('H:i:s', strtotime($end1) + 86400); // Add 24 hours to end1
        }
        if ($start2 > $end2) {
            $end2 = date('H:i:s', strtotime($end2) + 86400); // Add 24 hours to end2
        }
        return $start1 < $end2 && $start2 < $end1;
    }

    function getShortDayNames($days) {
        $shortDays = array();
    
        foreach ($days as $day) {
            switch($day) {
                case "Monday":
                    $shortDays[] = "Mon";
                    break;
                case "Tuesday":
                    $shortDays[] = "Tue";
                    break;
                case "Wednesday":
                    $shortDays[] = "Wed";
                    break;
                case "Thursday":
                    $shortDays[] = "Thu";
                    break;
                case "Friday":
                    $shortDays[] = "Fri";
                    break;
                case "Saturday":
                    $shortDays[] = "Sat";
                    break;
                case "Sunday":
                    $shortDays[] = "Sun";
                    break;
                default:
                    $shortDays[] = "Invalid day";
                    break;
            }
        }
    
        return $shortDays;
    }





}