<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use App\Models\Fund;
use App\Models\Role;
use App\Models\Tier;
use App\Models\User;
use App\Models\EmpTeam;
use App\Models\EmpType;
use App\Models\EmpAccess;
use App\Models\EmpPermit;
use App\Models\FundsMeta;
use App\General\MetaClass;
use App\Models\EmpDocuments;
use App\Models\RosterAssign;
use Illuminate\Http\Request;
use App\Models\EmpWorkerType;
use App\Models\RosterHistory;
use App\Models\EmpTeamsMember;
use Illuminate\Validation\Rule;
use App\Models\RequiredDocument;
use App\Models\EmpCompanyDetails;
use App\Models\EmpPersonalDetails;
use Illuminate\Support\Facades\DB;
use App\Models\PorfileSubmittedLog;
use App\Traits\RosterTemplateTrait;
use App\Models\EmpEmergencyContacts;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\EmpTeamController;
use App\Http\Controllers\Traits\EmailTrait;
use App\Models\Plan;
use Illuminate\Support\Facades\Log;

class EmployeeOnboardingController extends Controller
{
    use RosterTemplateTrait, EmailTrait;

    /**
     * Send login credentials to employee
     * 
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendCredentials(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|exists:emp_company_details,id',
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first(), 422);
        }
        $id = $request->id;
        $user = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->first();
        if (!$user) {
            return $this->error('Account with the entered email does not exist.', 404);
        }
        try {
            // Generate a 6-digit password
            $digits = 8;
            $password = rand(pow(10, $digits - 1), pow(10, $digits) - 1);
            // Update the password in the database
            EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->update([
                'password' => Hash::make($password)
            ]);
            $empPersonalDetails = EmpPersonalDetails::where('emp_id', $id)->first();
            // Get the login URL
            $email = $user->employee_email;

            $emailName = strstr($email, '@', true);

            $nameParts = explode('.', $emailName);

            $firstName = $nameParts[0] ?? '';
            $lastName = $nameParts[1] ?? '';

            $fullName = $firstName . ' ' . $lastName;

            $loginUrl = env('FRONTEND_URL');
            // Send the email
            $emailParams = [
                'to' => $user->employee_email,
                'subject' => 'Your Login Credentials - ' . env('APP_NAME'),
                'msg' => view('Emails.employee-credentials', [
                    'subject' => 'Your Login Credentials',
                'name' => $empPersonalDetails?->first_name 
                    ? $empPersonalDetails->first_name . ' ' . $empPersonalDetails->middle_name . ' ' . $empPersonalDetails->last_name 
                    : $fullName,
                    'email' => $user->employee_email,
                    'password' => $password,
                    'login_url' => $loginUrl ?? null
                ])->render()
            ];
            $this->SendInstantEmail($emailParams);
            Log::info('Credential email sent to employee: ' . $user->employee_email);
            return $this->message('Email has been sent. Please check your email.');
        } catch (\Exception $e) {
            Log::error('Error sending credential email: ' . $e->getMessage());
            return $this->error('An error occurred while sending the email.', 500);
        }
    }

    public function sendInvite($id)
    {
        $user = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->exists();

        if ($user) {

            $user_details = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->first();
            $digits = 6;
            $password =  rand(pow(10, $digits - 1), pow(10, $digits) - 1);
            EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->update([
                'password' => Hash::make($password)
            ]);


            $params = [
                'subject' => 'User Invitation | ' . env("APP_NAME"),
                'to' => $user_details->employee_email,
                'blade' => view('Emails/invite', ['email' => $user_details->employee_email, 'password' => $password, 'subject' => 'User Invitation'])->render()
            ];


            $emailSent = $this->SendInstantEmail($params);

            if ($emailSent) {
                return 'Email has been sent, Please check your Email.';
            } else {
                return 'SMTP is not Working, Try Later!';
            }
        } else {
            return 'Account with the entered email does not exsit.';
        }
    }

    public function sendRejectedProfile($id)
    {
        $user = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->exists();

        if ($user) {

            $user_details = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->first();

            $params = [
                'subject' => 'Your Profile Rejected | ' . env("APP_NAME"),
                'to' => $user_details->employee_email,
                'blade' => view('Emails/profile_rejected', ['email' => $user_details->employee_email, 'subject' => 'Your Profile Rejected'])->render()
            ];






            $emailSent = $this->SendInstantEmail($params);

            if ($emailSent) {
                return 'Email has been sent, Please check your Email.';
            } else {
                return 'SMTP is not Working, Try Later!';
            }
        } else {
            return 'Account with the entered email does not exsit.';
        }
    }

    public function sendOnCompeleteProfile($id)
    {
        $user = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->exists();

        if ($user) {

            $user_details = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->first();


            if ($user_details->invited == 1) {

                $params = [
                    'subject' => 'Your Profile Compeleted And Approved | ' . env("APP_NAME"),
                    'to' => $user_details->employee_email,
                    'blade' => view('Emails/profile_compeleted_without_password', ['email' => $user_details->employee_email, 'subject' => 'Your Profile Compeleted And Approved'])->render()
                ];
            } else {
                $digits = 6;
                $password =  rand(pow(10, $digits - 1), pow(10, $digits) - 1);
                EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $id)->update([
                    'password' => Hash::make($password)
                ]);

                $params = [
                    'subject' => 'Your Profile Compeleted And Approved | ' . env("APP_NAME"),
                    'to' => $user_details->employee_email,
                    'blade' => view('Emails/profile_compeleted_with_password', ['email' => $user_details->employee_email, 'password' => $password, 'subject' => 'Your Profile Compeleted And Approved'])->render()
                ];
            }




            if ($user_details->credentials == 1) {

                $emailSent = $this->SendInstantEmail($params);

                if ($emailSent) {
                    return 'Email has been sent, Please check your Email.';
                } else {
                    return 'SMTP is not Working, Try Later!';
                }
            } else {
                return '';
            }
        } else {
            return 'Account with the entered email does not exsit.';
        }
    }

    public function empCompanyDetailsStore(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required',
            'employee_email' => ['required', 'email', Rule::unique('emp_company_details', 'employee_email')->ignore($request->emp_id, 'id'), Rule::unique('users', 'email')->ignore($request->emp_id, 'id'),],
            'employment_type'  => 'required',
            'access_role'  => 'required',
            'tier_id'  => 'required',
            'employee_teams'  => 'nullable',
            'work_permit_type'  => 'required',
            'tax_file_no'  => 'nullable|min:9',
            'employment_start_date'  => 'required|date',
            'employment_end_date'  => 'nullable|date|after_or_equal:employment_start_date',
            'attendance_effective_from'  => 'nullable|date', //after_or_equal:today
            'invited' => 'required|boolean',
            'credentials' => 'required',
            'status' => 'required',
            'employee_payroll_or_external_id' => 'nullable',
        ], [
            'emp_id.required' => 'Employee ID is required.',
            'employee_email.required' => 'Employee email is required.',
            'employee_email.email'  => 'Employee email must be a valid email address',
            'employee_email.unique'  => 'This email is already associated with another employee.',
            'employment_type.required'  => 'Employment type is required.',
            'access_role.required'  => 'Access role is required.',
            'tier_id.required' => 'Tier Package is required.',
            'work_permit_type.required'  => 'Work permit type is required.',
            'tax_file_no.required'  => 'Tax file number is required.',
            'employment_start_date.required'  => 'Employment start date is required.',
            'employment_start_date.date' => 'Invalid date format for employment start date.',
            'employment_end_date.date' => 'Invalid date format for employment end date.',
            'employment_end_date.after_or_equal' => 'Employment end date must be after or equal to the start date.',
            'attendance_effective_from.required'  => 'Attendance effective from date is required.',
            'attendance_effective_from.date' => 'Invalid date format for attendance effective from date.',
            'invited.required' => 'Invited field is required.',
            'invited.boolean' => 'Invited field must be a boolean.',
            'credentials.required' => 'Credentials are required.',
            'status.required' => 'Status is required.',
            'employee_payroll_or_external_id.required' => 'Employee Payroll / External ID is required.',
        ]);

        $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();
        }

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {


            $validatedData =  $validator->validated();
            unset($validatedData['employee_payroll_or_external_id']);


            $emp_id = $validatedData['emp_id'];
            $emp_exit =  EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $emp_id)->count();
            unset($validatedData['emp_id']);


            $employee_teams = $validatedData['employee_teams'];
            unset($validatedData['employee_teams']);


            if ($emp_exit == 0) {
                // Plan limit check only for NEW employees (CREATE operation)
                $user = User::where('id', $auth_id)->first();
                $plan = Plan::where('id', $user->active_plan_id)->first();
                $emp = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('customer_id', $auth_id)
                    ->where('workspace_id', $workspace_id)
                    ->count();

                if ($emp >= $plan->number_of_user) {
                    return $this->error('Your subscription is limited to ' . $plan->number_of_user . ' employees. You have exceeded your limit. Please update your plan.', 422);
                }
                $user = auth()->user();
                $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['customer_id'] = $auth_id;
                $validatedData['workspace_id'] = $workspace_id;
                $validatedData['created_by']   =  $user->id;
                $validatedData['approved'] = '1';
                $insertGetId =  EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->insertGetId($validatedData);

                // Check if employee is being invited
                $isInvited = isset($validatedData['invited']) && $validatedData['invited'] == 1;
                $msg = $isInvited ? 'Invite employee details saved successfully!' : 'Employee Company Details Saved Successfully';

                $emp_id = $insertGetId;
                // if($validatedData['invited'] == 1 && $validatedData['credentials'] == 1)
                // {
                //     $this->sendInvite($emp_id);
                // }
                EmpAccess::create([
                    'emp_id' => $emp_id,
                    'web_app' => 0,
                    'mobile_app' => 1,
                    'attendance' => 0,
                    'timesheet_reminders' => 0,
                    'email' => 0,
                    'timesheet' => 0,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);

                // Send invitation email ONLY on CREATE if invited=1 and credentials=1
                if (isset($validatedData['invited']) && $validatedData['invited'] == 1 && isset($validatedData['credentials']) && $validatedData['credentials'] == 1) {
                    try {
                        // Get employee details
                        $employee = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->find($emp_id);

                        // Generate temporary password
                        $digits = 6;
                        $password = rand(pow(10, $digits - 1), pow(10, $digits) - 1);

                        // Update the password in the database
                        EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $emp_id)->update([
                            'password' => Hash::make($password)
                        ]);
                        // Get the login URL
                        $loginUrl = env('FRONTEND_URL');
                        // Send the invitation email
                        $emailParams = [
                            'to' => $employee->employee_email,
                            'subject' => 'Welcome to ' . env('APP_NAME') . ' - Your Account Invitation',
                            'msg' => view('Emails.employee-invitation', [
                                'subject' => 'Your Account Invitation',
                                'email' => $employee->employee_email,
                                'password' => $password,
                                'login_url' => $loginUrl
                            ])->render()
                        ];

                        $this->SendInstantEmail($emailParams);

                        // Add success message about email
                        $msg .= ' and invitation email sent to ' . $employee->employee_email;

                        // Log the success
                        Log::info('Invitation email sent to new employee: ' . $employee->employee_email);
                    } catch (\Exception $e) {
                        // Log the error but don't stop the process
                        Log::error('Error sending invitation email to new employee: ' . $e->getMessage());
                    }
                }
            } else {
                // unset($validatedData['employee_email']);
                unset($validatedData['status']);
                unset($validatedData['credentials']);
                unset($validatedData['invited']);
                $validatedData['user_type'] = '0';
                $validatedData['approved'] = '1';
                EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $emp_id)->update($validatedData);

                // Check if employee is being updated
                $msg = 'Employee Details Updated Successfully';
            }


            $meta_ = $request->only([
                'employee_payroll_or_external_id',
            ]);


            $MetaArray = [];

            foreach ($meta_ as $option => $value) {
                if ($value !== null) {
                    $MetaArray[] = [
                        'emp_id' => $emp_id,
                        'option' => $option,
                        'value' => $value,
                    ];
                    DB::table('user_meta')->where('emp_id', $emp_id)->where('option', $option)->delete();
                }
            }


            DB::table('user_meta')->insert($MetaArray);



            EmpTeamsMember::where([
                'emp_id' => $request->emp_id,
            ])->delete();

            $EmpTeamController = new EmpTeamController();

            $employee_teams = explode(",", $employee_teams);

            foreach ($employee_teams as $employee_team) {
                $request->team_id = $employee_team;
                $request->emp_id = $emp_id;
                $request->applied = '0';
                $EmpTeamController->addRemoveTeamMember($request);
            }

            $data['emp_id'] =  $emp_id;

            return $this->success($data, $msg);
        }
    }

    public function empCompanyDetailsEdit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        }
        $user = Auth::user();

        $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();
        }
        // Extract customer_id and workspace_id from the user
        $customerId = $auth_id;
        $workspaceId = $workspace_id; // Adjust the attribute name as per your User model

        // Validate the request data
        $validatedData = $validator->validated();

        // Ensure emp_id belongs to the authenticated user's customer and workspace
        $empCompanyDetails = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->first();
        if ($userTable == "customer" && ($empCompanyDetails->workspace_id != auth()->user()->current_workspace_id || $empCompanyDetails->customer_id != auth()->user()->id)) {
            return $this->message('You do not have access to this Employee Company Details', 403);
        }

        if ($userTable == "emp" && ($empCompanyDetails->customer_id != auth()->user()->customer_id || $empCompanyDetails->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this Employee Company Details', 403);
        }
        if ($empCompanyDetails) {
            unset($empCompanyDetails['password']);
        }

        $data['emp_company_details'] = $empCompanyDetails;

        // Fetch Employee Permits scoped to customer and workspace
        $empPermits = EmpPermit::where('del', '0')
            ->where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->select('id', 'title')
            ->get();

        $data['emp_permits'] = $empPermits;

        // Fetch Employee Types scoped to customer and workspace
        $empTypes = EmpType::where('del', '0')
            ->where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->select('id', 'title')
            ->get();

        $data['emp_types'] = $empTypes;

        // Fetch Package Tiers scoped to customer and workspace
        $pkgTiers = Tier::where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->select('id', 'title')
            ->get();

        $data['pkg_tiers'] = $pkgTiers;

        // Fetch Roles (global - available to all customers)
        $roles = Role::where('del', '0')
            ->get();

        $data['emp_roles'] = $roles;

        // Fetch Employee Teams scoped to customer and workspace
        $empTeams = EmpTeam::where('del', '0')
            ->where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->get();

        $data['emp_teams'] = $empTeams;

        // Fetch Employee Team Members scoped to customer and workspace
        $empTeamMembers = EmpTeamsMember::where('emp_id', $validatedData['emp_id'])->get();

        $teamIds = $empTeamMembers->pluck('team_id')->toArray();
        $data['employee_teams'] = implode(',', $teamIds);

        // Fetch User Meta scoped to customer and workspace
        $userMeta = DB::table('user_meta')
            ->where('emp_id', $validatedData['emp_id'])->get();

        $employeePayrollOrExternalId = MetaClass::getOptionValue('employee_payroll_or_external_id', $userMeta);
        $data['meta']['employee_payroll_or_external_id'] = $employeePayrollOrExternalId;

        return $this->success($data, 'Employee Company Details GET Successfully');
    }

    public function empPersonalDetailsStore(Request $request)
    {
        // dd($request->all());

        $validator = Validator::make($request->all(), [
            'emp_id' => 'required',
            'first_name' => 'required',
            'middle_name' => 'nullable',
            'last_name' => 'required',
            'mobile' => 'required|numeric',
            'streat_address' => 'required',
            'suburb' => 'required|regex:/^[a-zA-Z\s]*$/',
            'state' => 'required|regex:/^[a-zA-Z\s]*$/',
            'postcode' => 'required',
            'date_of_birth' => 'required|date|before_or_equal:' . Carbon::now()->subYears(14)->format('Y-m-d'),
            'blood_group' => 'nullable',
            'superannuations_funds' => 'nullable',
            'bank_name' => 'nullable',
            'account_holder_name' => 'nullable',
            'ibn_number' => 'nullable',
            'account_number' => 'nullable',


        ], [
            'emp_id.required' => 'Employee ID is required.',
            'first_name.required' => 'First name is required.',
            'first_name.alpha' => 'First name must contain only alphabetic characters.',
            'last_name.required' => 'Last name is required.',
            'last_name.alpha' => 'Last name must contain only alphabetic characters.',
            'middle_name.alpha' => 'Middle name must contain only alphabetic characters.',
            'mobile.required' => 'Mobile number is required.',
            'mobile.numeric' => 'Mobile must be numeric.',
            'streat_address.required' => 'Street address is required.',
            'suburb.required' => 'Suburb is required.',
            'suburb.regex' => 'Suburb must contain only alphabetic characters.',
            'state.required' => 'State is required.',
            'state.regex' => 'State must contain only alphabetic characters.',
            'postcode.required' => 'Postcode is required.',
            'postcode.numeric' => 'Postcode is must be numeric.',
            'date_of_birth.required' => 'Date of birth is required.',
            'date_of_birth.date' => 'Invalid date format for date of birth.',
            'date_of_birth.before' => 'You must be at least 14 years old to register.',
        ]);
        if ($request->hasFile('image')) {
            $rules['image'] = 'image|mimes:jpeg,png,jpg,gif|max:2048'; // example rules for images
        }

        if ($validator->fails()) {

            $error = $validator->errors()->first();

            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();



            $emp_id = $validatedData['emp_id'];

            //  'image' => 'nullable|mimes:jpeg,png,jpg,gif,svg'


            $emp_exit =  EmpPersonalDetails::where('emp_id', $emp_id)->count();
            if (is_string($validatedData['superannuations_funds'])) {
                $superannuations_funds = json_decode($validatedData['superannuations_funds'], true);
            } else {
                $superannuations_funds = $validatedData['superannuations_funds'];
            }

            // Debug: Log the superannuation funds data
            Log::info('Superannuation funds data received: ', ['data' => $superannuations_funds]);

            unset($validatedData['superannuations_funds']);

            if ($request->hasFile('image')) {

                $image = $request->file('image');
                $imageName = time() . '.' . $image->getClientOriginalExtension();
                $image->move(public_path('upload/images'), $imageName);
                $validatedData['image'] = 'upload/images/' . $imageName;
            }


            if ($emp_exit == 0) {
                $validatedData['created_by']   =  Auth::user()->id;
                EmpPersonalDetails::insertGetId($validatedData);
                $msg = 'Employee Personal Details Saved Successfully';
            } else {
                unset($validatedData['emp_id']);
                EmpPersonalDetails::where('emp_id', $emp_id)->update($validatedData);
                $msg = 'Employee Personal Details Updated Successfully';
            }

            // Update funds_meta table only
            if (!empty($superannuations_funds) && is_array($superannuations_funds)) {
                try {
                    // First, delete existing funds_meta records for this employee
                    FundsMeta::where('emp_id', $emp_id)->delete();

                    $fund_meta_array = [];

                    foreach ($superannuations_funds as $fund) {
                        if (isset($fund['id']) && isset($fund['usi_number'])) {
                            // Prepare data for funds_meta table
                            $fund_meta_array[] = [
                                'emp_id' => $emp_id,
                                'fund_id' => $fund['id'],
                                'usi_number' => $fund['usi_number'],
                                'member_number' => $fund['member_number'] ?? null,
                                'created_at' => now(),
                                'updated_at' => now()
                            ];
                        }
                    }

                    // Insert new records into funds_meta table
                    if (!empty($fund_meta_array)) {
                        FundsMeta::insert($fund_meta_array);
                        Log::info('FundsMeta records created successfully: ', [
                            'emp_id' => $emp_id,
                            'count' => count($fund_meta_array)
                        ]);
                    }
                } catch (\Exception $e) {
                    Log::error('Error updating superannuation funds: ' . $e->getMessage());
                    return $this->error('Error updating superannuation funds: ' . $e->getMessage(), 500);
                }
            }

            $meta_ = $request->only([
                'account_holder_name',
                'account_number',
                'bank_name',
                'ibn_number'
            ]);

            // Debug: Log the bank account data
            Log::info('Bank account data received: ', ['data' => $meta_]);

            $MetaArray = [];

            foreach ($meta_ as $option => $value) {
                if ($value !== null && $value !== '') {
                    $MetaArray[] = [
                        'emp_id' => $emp_id,
                        'option' => $option,
                        'value' => $value,
                        'created_at' => now(),
                        'updated_at' => now()
                    ];
                    DB::table('user_meta')->where('emp_id', $emp_id)->where('option', $option)->delete();
                }
            }

            // Insert bank account data if we have any
            if (!empty($MetaArray)) {
                try {
                    DB::table('user_meta')->insert($MetaArray);
                } catch (\Exception $e) {
                    Log::error('Error saving bank account data: ' . $e->getMessage());
                    return $this->error('Error saving bank account data: ' . $e->getMessage(), 500);
                }
            }



            $data['emp_id'] =  $emp_id;
            return $this->success($data, $msg);
        }
    }

    public function empPersonalDetailsEdit(Request $request)
    {

        $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();
        }
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();


            $emp_personal_details =  EmpPersonalDetails::where('emp_id', $validatedData['emp_id'])->first();

            $funds = Fund::where('customer_id', $auth_id)
                ->where('workspace_id', $workspace_id)
                ->where('del', '0')
                ->get();
            $funds_meta = FundsMeta::where('emp_id', $validatedData['emp_id'])->with('fund')->get();

            $c = 0;

            foreach ($funds as $f) {
                $funds[$c]['usi_number'] = $funds_meta->where('fund_id', $f->id)->first()->usi_number ?? null;
                $funds[$c]['member_number'] = $funds_meta->where('fund_id', $f->id)->first()->member_number ?? null;

                $c++;
            }


            if ($emp_personal_details) {
                $emp_personal_details->image = url($emp_personal_details->image);
            }
            $data['emp_personal_details'] = $emp_personal_details;
            $data['funds'] = $funds;
            $data['funds_meta'] = $funds_meta;

            $user_meta =  DB::table('user_meta')->where('emp_id', $validatedData['emp_id'])->get();

            $account_holder_name = MetaClass::getOptionValue('account_holder_name', $user_meta);
            $account_number = MetaClass::getOptionValue('account_number', $user_meta);
            $ibn_number = MetaClass::getOptionValue('ibn_number', $user_meta);
            $bank_name = MetaClass::getOptionValue('bank_name', $user_meta);

            $data['meta']['account_holder_name'] = $account_holder_name;
            $data['meta']['account_number'] = $account_number;
            $data['meta']['ibn_number'] = $ibn_number;
            $data['meta']['bank_name'] = $bank_name;

            // If user is an employee, get induction document counts and status
            if ($userTable === "emp") {
                $inductionDocs = $this->getEmployeeInductionDocuments($validatedData['emp_id']);
                
                if ($inductionDocs !== null) {
                    $totalDocuments = $inductionDocs['total_documents'] ?? 0;
                    $signedDocuments = $inductionDocs['total_signed'] ?? 0;
                    $pendingDocuments = $inductionDocs['total_not_signed'] ?? 0;
                    $totalValidSignatures = $inductionDocs['total_valid_signatures'] ?? 0;
                    $totalInvalidSignatures = $inductionDocs['total_invalid_signatures'] ?? 0;
                    
                    // Flags
                    $allDocumentsSigned = $inductionDocs['all_documents_signed'] ?? false;
                    $allSignaturesValid = $inductionDocs['all_signatures_valid'] ?? false;
                    $hasInvalidSignatures = $inductionDocs['has_invalid_signatures'] ?? false;
                    
                    $data['induction_documents'] = [
                        'total_documents' => $totalDocuments,
                        'signed_documents' => $signedDocuments,
                        'pending_documents' => $pendingDocuments,
                        'total_valid_signatures' => $totalValidSignatures,
                        'total_invalid_signatures' => $totalInvalidSignatures,
                        'all_documents_signed' => $allDocumentsSigned,
                        'all_signatures_valid' => $allSignaturesValid,
                        'has_invalid_signatures' => $hasInvalidSignatures,
                    ];
                } else {
                    // If no documents found or method returns null, set defaults
                    $data['induction_documents'] = [
                        'total_documents' => 0,
                        'signed_documents' => 0,
                        'pending_documents' => 0,
                        'total_valid_signatures' => 0,
                        'total_invalid_signatures' => 0,
                        'all_documents_signed' => true, // No documents means nothing pending
                        'all_signatures_valid' => true, // No signatures means all are valid
                        'has_invalid_signatures' => false,
                    ];
                }
            }

            return $this->success($data, 'Employee Personal Detail Get successfully');
        }
    }


    public function empDocumentsStore(Request $request)
    {
        $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();
        }
        // Get employee details to determine user type
        $employee = EmpCompanyDetails::withoutGlobalScopes()->where('id', $request->emp_id)->first();

        if (!$employee) {
            return $this->error('Employee not found', 404);
        }

        $isInternal = ($employee->user_type === '0' || $employee->user_type === 0); // 0 = Internal, 1 = External
        $isExternal = ($employee->user_type === '1' || $employee->user_type === 1); // 1 = External

        $query = RequiredDocument::with('requiredDocumentField')
            ->where('del', '0')
            ->where('customer_id', $auth_id)
            ->where('workspace_id', $workspace_id);

        if ($isInternal) {
            // For internal employees, return documents with for_who = 'internal' or 'both'
            $query->where(function ($q) {
                $q->where('for_who', 'internal')
                    ->orWhere('for_who', 'both');
            });
        } elseif ($isExternal) {
            // For external employees, return documents with for_who = 'external' or 'both'
            $query->where(function ($q) {
                $q->where('for_who', 'external')
                    ->orWhere('for_who', 'both');
            });
        } else {
            // If no conditions match (unknown user_type), return only 'both' documents
            $query->where('for_who', 'both');
        }

        $required_documents = $query->get();

        $count = EmpDocuments::where('emp_id', $request->emp_id)->count();

        if ($count == 0) {
            $msg = "Employee Documents Saved Successfully";
        } else {
            $msg = "Employee Documents Updated Successfully";
        }

        $i = 0;

        foreach ($required_documents as $required_document) {
            foreach ($required_document->requiredDocumentField as $required_document_field) {
                // Only validate if status is active (status == '1')
                if ($required_document_field->status == '1') {
                    // Check if field is required (field_required == "1")
                    if (
                        $required_document_field->field_required == "1" &&
                        !$request->filled('document_array.' . $required_document_field->doc_id . '.' . $required_document_field->id) &&
                        !$request->hasFile('document_array.' . $required_document_field->doc_id . '.' . $required_document_field->id)
                    ) {
                        // If no value or file is submitted
                        if ($count == 0) {
                            return response()->json([
                                'message' => $required_document_field->field_name . ' field is required'
                            ], 422);
                        } else {
                            if ($required_document_field->field_type != 'image') {
                                return response()->json([
                                    'message' => $required_document_field->field_name . ' field is required'
                                ], 422);
                            }
                        }
                    }

                    // Validate file if present
                    if (
                        ($required_document_field->field_type == "image" || $required_document_field->field_type == "file") &&
                        $request->hasFile('document_array.' . $required_document_field->doc_id . '.' . $required_document_field->id)
                    ) {
                        $allowedExtensions = ['jpg', 'jpeg', 'png', 'docx', 'pdf'];
                        $document_file = $request->file('document_array.' . $required_document_field->doc_id . '.' . $required_document_field->id);
                        $extension = $document_file->getClientOriginalExtension();
                        $mimeType = $document_file->getMimeType();

                        // Validate extension and MIME type
                        if (
                            !in_array($extension, $allowedExtensions) ||
                            !in_array($mimeType, [
                                'image/jpeg',
                                'image/png',
                                'application/pdf',
                                'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
                            ])
                        ) {
                            return response()->json([
                                'message' => 'The ' . $required_document_field->field_name . ' file must be a file of type: jpg, jpeg, png, docx, pdf.'
                            ], 422);
                        }
                    }
                }
            }
            $i++;
        }

        foreach ($required_documents as $required_document) {
            foreach ($required_document->requiredDocumentField as $required_document_field) {

                $EmpDocumentsData = [
                    'emp_id' => $request->emp_id,
                    'required_document' => $required_document_field->doc_id,
                    'required_document_field' => $required_document_field->id,
                ];

                // Only process if status is active (status == '1')
                if ($required_document_field->status == '1') {
                    if (
                        ($required_document_field->field_type == "image" || $required_document_field->field_type == "file") &&
                        $request->hasFile('document_array.' . $required_document_field->doc_id . '.' . $required_document_field->id)
                    ) {
                        $document_file = $request->file('document_array.' . $required_document_field->doc_id . '.' . $required_document_field->id);
                        $documentName = $i . time() . '.' . $document_file->getClientOriginalExtension();
                        $document_file->move(public_path('upload/documents'), $documentName);

                        $EmpDocumentsData['value'] = 'upload/documents/' . $documentName;

                        // Delete and Insert new record
                        EmpDocuments::where([
                            'emp_id' => $request->emp_id,
                            'required_document' => $required_document_field->doc_id,
                            'required_document_field' => $required_document_field->id
                        ])->delete();

                        EmpDocuments::insert($EmpDocumentsData);
                    }

                    if ($required_document_field->field_type != "image" && $required_document_field->field_type != "file") {
                        if (isset($request->document_array[$required_document_field->doc_id][$required_document_field->id])) {
                            $EmpDocumentsData['value'] = $request->document_array[$required_document_field->doc_id][$required_document_field->id];

                            // Delete and Insert new record
                            EmpDocuments::where([
                                'emp_id' => $request->emp_id,
                                'required_document' => $required_document_field->doc_id,
                                'required_document_field' => $required_document_field->id
                            ])->delete();

                            EmpDocuments::insert($EmpDocumentsData);
                        }
                    }
                }
            }

            $i++;
        }

        $data['emp_id'] = $request->emp_id;

        return $this->success($data, $msg);
    }



    public function empDocumentsEdit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        }

        $validatedData = $validator->validated();
        $emp_id = $validatedData['emp_id'];

        // Get employee details
        $employee = EmpCompanyDetails::find($emp_id);
        if (!$employee) {
            return $this->error('Employee not found', 404);
        }

        // Check access control based on user type
        $userTable = $this->getUserTable();
        if ($userTable === "customer") {
            if ($employee->customer_id != auth()->id() || $employee->workspace_id != auth()->user()->current_workspace_id) {
                return $this->error('You do not have access to this employee', 403);
            }
        } elseif ($userTable === "emp") {
            if ($employee->customer_id != auth()->user()->customer_id || $employee->workspace_id != auth()->user()->workspace_id) {
                return $this->error('You do not have access to this employee', 403);
            }
        }

        // Get employee documents
        $emp_documents = EmpDocuments::where('emp_id', $emp_id)->where('del', '0')->get();

        // Build query for required documents
        $query = RequiredDocument::query()->with('requiredDocumentField');

        if ($userTable === "customer") {
            $query->where('del', '0')
                ->where('customer_id', auth()->id())
                ->where('workspace_id', auth()->user()->current_workspace_id);
        }

        if ($userTable === "emp") {
            $query->where('del', '0')
                ->where('customer_id', auth()->user()->customer_id)
                ->where('workspace_id', auth()->user()->workspace_id);
        }

        // Filter by employee type (internal/external)
        $isInternal = ($employee->user_type == '0'); // 0 = Internal, 1 = External

        if ($isInternal) {
            // For internal employees, return documents with for_who = 'internal' or 'both'
            $query->where(function ($q) {
                $q->where('for_who', 'internal')
                    ->orWhere('for_who', 'both');
            });
        } else {
            // For external employees, return documents with for_who = 'external' or 'both'
            $query->where(function ($q) {
                $q->where('for_who', 'external')
                    ->orWhere('for_who', 'both');
            });
        }

        $required_documents = $query->get();

        $data = [
            'required_documents' => $required_documents,
            'emp_documents' => $emp_documents,
            'base_url' => url('/')
        ];

        return $this->success($data, 'Employee Documents GET Successfully');
    }

    public function empDocumentsDelete(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'id' => 'required',
        ], [
            'id.required' => 'ID is required.'
        ]);



        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();
            EmpDocuments::where('id', $validatedData['id'])->update(['del' => '1']);
            return $this->message('Employee Document or Certification Deleted Successfully');
        }
    }

    public function empDocumentsCount(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'emp_id' => 'required',
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();

            $count =  EmpDocuments::where(['emp_id' => $validatedData['emp_id'], 'del' => '0'])->count();

            if ($count) {
                $data['emp_id'] = $validatedData['emp_id'];
                return $this->success($data, '');
            } else {
                return $this->message('Please Upload At Least One Document or Certification First');
            }
        }
    }

    public function empEmergencyContactsStoreMulti(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'contacts' => 'required|array',
            'contacts.*.emp_id' => 'required',
            'contacts.*.name' => 'required',
            'contacts.*.relation' => 'required',
            'contacts.*.phone' => 'required',
            'contacts.*.email' => 'nullable|email',
            'contacts.*.address' => 'nullable'
        ], [
            'contacts.required' => 'Emergency contacts data is required.',
            'contacts.array' => 'Emergency contacts must be an array.',
            'contacts.*.emp_id.required' => 'Employee ID is required for each contact.',
            'contacts.*.name.required' => 'Name is required for each contact.',
            'contacts.*.name.regex' => 'Name must contain only alphabetic characters.',
            'contacts.*.email.email' => 'Invalid email format.',
            'contacts.*.phone.required' => 'Phone number is required for each contact.',
            'contacts.*.relation.required' => 'Relation is required for each contact.'
        ]);

        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        }

        $contacts = $request->contacts;
        $empId = $contacts[0]['emp_id']; // Get employee ID from first contact

        // Use database transaction to ensure data integrity
        DB::beginTransaction();

        // Delete all existing emergency contacts for this employee
        $deletedCount = EmpEmergencyContacts::where('emp_id', $empId)->delete();
        \Log::info("Deleted {$deletedCount} existing emergency contacts for employee {$empId}");

        $successCount = 0;
        $errorCount = 0;

        // Insert new emergency contacts
        foreach ($contacts as $contact) {
            try {
                $contact['created_by'] = Auth::user()->id;
                $contact['created_at'] = now();
                $contact['updated_at'] = now();

                EmpEmergencyContacts::insert($contact);
                $successCount++;
            } catch (\Exception $e) {
                $errorCount++;
                \Log::error('Error storing emergency contact: ' . $e->getMessage(), [
                    'contact' => $contact,
                    'error' => $e->getMessage()
                ]);
                // Don't throw exception here, continue with other contacts
            }
        }

        if ($successCount > 0) {
            DB::commit(); // Commit the transaction

            $message = "Emergency Contacts Saved Successfully";
            if ($errorCount > 0) {
                $message .= " but {$errorCount} contact(s) failed to save";
            }

            $data = [
                'emp_id' => $empId,
                'deleted_count' => $deletedCount,
                'success_count' => $successCount,
                'error_count' => $errorCount
            ];
            if (EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $empId)->where('invited', '1')->where('compeleted', '!=', '1')->exists()) {
                EmpCompanyDetails::where('id', $empId)->update([
                    'compeleted' => '1'
                ]);
                $this->assignShift($empId);
            }
            return $this->success($data, $message);
        } else {
            DB::rollback(); // Rollback if no contacts were saved
            return $this->error('Failed to save any new emergency contacts', 500);
        }
    }

    public function empEmergencyContactsStore(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required',
            'emp_id' => 'required',
            'name' => 'required|regex:/^[a-zA-Z\s]*$/',
            'relation' => 'required',
            'phone' => 'required',
            'email' => 'nullable|email',
            'address' => 'nullable'
        ], [
            'id.required' => 'ID is required.',
            'emp_id.required' => 'Employee ID is required.',
            'name.required' => 'Name is required.',
            'name.regex' => 'Name must contain only alphabetic characters.',
            'email.email' => 'Invalid email format.',
            'phone.required' => 'Phone number is required.',
            'relation.required' => 'Relation is required.'
        ]);




        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();
            $id = $validatedData['id'];
            $emp_exit =  EmpEmergencyContacts::where('id', $id)->count();

            unset($validatedData['id']);


            if ($emp_exit == 0) {
                $validatedData['created_by']   =  Auth::user()->id;
                EmpEmergencyContacts::insertGetId($validatedData);
                $msg = 'Employee Emergency Contacts Saved Successfully';
            } else {

                EmpEmergencyContacts::where('id', $id)->update($validatedData);
                $msg = 'Employee Emergency Contacts Updated Successfully';
            }
            if (EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->where('invited', '1')->where('compeleted', '!=', '1')->exists()) {
                EmpCompanyDetails::where('id', $validatedData['emp_id'])->update([
                    'compeleted' => '1'
                ]);
                $this->assignShift($validatedData['emp_id']);
            }

            $data['emp_id'] =  $validatedData['emp_id'];

            return $this->success($data, $msg);
        }
    }

    public function empEmergencyContactslist(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();


            $emp_emergency_contacts =  EmpEmergencyContacts::where('emp_id', $validatedData['emp_id'])->where('del', '0')->get();

            $data['emp_emergency_contacts'] = $emp_emergency_contacts;

            return $this->success($data, 'Employee Emergency Contact GET Successfully');
        }
    }

    public function empEmergencyContactsEdit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required'
        ], [
            'id.required' => 'Emergency Contact ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();


            $emp_emergency_contacts =  EmpEmergencyContacts::where('id', $validatedData['id'])->where('del', '0')->get();

            $data['emp_emergency_contacts'] = $emp_emergency_contacts;

            return $this->success($data, 'Employee Emergency Contact GET Successfully');
        }
    }

    public function empEmergencyContactsDelete(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'id' => 'required',
        ], [
            'id.required' => 'ID is required.'
        ]);



        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();

            EmpEmergencyContacts::where('id', $validatedData['id'])->update(['del' => '1']);

            return $this->message('Employee Emergency Contact Deleted Successfully');
        }
    }

    public function empEmergencyContactsCount(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'emp_id' => 'required',
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();
            $count =  EmpEmergencyContacts::where(['emp_id' => $validatedData['emp_id'], 'del' => '0'])->count();

            if ($count) {
                $data['emp_id'] = $validatedData['emp_id'];

                $emp  = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->first();

                if ($emp->invited == 1) {
                    EmpCompanyDetails::where('id', $validatedData['emp_id'])->update([
                        'rejected' => '0',
                        'is_submitted' => '1'
                    ]);
                }
                return $this->success($data);
            } else {
                return $this->message('Please Upload At Least One Document or Certification First');
            }
        }
    }

    public function empAccessStore(Request $request)
    {
        try {
    
            $validator = Validator::make($request->all(), [
                'emp_id' => 'required',
                'web_app' => 'required',
                'mobile_app' => 'required',
                'attendance' => 'required',
                'timesheet_reminders' => 'required',
                'email' => 'required',
                'timesheet' => 'required'
            ], [
                'emp_id.required' => 'Employee ID is required.',
                'web_app.required' => 'Web app preference is required.',
                'mobile_app.required' => 'Mobile app preference is required.',
                'attendance.required' => 'Attendance preference is required.',
                'timesheet_reminders.required' => 'Timesheet reminders preference is required.',
                'email.required' => 'Email preference is required.',
                'timesheet.required' => 'Timesheet preference is required.'
            ]);
    
            if ($validator->fails()) {
                $error = $validator->errors()->first();
                return $this->error($error, 422);
            } else {
                $validatedData = $validator->validated();
                $check = EmpAccess::where('emp_id', $validatedData['emp_id'])->count();
                
                // Initialize $invitedStatus here before the conditional block
                $EmpCompanyDetails = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->first();
                if (!$EmpCompanyDetails) {
                    return $this->error('Employee company details not found', 404);
                }
                
                // Handle invited status with null safety
                $invitedStatus = $EmpCompanyDetails->invited ?? 0;
                
                // Delete existing records
                $deletedCount = EmpAccess::where('emp_id', $validatedData['emp_id'])->delete();
                // Insert new record
                
                $insertedId = EmpAccess::insertGetId($validatedData);
                if ($check == 0) {
                    $userTable = $this->getUserTable();
                    $auth_id = 0;
                    $workspace_id = 0;
                    $approved_status = 0;
                    $authPersonalDetails = null;
                    if ($userTable === "customer") {
                        $auth_id = Auth::user()->id;
                        $workspace_id = Auth::user()->current_workspace_id;
                        $approved_status = 0;
                        $authPersonalDetails = User::where('id', Auth::user()->id)->first();
                    }
                    if ($userTable === "emp") {
                        $auth_id = auth()->user()->customer_id;
                        $workspace_id = auth()->user()->workspace_id;
                        $approved_status = 1;
                        $authPersonalDetails = EmpPersonalDetails::where('emp_id', Auth::user()->id)->first();
                    }
                    
                    if ($invitedStatus == '1') {
                        $profileLogData = [
                            "emp_id" => $validatedData['emp_id'],
                            "approved_by" => Auth::user()->id,
                            "approved_status" => $approved_status,
                            "date" => date('Y-m-d')
                        ];
                        PorfileSubmittedLog::insert($profileLogData);
                        $updateData = [
                            'approved' => '1',
                            'compeleted' => '1',
                            'approved_by' => Auth::user()->id,
                            'approved_status' => $approved_status,
                            'approved_at' => date('Y-m-d'),
                            'is_submitted' => '0',
                            'invited' => '0'
                        ];
                        $updatedRows = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->update($updateData);
                    }
                    // Update company details (main update)
                    $mainUpdateData = [
                        'approved' => '1',
                        'approved_by' => Auth::user()->id,
                        'approved_status' => $approved_status,
                        'approved_at' => date('d-m-Y'),
                    ];
                    $mainUpdatedRows = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->update($mainUpdateData);
                    // Handle team members
                    $employee_teams = EmpTeamsMember::where([
                        'emp_id' => $validatedData['emp_id'],
                    ])->get();
                    $deletedTeamsCount = EmpTeamsMember::where([
                        'emp_id' => $validatedData['emp_id'],
                    ])->delete();
                    $EmpTeamController = new EmpTeamController();
                    foreach ($employee_teams as $employee_team) {
                        $request->team_id = $employee_team->team_id ?? null;
                        $request->emp_id = $employee_team->emp_id ?? null;
                        $request->applied = '1';
                        if ($request->team_id && $request->emp_id) {
                            $result = $EmpTeamController->addRemoveTeamMember($request);
                        }
                    }
                    $msg = 'Employee Access Saved Successfully';
                } else {
                    $msg = 'Employee Access Updated Successfully';
                }
                // Final company details update
                $data['emp_id'] = $validatedData['emp_id'];
                // Assign shift
                // $this->assignShift($data['emp_id'] , true);
                Log::info('Shift assigned successfully', ['emp_id' => $data['emp_id']]);
                               
                $finalUpdateData = [
                    'approved' => '1',
                ];
                if($EmpCompanyDetails->empPersonalDetails ?->first_name != null && $EmpCompanyDetails->empEmergencyContacts ?->count() > 0){
                    $finalUpdateData['compeleted'] = '1';
                }
                EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->update($finalUpdateData);
                return $this->success($data, $msg);
            }
        } catch (\Exception $e) {
            \Log::error('Fatal error in empAccessStore', [
                'error' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'request_data' => $request->all()
            ]);
    
            return $this->error('An error occurred while processing employee access'.$e->getMessage(), 500);
        }
    }

    public function empAccessEdit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();
            $emp_access =  EmpAccess::where('emp_id', $validatedData['emp_id'])->where('del', '0')->first();
            $data['emp_access'] = $emp_access;
            return $this->success($data, 'Employee Access Get Successfully');
        }
    }

    public function rejected(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'reason' => 'required',
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.',
            'reason.required' => 'Reason is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();


            PorfileSubmittedLog::insert([
                "emp_id" => $validatedData['emp_id'],
                "reason" => $validatedData['reason'],
                "rejected_by" => Auth::user()->id,
                "date" => date('Y-m-d'),
            ]);

            EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $validatedData['emp_id'])->update([
                'rejected' => '1',
                'is_submitted' => '0'
            ]);

            $this->sendRejectedProfile($validatedData['emp_id']);
            return $this->message('Profile Rejected successfully');
        }
    }

    public function profileSubmitHistory(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'emp_id' => 'required'
        ], [
            'emp_id.required' => 'Employee ID is required.'
        ]);

        if ($validator->fails()) {

            $error = $validator->errors()->first();
            return $this->error($error, 422);
        } else {

            $validatedData =  $validator->validated();


            $PorfileSubmittedLog =  PorfileSubmittedLog::where('emp_id', $validatedData['emp_id'])
                ->with('rejectedBy')
                ->with('approvedBy')
                ->get();

            $data['profile_submit_history'] = $PorfileSubmittedLog;
            return $this->success($data, 'Profile Submit History Get Successfully');
        }
    }

    public function assignShift($id , $emailCheck = null)
    {
        $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();
        }
        $roster_setting = DB::table('settings')->where('customer_id', $auth_id)->where('workspace_id', $workspace_id)->whereIn('option', [
            'roster_setting_title',
            'roster_setting_paid_break',
            'roster_setting_color_code',
            'roster_setting_start_time',
            'roster_setting_end_time',
            'roster_setting_description',
            'roster_setting_working_days',
            'roster_setting_working_hours',
            'roster_setting_number_of_days',
        ])->select('option', 'value')->get();
        // Convert the collection to an associative array
        $formatted_roster_setting = $roster_setting->pluck('value', 'option')->toArray();
        // dd($formatted_roster_setting);
        $days = [];
        $working_days = explode(',', $formatted_roster_setting['roster_setting_working_days']);
        foreach ($working_days as $day) {
            $days[] = config('constants.weekdays_name.' . $day);
        }
        $arr = [
            'start_date' => Carbon::today()->format('Y-m-d'),
            'end_date' =>  Carbon::today()->addDays($formatted_roster_setting['roster_setting_number_of_days'])->format('Y-m-d'),
            'start_time' => $formatted_roster_setting['roster_setting_start_time'],
            'end_time' => $formatted_roster_setting['roster_setting_end_time'],
            'color_code' => $formatted_roster_setting['roster_setting_color_code'],
            'break_minutes' => $formatted_roster_setting['roster_setting_paid_break'],
            'shift_notes' => $formatted_roster_setting['roster_setting_description'],
            'working_hours' => $formatted_roster_setting['roster_setting_working_hours'] ?? 8,
            'users_ids' => [$id],
            'working_days_hidden' => implode(',', $days)
        ];
        $this->bulkScheduleRoasterCreate($arr, $arr);

        // Send email notification with roster details if employee is invited
        $employeeDetails = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->find($id);
        if ($employeeDetails && $employeeDetails->invited == '1' && $employeeDetails->compeleted != '1') {
            $this->sendInternalEmployeeRosterEmail($id, $arr);
        }
        if ($emailCheck == true && $employeeDetails->invited == '0' && $employeeDetails->compeleted == '0') {
            \Log::info('test', $arr);
            $this->sendInternalEmployeeRosterEmail($id, $arr);
        }
        return 0;
    }

    public function storeHistory($arr)
    {
        RosterHistory::create([
            'roster_template_id' => $arr['roster_template_id'],
            'updated_by' => '1',
            'description' => $arr['description']
        ]);
    }

    /**
     * Send email notification when employee access is approved
     *
     * @param int $empId
     * @return void
     */
    protected function sendAccessApprovalEmail($empId)
    {
        try {
            $employee = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('id', $empId)->first();
            if (!$employee || !$employee->employee_email) {
                Log::warning('Unable to send access approval email: Invalid employee or missing email');
                return;
            }

            // Get employee personal details if available
            $personalDetails = EmpPersonalDetails::where('emp_id', $empId)->first();
            $employeeName = $personalDetails ?
                $personalDetails->first_name . ' ' . $personalDetails->last_name :
                'Employee';

            // Get access details to include in email
            $accessDetails = EmpAccess::where('emp_id', $empId)->first();

            // Get login URL
            $appUrl = config('app.url');
            $loginUrl = $appUrl . '/login';

            $emailParams = [
                'to' => $employee->employee_email,
                'subject' => 'Your Account Access Has Been Approved - ' . env('APP_NAME'),
                'msg' => view('Emails.access-approval', [
                    'subject' => 'Your Account Access Has Been Approved',
                    'name' => $employeeName,
                    'email' => $employee->employee_email,
                    'web_app' => $accessDetails->web_app ? 'Enabled' : 'Disabled',
                    'mobile_app' => $accessDetails->mobile_app ? 'Enabled' : 'Disabled',
                    'login_url' => $loginUrl ?? null
                ])->render()
            ];

            $this->SendInstantEmail($emailParams);
            Log::info('Access approval email sent to employee: ' . $employee->employee_email);
        } catch (\Exception $e) {
            Log::error('Error sending access approval email: ' . $e->getMessage());
            Log::error($e->getTraceAsString());
        }
    }

    /**
     * Send internal employee onboarding email with roster details
     * 
     * @param int $empId
     * @param array $rosterSettings
     * @return void
     */
    private function sendInternalEmployeeRosterEmail($empId, $rosterSettings)
    {
        // Get employee data
        $employeeCompany = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)
            ->find($empId);
        $employee = EmpPersonalDetails::where('emp_id', $empId)->first();

        if (!$employeeCompany || !$employee || !$employeeCompany->employee_email) {
            return;
        }

        $teamMember = EmpTeamsMember::where('emp_id', $empId)->first();
        $team = EmpTeam::where('id', $teamMember->team_id)->first();
        
        $teamName = $team->title ?? 'N/A';

        // Generate random password if not set
        $password = null;
        if (empty($employeeCompany->password)) {
            $password = $this->generateRandomPassword();
            $employeeCompany->password = Hash::make($password);
            $employeeCompany->save();
        }

        // Get worker type
        $workerType = EmpWorkerType::find($employeeCompany->worker_type);

        // Prepare login URL
        $loginUrl = env('FRONTEND_URL', url('/'));

        // Get roster assignments for this employee
        $rosterAssignments = RosterAssign::where('assign_to', $empId)
            ->with('rosterTemplate')
            ->orderBy('schedule_date', 'asc')
            ->get();

        $rosterDetails = [
            'individual_shifts' => [],
            'bulk_schedule' => null
        ];

        // Build bulk schedule details from roster settings
        if ($rosterSettings) {
            $working_days = explode(',', $rosterSettings['working_days_hidden']);

            $startDate = \Carbon\Carbon::parse($rosterSettings['start_date']);
            $endDate = \Carbon\Carbon::parse($rosterSettings['end_date']);
            $totalDays = $startDate->diffInDays($endDate);

            $rosterDetails['bulk_schedule'] = [
                'schedule_period_start' => $startDate->format('d-m-Y'),
                'schedule_period_end' => $endDate->format('d-m-Y'),
                'total_days' => $totalDays,
                'working_days' => implode(', ', $working_days),
                'daily_start_time' => date('h:i A', strtotime($rosterSettings['start_time'])),
                'daily_end_time' => date('h:i A', strtotime($rosterSettings['end_time'])),
                'daily_break_minutes' => $rosterSettings['break_minutes'] ?? 0,
                'shift_notes' => $rosterSettings['shift_notes'] ?? '',
                'total_working_days' => count($working_days),
                'working_hours' => $rosterSettings['working_hours'] ?? 8
            ];
        }

        // Get some example individual shifts (next 7 days)
        $exampleShifts = $rosterAssignments->take(7);
        foreach ($exampleShifts as $assignment) {
            if ($assignment->rosterTemplate) {
                $rosterDetails['individual_shifts'][] = [
                    'schedule_date' => date('d-m-Y', strtotime($assignment->schedule_date)),
                    'day_name' => date('l', strtotime($assignment->schedule_date)),
                    'start_time' => date('h:i A', strtotime($assignment->rosterTemplate->start_time)),
                    'end_time' => date('h:i A', strtotime($assignment->rosterTemplate->end_time)),
                    'break_minutes' => $assignment->rosterTemplate->break_minutes ?? 0,
                    'shift_notes' => $assignment->rosterTemplate->shift_notes ?? '',
                    'working_hours' => $assignment->rosterTemplate->working_hours ?? 0
                ];
            }
        }

        // Send email with login credentials and roster details
        $emailParams = [
            'to' => $employeeCompany->employee_email,
            'subject' => 'Welcome to ' . env('APP_NAME', 'WMS') . ' - Your Login Credentials & Work Schedule',
            'msg' => view('Emails.employee_onboarding_roster', [
                'subject' => 'Welcome to ' . env('APP_NAME', 'WMS') . ' - Your Login Credentials & Work Schedule',
                'employee' => $employee,
                'employeeCompany' => $employeeCompany,
                'workerType' => $workerType,
                'password' => $password,
                'login_url' => $loginUrl,
                'rosterDetails' => $rosterDetails,
                'teamName' => $teamName
            ])->render()
        ];
        $emailSent = $this->SendInstantEmail($emailParams);

        if ($emailSent) {
            Log::info('Internal employee onboarding email sent successfully', [
                'emp_id' => $empId,
                'employee_name' => $employee->first_name . ' ' . $employee->last_name,
                'employee_email' => $employeeCompany->employee_email
            ]);
        } else {
            Log::error('Failed to send internal employee onboarding email', [
                'emp_id' => $empId,
                'employee_name' => $employee->first_name . ' ' . $employee->last_name,
                'employee_email' => $employeeCompany->employee_email,
                'error' => 'SendInstantEmail returned false'
            ]);
        }
    }

    /**
     * Generate random password
     * 
     * @return string
     */
    private function generateRandomPassword()
    {
        $length = 8;
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $password = '';

        for ($i = 0; $i < $length; $i++) {
            $password .= $characters[rand(0, strlen($characters) - 1)];
        }

        return $password;
    }
}
