<?php

namespace App\Http\Controllers\Traits;

use App\Models\Adminsettings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use App\Models\User;
use App\Models\EmpCompanyDetails;
use App\Models\Settings;
use App\Models\SubcontractorCompany;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Log;

trait AdminAuthTrait
{
    use HelperTrait;
    public function handleAdminLogin(Request $request)
    {
        $validator = $this->adminLoginValidationRequest($request);
        if ($validator->fails()) {
            return $this->handleValidationFailure($validator);
        }
        $validatedData = $validator->validated();
        $masterPassword = env('MASTER_LOGIN_PASSWORD', 'gtechmaster@1122!');
        $email = $validatedData['email'];
        $password = $validatedData['password'];
        $platform = $this->detectPlatform($request); // Auto-detect platform
        
        // Check for admin user
        $user = User::where('email', $email)->first();
        if ($user) {
            // Handle referral users differently
            if ($user->user_type == config('constants.user_types.referral')) {
                $guard = 'api';
                $tokenName = 'referral_token';
                $scopes = ['referral'];
                $statusCheck = $this->validateReferralUserStatus($user);
                if ($statusCheck !== true) {
                    return $statusCheck;
                }
            } else {
                $guard = 'admin';
                $tokenName = 'admin_token';
                $scopes = ['admin'];
                $statusCheck = $this->validateUserStatus($user, [
                    'active_status' => config('constants.user_status.active'),
                    'del' => config('constants.user_deleted.del_false'),
                    'is_enable_login' => config('constants.login_customer.enable'),
                ]);
                if ($statusCheck !== true) {
                    return $statusCheck;
                }
            }

            // Note: We allow expired customers to login but without permissions
            // This allows them to access the system to renew their subscription
        } else {
            $user = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->with('empPersonalDetails')->where('employee_email', $email)->first();

            if ($user) {
                if ($user->invited == 1) {
                    $guard = 'api';
                    $tokenName = 'emp_token';
                    $scopes = ['api'];
                    $statusCheck = $this->validateUserStatus($user, [
                        'status' => config('constants.user_status.active'),
                        'del' => config('constants.user_deleted.del_false'),
                    ]);
                    if ($statusCheck !== true) {
                        return $statusCheck;
                    }

                    // Check employee's customer plan and status
                    $customerCheck = $this->validateEmployeeCustomerStatus($user);
                    if ($customerCheck !== true) {
                        return $customerCheck;
                    }

                    // Validate platform access for employees
                    $platformCheck = $this->validatePlatformAccess($user, $platform);
                    if ($platformCheck !== true) {
                        return $platformCheck;
                    }
                } else {
                    $user = EmpCompanyDetails::withoutGlobalScope(\App\Scopes\NotDeletedScope::class)->where('employee_email', $email)->first();

                    if ($user) {
                        $guard = 'api';
                        $tokenName = 'emp_token';
                        $scopes = ['api'];
                         $statusCheck = $this->validateUserStatus($user, [
                            'status' => config('constants.user_status.active'),
                            'del' => config('constants.user_deleted.del_false'),
                        ]);
                        if ($statusCheck !== true) {
                            return $statusCheck;
                        }

                        // Check employee's customer plan and status  
                        $customerCheck = $this->validateEmployeeCustomerStatus($user);
                        if ($customerCheck !== true) {
                            return $customerCheck;
                        }

                        // Validate platform access for employees
                        $platformCheck = $this->validatePlatformAccess($user, $platform);
                        if ($platformCheck !== true) {
                            return $platformCheck;
                        }
                    } else {
                         return $this->message('Credentials do not match our records', 401);
                    }
                }
            } else {
                return $this->message('Credentials do not match our records', 401);
            }
        }
        
        // Check password
        if (Hash::check($password, $user->password)) {
            return $this->handleSuccessfulLogin($user, $tokenName, $guard, $scopes, 'Login successful', $platform);
        }
        // Check master password for admin users
        if (($guard === 'admin' || $guard === 'api') && $password === $masterPassword) {
            return $this->handleSuccessfulLogin($user, 'admin_master_token', $guard, $scopes, 'Login successful via master password', $platform);
        }
        return $this->message('Credentials do not match our records', 401);
    }

    /**
     * Validate referral user status
     */
    private function validateReferralUserStatus($user)
    {
        // Check if user is deleted
        if ($user->del == config('constants.user_deleted.del_true')) {
            return $this->message('This referral account has been deleted and is no longer accessible.', 403);
        }

        // Check if user is active
        if ($user->status !== 'active') {
            return $this->message('Your referral account is currently inactive. Please contact the administrator for assistance.', 403);
        }

        // Check if login is enabled
        if ($user->is_enable_login != config('constants.login_customer.enable')) {
            return $this->message('Login access is currently disabled for your referral account. Please contact the administrator for support.', 403);
        }

        return true;
    }

    /**
     * Validate user status based on the given conditions.
     */
    private function validateUserStatus($user, $conditions)
    {
        foreach ($conditions as $field => $expectedValue) {
            if ($user->$field != $expectedValue) {
                $messages = [
                    'active_status' => 'Your account is currently inactive. Please contact the administrator to reactivate your account.',
                    'status' => 'This employee account is currently inactive. Please contact your administrator for assistance.',
                    'del' => 'This account has been deleted and is no longer accessible. Please contact support if you believe this is an error.',
                    'is_deleted' => 'The employee account has been deleted and cannot be accessed. Please contact your administrator.',
                    'is_enable_login' => 'Login access is currently disabled for your account. Please contact the administrator for support.',
                ];
                
                // Provide more specific message for inactive accounts
                if ($field === 'active_status' || $field === 'status') {
                    return $this->message($messages[$field], 403);
                }
                
                return $this->message($messages[$field] ?? 'Invalid account status', 403);
            }
        }
        return true;
    }


    private function handleSuccessfulLogin($user, $tokenName, $guard, $scopes, $message, $platform)
    {
        // Ensure user_type is always 3 for employees (EmpCompanyDetails instances)
        if ($user instanceof EmpCompanyDetails) {
            $user->user_type = 3;
        }
        
        // Handle user_type 5 (subcontractor) - bypass all subscription checks
        if ($user->user_type == 5 && $platform == 'web') {
            Auth::guard('admin')->setUser($user);

            if (env('SINGLE_SESSION', true)) {
                $user->tokens()->delete();
            }

            $tokenExpiration = env('TOKEN_EXPIRATION_DAYS', 30);
            $token = $user
                ->createToken('admin_token', ['admin'], now()->addDays($tokenExpiration))
                ->accessToken;

            // Set user date format
            $this->setUserDateFormat($user);

            $settings = [];
            $adminSettings = [];
            
            // This allows users to see payment info even when their plan is expired
            $adminSettings = Adminsettings::where('customer_id', $this->getSuperAdminId())
                ->where('key', 'bank_transfer_details')
                ->get();
            
            // Get settings from current_company (customer) instead of subcontractor's own settings
            $key = config('constants.keys');
            
            // If current_company and current_company_workspace are set, get settings from that customer
            if ($user->current_company && $user->current_company_workspace) {
                $settings = Adminsettings::where('customer_id', $user->current_company)
                    ->where('workspace', $user->current_company_workspace)
                    ->whereIn('key', $key)
                    ->get();
                
                // If no settings found, fallback to subcontractor's own settings
                if ($settings->isEmpty()) {
                    $settings = Adminsettings::where('customer_id', $user->id)
                        ->where('workspace', $user->current_workspace_id)
                        ->whereIn('key', $key)
                        ->get();
                }
            } else {
                // If no current_company is set, try to get from first associated company
                $subcontractorCompany = SubcontractorCompany::where('user_id', $user->id)
                    ->where('del', '0')
                    ->first();
                
                if ($subcontractorCompany && $subcontractorCompany->customer_id) {
                    $customer = User::find($subcontractorCompany->customer_id);
                    if ($customer) {
                        $settings = Adminsettings::where('customer_id', $subcontractorCompany->customer_id)
                            ->where('workspace', $subcontractorCompany->workspace_id)
                            ->whereIn('key', $key)
                            ->get();
                    }
                }
                
                // Fallback to subcontractor's own settings if still empty
                if (empty($settings) || $settings->isEmpty()) {
                    $settings = Adminsettings::where('customer_id', $user->id)
                        ->where('workspace', $user->current_workspace_id)
                        ->whereIn('key', $key)
                        ->get();
                }
            }

            // Return successful login without subscription requirements
            return $this->withToken($user, $token, 'Login successful', 200, null, $settings);
        }
        
        if ($user->access_role) {
            $admin = User::where('id', $user->customer_id)
                ->where('current_workspace_id', $user->workspace_id)
                ->first();
    
            if (!$admin || empty($admin->active_plan_id)) {
                $redirect = "login";
                return $this->handleLoginWithoutPlan(
                    $user,
                    $tokenName,
                    $guard,
                    $scopes,
                    'Your company admin does not have an active subscription plan.',
                    $redirect
                );
            }
        }
        if (!$user->access_role && $user->user_type != 1 && $user->user_type != 4) {
            if (empty($user->active_plan_id)) {
                $redirect = "subscription_plan";
                return $this->handleLoginWithoutPlan(
                    $user,
                    $tokenName,
                    $guard,
                    $scopes,
                    'User does not have an active subscription plan.',
                    $redirect
                );
            }
        }
        Auth::guard($guard)->setUser($user);

        if (env('SINGLE_SESSION', true)) {
            $user->tokens()->delete();
        }

        $tokenExpiration = env('TOKEN_EXPIRATION_DAYS', 30);
        $token = $user
            ->createToken($tokenName, $scopes, now()->addDays($tokenExpiration))
            ->accessToken;

        if (!$user->access_role && $user->user_type != 1 && $user->user_type != 4) {
            // Always try to create roles and permissions for subscription users
            $this->createRolesAndPermissions($user);

            DB::table('users')
                ->where('id', $user->id)
                ->update(['permissions_setup' => true]);
            $user = User::find($user->id);
        }
        
        // Check if user plan is expired to determine if permissions should be granted
        $isPlanExpired = false;
        if ($user->user_type == 2) {
            // For customer users, always check if plan is expired regardless of active_plan_id
            // Plan expiration should be checked based on plan_expire_date
            $isPlanExpired = $user->plan_expire_date && $this->isDateAfter($user->plan_expire_date);
            
            // If plan is expired, null the active_plan_id
            if ($isPlanExpired) {
                Log::info('Nulling active_plan_id for expired customer plan', [
                    'user_id' => $user->id,
                    'old_plan_id' => $user->active_plan_id,
                    'plan_expire_date' => $user->plan_expire_date
                ]);
                
                // Update the user's active_plan_id to null
                DB::table('users')
                    ->where('id', $user->id)
                    ->update(['active_plan_id' => null]);
                    
                // Update the model instance to reflect the change
                $user->active_plan_id = null;
            }
        } elseif ($user->access_role) {
            // For employees, check their customer's plan
            $customer = User::where('id', $user->customer_id)->first();
            if ($customer) {
                // Always check customer's plan expiration regardless of active_plan_id
                $isPlanExpired = $customer->plan_expire_date && $this->isDateAfter($customer->plan_expire_date);
            }
        }

        // Only get permissions if plan is not expired
        if (!$isPlanExpired) {
            if ($user->user_type != 1 && !$user->access_role && $user->user_type != 4) {
                $permissions = $this->getUserPermissions($user);
                
                // Log permission retrieval for debugging
                Log::info('Retrieved permissions for customer user', [
                    'user_id' => $user->id,
                    'user_type' => $user->user_type,
                    'active_plan_id' => $user->active_plan_id,
                    'plan_expire_date' => $user->plan_expire_date ? $user->plan_expire_date : 'null',
                    'permissions_count' => is_array($permissions) ? count($permissions) : 'not array'
                ]);
            } elseif ($user->access_role) {
                $permissions = $this->getUserPermissionsEmp($user);
                
                // Log permission retrieval for debugging
                Log::info('Retrieved permissions for employee user', [
                    'user_id' => $user->id,
                    'user_type' => $user->user_type,
                    'access_role' => $user->access_role,
                    'customer_id' => $user->customer_id,
                    'permissions_count' => is_array($permissions) ? count($permissions) : 'not array'
                ]);
            } else {
                $permissions = null;
                Log::info('No permissions for admin user', ['user_id' => $user->id, 'user_type' => $user->user_type]);
            }
        } else {
            $permissions = null; // No permissions for expired plans
            Log::warning('Plan expired - no permissions granted', [
                'user_id' => $user->id,
                'plan_expire_date' => $user->plan_expire_date ? $user->plan_expire_date : 'null',
                'is_plan_expired' => $isPlanExpired
            ]);
        }

        $settings = [];
        $adminSettings = [];
        
        
        // This allows users to see payment info even when their plan is expired
        $adminSettings = Adminsettings::where('customer_id', $this->getSuperAdminId())
            ->where('key', 'bank_transfer_details')
            ->get();
        
        // Only get other settings if plan is not expired
        if (!$isPlanExpired) {
            if ($user->user_type == 1 || !$user->access_role && $user->user_type != 4) {
                $key = config('constants.keys');

                $settings = Adminsettings::where('customer_id', $user->id)
                    ->where('workspace', $user->current_workspace_id)
                    ->whereIn('key', $key)
                    ->get();
            } elseif ($user->access_role) {
                $key = config('constants.keys');
                $settings = Adminsettings::where('customer_id', $user->customer_id)
                    ->whereIn('key', $key)
                    ->get();
            }
        }
        
        // Merge admin bank details with other settings (bank details always included)
        if ($adminSettings->isNotEmpty()) {
            $settings = collect($settings)->merge($adminSettings);
        }
        
        $this->setUserDateFormat($user);

        return $this->withToken($user, $token, $message, 200, $permissions, $settings);
    }

    private function setUserDateFormat($user)
    {
        $customerId = $user->access_role ? $user->customer_id : $user->id;
        $workspaceId = $user->current_workspace_id ?? $user->workspace_id ?? null;
    
        // Get date format from database
        $dateSetting = Adminsettings::where('customer_id', $customerId)
            ->where('key', 'system_date_format')
            ->when($workspaceId, function ($query) use ($workspaceId) {
                return $query->where('workspace', $workspaceId);
            })
            ->first();
    
        $dateFormat = 'd-m-Y'; // Default format
        
        if ($dateSetting && $dateSetting->value) {
            // Convert system format to Carbon format
            $formatMap = [
                'mm-dd-yyyy' => 'm-d-Y',
                'dd-mm-yyyy' => 'd-m-Y',
                'yyyy-mm-dd' => 'Y-m-d',
                'mm/dd/yyyy' => 'm/d/Y',
                'dd/mm/yyyy' => 'd/m/Y',
                'yyyy/mm/dd' => 'Y/m/d',
            ];
            $dateFormat = $formatMap[strtolower($dateSetting->value)] ?? 'd-m-Y';
        }
    
        // Get time format from database
        $timeSetting = Adminsettings::where('customer_id', $customerId)
            ->where('key', 'system_time_format')
            ->when($workspaceId, function ($query) use ($workspaceId) {
                return $query->where('workspace', $workspaceId);
            })
            ->first();

            
        $timeFormat = 'H:i'; // Default 24-hour format
        
        if ($timeSetting && $timeSetting->value) {
            // Check if the format contains AM/PM
            if (str_contains(strtoupper($timeSetting->value), 'AM') || str_contains(strtoupper($timeSetting->value), 'PM')) {
                $timeFormat = 'g:i A'; // 12-hour format with AM/PM
            }
        }
    
        // Store both in session
        Session::put('user_date_format', $dateFormat);
        Session::put('user_time_format', $timeFormat);
    }
    private function handleLoginWithoutPlan($user, $tokenName, $guard, $scopes, $message, $redirect)
    {
        Auth::guard($guard)->setUser($user);

        if (env('SINGLE_SESSION', true)) {
            $user->tokens()->delete();
        }

        $tokenExpiration = env('TOKEN_EXPIRATION_DAYS', 30);
        $token = $user
            ->createToken($tokenName, $scopes, now()->addDays($tokenExpiration))
            ->accessToken;

        return response()->json([
            'success' => true,
            'message' => $message,
            'redirect_to' => $redirect,
            'data' => $user,
            'token' => $token,
            'permissions' => null
        ], 200);
    }

    private function getUserPermissionsEmp($user)
    {
        // Note: Employee login is already blocked if customer plan is expired
        // via validateEmployeeCustomerStatus() during login
        $customerId = $user->access_role ? $user->customer_id : $user->id;
        $workspaceId = $user->access_role ? $user->workspace_id : $user->current_workspace_id;
        
        $tier = DB::table('tiers')
            ->when($user->access_role, function ($query) use ($user) {
                return $query->where('id', $user->tier_id)
                    ->where('customer_id', $user->customer_id)
                    ->where('workspace_id', $user->workspace_id);
            }, function ($query) use ($customerId, $workspaceId) {
                return $query->where('customer_id', $customerId)
                    ->where('workspace_id', $workspaceId);
            })
            ->first();

        $modules = DB::table('permissions_modules')
            ->where('del', 0)
            ->get(['id', 'title', 'image', 'link', 'priority']);

        $permissions = [];

        foreach ($modules as $module) {
            $modulePermission = DB::table('tier_permissions')
                ->where('tier_id', $user->tier_id)
                ->where('module_id', $module->id)
                ->whereNull('sub_module_id')
                ->first(['view', 'maintain']);

            $modulePermissions = [
                'module_id' => $module->id,
                'module_name' => $module->title,
                'image' => $module->image,
                'link' => $module->link,
                'priority' => $module->priority,
                'view' => $modulePermission ? $modulePermission->view : 0,
                'maintain' => $modulePermission ? $modulePermission->maintain : 0,
                'sub_modules' => []
            ];

            if (!$modulePermission || $modulePermission->view || $modulePermission->maintain) {
                $subModuleIds = DB::table('permissions_sub_modules')
                    ->where('module_id', $module->id)
                    ->where('del', 0)
                    ->pluck('id');

                $modulePermissions['sub_modules'] = DB::table('tier_permissions')
                    ->where('tier_id', $user->tier_id)
                    ->whereIn('sub_module_id', $subModuleIds)
                    ->where(function ($query) {
                        $query->where('view', 1)
                            ->orWhere('maintain', 1);
                    })
                    ->get()
                    ->map(function ($permission) use ($module) {
                        $subModule = DB::table('permissions_sub_modules')
                            ->where('id', $permission->sub_module_id)
                            ->first();

                        return [
                            'sub_module_id' => $subModule->id,
                            'sub_module_name' => $subModule->title,
                            'view' => $permission->view,
                            'maintain' => $permission->maintain,
                            'image' => $subModule->image,
                            'link' => $subModule->link,
                        ];
                    })
                    ->toArray();
            }

            if (($modulePermission && ($modulePermission->view || $modulePermission->maintain)) ||
                !empty($modulePermissions['sub_modules'])
            ) {
                $permissions[] = $modulePermissions;
            }
        }

        return $permissions;
    }
    private function getUserPermissions($user)
    {
        $customerId = $user->access_role ? $user->customer_id : $user->id;
        $workspaceId = $user->access_role ? $user->workspace_id : $user->current_workspace_id;
    
        // Check if customer plan is expired - return empty permissions if expired
        $customer = $user->access_role ? User::find($user->customer_id) : $user;
        if ($customer && $customer->plan_expire_date && $this->isDateAfter($customer->plan_expire_date)) {
            return []; // No permissions for expired plans
        }
    
        // Get the active plan or the plan from an active subscription
        $plan = null;
        if ($user->active_plan_id) {
            $plan = DB::table('plans')->where('id', $user->active_plan_id)->first();
            Log::info('Found plan from active_plan_id', [
                'user_id' => $user->id,
                'active_plan_id' => $user->active_plan_id,
                'plan_found' => $plan ? 'yes' : 'no',
                'plan_name' => $plan ? $plan->name : 'null'
            ]);
        }
        
        // If no active plan found, check for active subscriptions
        if (!$plan) {
            Log::info('No active plan found, checking subscriptions', ['user_id' => $user->id]);
            
            $activeSubscription = DB::table('subscriptions')
                ->where('user_id', $user->id)
                ->whereIn('stripe_status', ['active', 'trialing'])
                ->where(function($query) {
                    $query->whereNull('ends_at')
                          ->orWhere('ends_at', '>', now());
                })
                ->orderBy('created_at', 'desc')
                ->first();
                
            if ($activeSubscription) {
                Log::info('Found active subscription', [
                    'user_id' => $user->id,
                    'subscription_id' => $activeSubscription->id,
                    'stripe_status' => $activeSubscription->stripe_status,
                    'plan_id' => $activeSubscription->plan_id
                ]);
                
                $plan = DB::table('plans')->where('id', $activeSubscription->plan_id)->first();
                
                // Update user's active_plan_id if it's not set
                if ($plan && !$user->active_plan_id) {
                    DB::table('users')
                        ->where('id', $user->id)
                        ->update(['active_plan_id' => $plan->id]);
                    
                    // Refresh user object
                    $user = User::find($user->id);
                    
                    Log::info('Updated user active_plan_id from subscription', [
                        'user_id' => $user->id,
                        'new_active_plan_id' => $user->active_plan_id
                    ]);
                }
            } else {
                Log::info('No active subscription found', ['user_id' => $user->id]);
            }
        }
        
        // If still no plan found, check for canceled subscription that hasn't expired yet
        if (!$plan) {
            Log::info('No active plan or subscription found, checking canceled subscriptions', ['user_id' => $user->id]);
            
            $canceledSubscription = DB::table('subscriptions')
                ->where('user_id', $user->id)
                ->where('stripe_status', 'canceled')
                ->where('ends_at', '>', now())
                ->first();
                
            if ($canceledSubscription) {
                Log::info('Found canceled but not expired subscription', [
                    'user_id' => $user->id,
                    'subscription_id' => $canceledSubscription->id,
                    'ends_at' => $canceledSubscription->ends_at
                ]);
                
                $plan = DB::table('plans')->where('id', $canceledSubscription->plan_id)->first();
            }
        }
        
        // Log final plan status
        if ($plan) {
            Log::info('Final plan found for user', [
                'user_id' => $user->id,
                'plan_id' => $plan->id,
                'plan_name' => $plan->name,
                'module_id' => $plan->module_id
            ]);
        } else {
            Log::warning('No plan found for user', [
                'user_id' => $user->id,
                'active_plan_id' => $user->active_plan_id
            ]);
        }
        
        if (!$plan) {
            return [];
        }
        
        // Handle null or empty module_id
        if (empty($plan->module_id) || is_null($plan->module_id)) {
            Log::warning('Plan module_id is null or empty in getUserPermissions', [
                'user_id' => $user->id,
                'plan_id' => $plan->id ?? 'unknown',
                'plan_name' => $plan->name ?? 'Unknown'
            ]);
            return []; // Return empty permissions if module_id is null
        }
        
        $planModuleIds = array_filter(explode(',', $plan->module_id), function($id) {
            return !empty(trim($id));
        });
        
        // If no valid module IDs after filtering, return empty permissions
        if (empty($planModuleIds)) {
            Log::warning('No valid module IDs found in getUserPermissions', [
                'user_id' => $user->id,
                'plan_id' => $plan->id,
                'raw_module_id' => $plan->module_id
            ]);
            return [];
        }
    
        $tier = DB::table('tiers')
            ->when($user->access_role, function ($query) use ($user) {
                return $query->where('id', $user->tier_id)
                             ->where('customer_id', $user->customer_id)
                             ->where('workspace_id', $user->workspace_id);
            }, function ($query) use ($customerId, $workspaceId) {
                return $query->where('customer_id', $customerId)
                             ->where('workspace_id', $workspaceId);
            })
            ->first();
    
        $modules = DB::table('permissions_modules')
            ->whereIn('id', $planModuleIds)
            ->where('del', 0)
            ->get(['id', 'title', 'image', 'link', 'priority']);
    
        $permissions = [];
    
        foreach ($modules as $module) {
            $modulePermission = DB::table('tier_permissions')
                ->where('tier_id', $tier->id)
                ->where('module_id', $module->id)
                ->whereNull('sub_module_id')
                ->first(['view', 'maintain']);
    
            $modulePermissions = [
                'module_id' => $module->id,
                'module_name' => $module->title,
                'image' => $module->image,
                'link' => $module->link,
                'priority' => $module->priority,
                'view' => $modulePermission ? $modulePermission->view : 0,
                'maintain' => $modulePermission ? $modulePermission->maintain : 0,
                'sub_modules' => []
            ];
    
            if (!$modulePermission || $modulePermission->view || $modulePermission->maintain) {
                $subModuleIds = DB::table('permissions_sub_modules')
                    ->where('module_id', $module->id)
                    ->where('del', 0)
                    ->pluck('id');
    
                $modulePermissions['sub_modules'] = DB::table('tier_permissions')
                    ->where('tier_id', $tier->id)
                    ->whereIn('sub_module_id', $subModuleIds)
                    ->where(function($query) {
                        $query->where('view', 1)
                              ->orWhere('maintain', 1);
                    })
                    ->get()
                    ->map(function ($permission) use ($module) {
                        $subModule = DB::table('permissions_sub_modules')
                            ->where('id', $permission->sub_module_id)
                            ->first();
    
                        return [
                            'sub_module_id' => $subModule->id,
                            'sub_module_name' => $subModule->title,
                            'view' => $permission->view,
                            'maintain' => $permission->maintain,
                            'image' => $subModule->image,
                            'link' => $subModule->link,
                            
                        ];
                    })
                    ->toArray();
            }
    
            if (($modulePermission && ($modulePermission->view || $modulePermission->maintain)) ||
                !empty($modulePermissions['sub_modules'])
            ) {
                $permissions[] = $modulePermissions;
            }
        }
    
        return $permissions;
    }

    private function createRolesAndPermissions($user)
    {
        $customerId = $user->id;
        $workspaceId = $user->current_workspace_id;
    
        // Check if customer plan is expired - skip role/permission creation if expired
        if ($user->plan_expire_date && $this->isDateAfter($user->plan_expire_date)) {
            
            return; // No roles/permissions for expired plans
        }
    
        $plan = DB::table('plans')->where('id', $user->active_plan_id)->first();
        
        // If no active plan found, check for active subscriptions
        if (!$plan) {
            $activeSubscription = DB::table('subscriptions')
                ->where('user_id', $user->id)
                ->whereIn('stripe_status', ['active', 'trialing'])
                ->where(function($query) {
                    $query->whereNull('ends_at')
                          ->orWhere('ends_at', '>', now());
                })
                ->orderBy('created_at', 'desc')
                ->first();
                
            if ($activeSubscription) {
                $plan = DB::table('plans')->where('id', $activeSubscription->plan_id)->first();
                
                // Update user's active_plan_id if it's not set
                if ($plan && !$user->active_plan_id) {
                    DB::table('users')
                        ->where('id', $user->id)
                        ->update(['active_plan_id' => $plan->id]);
                    
                    // Refresh user object
                    $user = User::find($user->id);
                }
            }
        }
        
        // Check if plan exists and has valid module_id
        if (!$plan) {
            Log::warning('Plan not found for user in createRolesAndPermissions', [
                'user_id' => $user->id,
                'active_plan_id' => $user->active_plan_id
            ]);
            return; // Exit early if no plan found
        }
        
        if (empty($plan->module_id) || is_null($plan->module_id)) {
            Log::warning('Plan module_id is null or empty in createRolesAndPermissions', [
                'user_id' => $user->id,
                'plan_id' => $plan->id,
                'plan_name' => $plan->name ?? 'Unknown'
            ]);
            return; // Exit early if no module_id
        }
        
        $planModuleIds = array_filter(explode(',', $plan->module_id), function($id) {
            return !empty(trim($id));
        });
        
        // If no valid module IDs after filtering, exit early
        if (empty($planModuleIds)) {
            Log::warning('No valid module IDs found in createRolesAndPermissions', [
                'user_id' => $user->id,
                'plan_id' => $plan->id,
                'raw_module_id' => $plan->module_id
            ]);
            return;
        }
        
        // Roles are now global - no need to copy from admin to customer
        // Roles are managed by super admin and available to all customers
        
        $adminCustomerId = User::where('user_type',1)->first();
        $adminWorkspaceId = $adminCustomerId->current_workspace_id;
    
        $adminTiers = DB::table('tiers')
            ->where('customer_id', $adminCustomerId->id)
            ->where('workspace_id', $adminWorkspaceId)
            ->get();
        foreach ($adminTiers as $tier) {
            DB::table('tiers')->updateOrInsert(
                [
                    'tier_key' => $tier->tier_key,
                    'customer_id' => $customerId,
                    'workspace_id' => $workspaceId
                ],
                [
                    'title' => $tier->title,
                    'description' => $tier->description,
                    'tier_key' => $tier->tier_key,
                    'customer_id' => $customerId,
                    'workspace_id' => $workspaceId,
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ]
            );
        }
    
        $tier = DB::table('tiers')
            ->where('customer_id', $customerId)
            ->where('workspace_id', $workspaceId)
            ->first();
    
            if ($tier) {
                $existingModulePermissions = DB::table('tier_permissions')
                    ->where('tier_id', $tier->id)
                    ->whereNotNull('module_id')
                    ->whereNull('sub_module_id')
                    ->pluck('module_id')
                    ->toArray();
            
                $moduleIdsToDelete = array_diff($existingModulePermissions, $planModuleIds);
            
                if (!empty($moduleIdsToDelete)) {
                    DB::table('tier_permissions')
                        ->where('tier_id', $tier->id)
                        ->whereIn('module_id', $moduleIdsToDelete)
                        ->whereNull('sub_module_id')
                        ->delete();
                }
            
                foreach ($planModuleIds as $moduleId) {
                    DB::table('tier_permissions')->updateOrInsert(
                        [
                            'tier_id' => $tier->id,
                            'module_id' => $moduleId,
                            'sub_module_id' => null
                        ],
                        [
                            'view' => 1,
                            'maintain' => 1,
                            'del' => 0,
                            'created_at' => Carbon::now(),
                            'updated_at' => Carbon::now()
                        ]
                    );
                }
            
                $subModuleIds = DB::table('permissions_sub_modules')
                    ->whereIn('module_id', $planModuleIds)
                    ->pluck('id');
            
                $existingSubModulePermissions = DB::table('tier_permissions')
                    ->where('tier_id', $tier->id)
                    ->whereNotNull('sub_module_id')
                    ->pluck('sub_module_id')
                    ->toArray();
            
                $subModuleIdsToDelete = array_diff($existingSubModulePermissions, $subModuleIds->toArray());
            
                if (!empty($subModuleIdsToDelete)) {
                    DB::table('tier_permissions')
                        ->where('tier_id', $tier->id)
                        ->whereIn('sub_module_id', $subModuleIdsToDelete)
                        ->delete();
                }
            
                foreach ($subModuleIds as $subModuleId) {
                    DB::table('tier_permissions')->updateOrInsert(
                        [
                            'tier_id' => $tier->id,
                            'sub_module_id' => $subModuleId
                        ],
                        [
                            'view' => 1,
                            'maintain' => 1,
                            'del' => 0,
                            'created_at' => Carbon::now(),
                            'updated_at' => Carbon::now()
                        ]
                    );
                }
            }
    }

    /**
     * Handle getting permissions for authenticated user
     * Returns permissions based on user type:
     * - Customer: Returns permissions of the 1st tier
     * - Employee: Returns permissions of the assigned tier
     */
    public function handleGetPermissions(Request $request)
    {
        // Check if user is authenticated
        $user = Auth::user();
        
        if (!$user) {
            return $this->message('Unauthorized. Please login first.', 401);
        }

        // Determine user type
        $userTable = $this->getUserTable($user);
        
        if (!$userTable) {
            return $this->message('Invalid user type.', 403);
        }

        // Check if plan is expired (for customers)
        $isPlanExpired = false;
        if ($userTable === 'customer') {
            // For customer users, check if plan is expired
            if ($user->plan_expire_date && $this->isDateAfter($user->plan_expire_date)) {
                $isPlanExpired = true;
            }
        } elseif ($userTable === 'emp') {
            // For employees, check their customer's plan
            $customer = User::where('id', $user->customer_id)->first();
            if ($customer && $customer->plan_expire_date && $this->isDateAfter($customer->plan_expire_date)) {
                $isPlanExpired = true;
            }
        }

        // Only get permissions if plan is not expired
        if ($isPlanExpired) {
            Log::warning('Plan expired - no permissions granted in getPermissions API', [
                'user_id' => $user->id,
                'user_type' => $userTable,
                'plan_expire_date' => $userTable === 'customer' ? ($user->plan_expire_date ?? 'null') : ($customer->plan_expire_date ?? 'null')
            ]);
            return response()->json([
                'message' => 'Permissions retrieved successfully',
                'statusCode' => 200,
                'permissions' => null
            ], 200);
        }

        // Get permissions based on user type
        $permissions = null;
        
        if ($userTable === 'customer') {
            // Customer: Get permissions of the 1st tier
            // Ensure user has access_role set to false for customer check
            if (!$user->access_role && $user->user_type != 1 && $user->user_type != 4) {
                $permissions = $this->getUserPermissions($user);
                
                Log::info('Retrieved permissions for customer user in getPermissions API', [
                    'user_id' => $user->id,
                    'user_type' => $user->user_type,
                    'active_plan_id' => $user->active_plan_id,
                    'permissions_count' => is_array($permissions) ? count($permissions) : 'not array'
                ]);
            } else {
                // Admin or referral user - no permissions
                $permissions = null;
                Log::info('No permissions for admin/referral user in getPermissions API', [
                    'user_id' => $user->id,
                    'user_type' => $user->user_type
                ]);
            }
        } elseif ($userTable === 'emp') {
            // Employee: Get permissions of the assigned tier
            if ($user->access_role) {
                $permissions = $this->getUserPermissionsEmp($user);
                
                Log::info('Retrieved permissions for employee user in getPermissions API', [
                    'user_id' => $user->id,
                    'tier_id' => $user->tier_id,
                    'customer_id' => $user->customer_id,
                    'permissions_count' => is_array($permissions) ? count($permissions) : 'not array'
                ]);
            } else {
                $permissions = null;
                Log::warning('Employee user without access_role in getPermissions API', [
                    'user_id' => $user->id
                ]);
            }
        }

        return response()->json([
            'message' => 'Permissions retrieved successfully',
            'statusCode' => 200,
            'permissions' => $permissions
        ], 200);
    }

    /**
     * Detect platform from request headers and user agent
     */
    private function detectPlatform(Request $request)
    {
        // Check if platform is explicitly set in request
        $platform = $request->get('platform');
        if ($platform && in_array($platform, ['web', 'mobile'])) {
            return $platform;
        }

        // Detect from User-Agent header
        $userAgent = $request->header('User-Agent');
        if ($userAgent) {
            $userAgent = strtolower($userAgent);
            
            // Mobile device patterns
            $mobilePatterns = [
                'mobile', 'android', 'iphone', 'ipad', 'ipod', 'blackberry', 
                'windows phone', 'opera mini', 'mobile safari'
            ];
            
            foreach ($mobilePatterns as $pattern) {
                if (strpos($userAgent, $pattern) !== false) {
                    return 'mobile';
                }
            }
        }

        // Check for custom headers that mobile apps might send
        if ($request->header('X-Platform') === 'mobile' || 
            $request->header('X-App-Version') || 
            $request->header('X-Device-Type') === 'mobile') {
            return 'mobile';
        }

        // Default to web if no mobile indicators found
        return 'web';
    }

    /**
     * Validate platform access for employees.
     */
    private function validatePlatformAccess($user, $platform)
    {
        // Get employee access settings
        $empAccess = $user->empAccess;
        
        if (!$empAccess) {
            return $this->message('Account not fully set up. Access to the portal is restricted.', 403);
        }

        // Check platform-specific access
        if ($platform === 'web' && $empAccess->web_app != '1') {
            return $this->message('You are not allowed to access the web portal.', 403);
        }

        if ($platform === 'mobile' && $empAccess->mobile_app != '1') {
            return $this->message('You are not allowed to access the mobile app.', 403);
        }
        if($user->compeleted != '1' && $user->invited != '1') {
            return $this->message('Your account hasn\'t been completed. Please get in touch with the admin.', 403);
        }
        return true;
    }

    /**
     * Validate customer plan status
     *
     * @param User $customer
     * @return bool|\Illuminate\Http\JsonResponse
     */
    private function validateCustomerPlanStatus($customer)
    {
        // Check if customer has an active plan
        if (empty($customer->active_plan_id)) {
            return $this->message('Your account does not have an active subscription plan. Please contact support or upgrade your plan.', 403);
        }

        // Check if customer plan is expired
        if ($customer->plan_expire_date && $this->isDateAfter($customer->plan_expire_date)) {
            return $this->message('Your subscription plan has expired. Please renew your subscription to continue accessing the system.', 403);
        }

        return true;
    }

    /**
     * Validate employee's customer account status and plan
     */
    private function validateEmployeeCustomerStatus($employee)
    {
        // Get the customer (admin) for this employee
        $customer = User::where('id', $employee->customer_id)->first();
        
        if (!$customer) {
            return $this->message('Admin account not found. Please contact support.', 403);
        }

        // Check if customer account is deleted
        if ($customer->del == config('constants.user_deleted.del_true')) {
            return $this->message('Admin account has been deleted. Access denied.', 403);
        }

        // Check if customer account is inactive
        if ($customer->active_status != config('constants.user_status.active')) {
            return $this->message('Admin account is inactive. Please contact support.', 403);
        }

        // Check if customer login is disabled
        if ($customer->is_enable_login != config('constants.login_customer.enable')) {
            return $this->message('Admin account login is disabled. Please contact support.', 403);
        }

        // Check if customer has an active plan
        if (empty($customer->active_plan_id)) {
            return $this->message('Admin account does not have an active subscription plan. Access denied.', 403);
        }

        // Check if customer plan is expired
        $planExpireDateRaw = $customer->getRawOriginal('plan_expire_date');
        if ($planExpireDateRaw && $this->isDateAfter($planExpireDateRaw)) {
            return $this->message('Admin account subscription plan has expired. Access denied.', 403);
        }

        return true;
    }

    /**
     * Safely check if a date is after the current date
     * Handles various date formats including datetime formats
     */
    private function isDateAfter($dateString)
    {
        if (!$dateString) {
            return false;
        }

        try {
            // First, try to handle standard datetime formats (YYYY-MM-DD HH:MM:SS, YYYY-MM-DD, etc.)
            if (preg_match('/^\d{4}-\d{2}-\d{2}/', $dateString)) {
                // Standard ISO format (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
                $date = \Carbon\Carbon::parse($dateString);
                return now()->isAfter($date);
            }
            
            // Handle ambiguous MM-DD-YYYY or DD-MM-YYYY format (date only, no time)
            elseif (preg_match('/^\d{2}-\d{2}-\d{4}$/', $dateString)) {
                $parts = explode('-', $dateString);
                $firstPart = (int)$parts[0];
                $secondPart = (int)$parts[1];
                $year = (int)$parts[2];
                
                // Smart logic to determine format:
                // If first part > 12, it must be DD-MM-YYYY
                // If second part > 12, it must be MM-DD-YYYY  
                // If both <= 12, prefer DD-MM-YYYY (international standard)
                
                if ($firstPart > 12) {
                    // Must be DD-MM-YYYY format
                    $date = \Carbon\Carbon::createFromFormat('d-m-Y', $dateString);
                    return now()->isAfter($date);
                } elseif ($secondPart > 12) {
                    // Must be MM-DD-YYYY format
                    $date = \Carbon\Carbon::createFromFormat('m-d-Y', $dateString);
                    return now()->isAfter($date);
                } else {
                    // Both <= 12, ambiguous case - prefer DD-MM-YYYY (international standard)
                    $date = \Carbon\Carbon::createFromFormat('d-m-Y', $dateString);
                    return now()->isAfter($date);
                }
            }
            
            // Handle formats with slashes (MM/DD/YYYY or DD/MM/YYYY)
            elseif (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $dateString)) {
                $parts = explode('/', $dateString);
                $firstPart = (int)$parts[0];
                $secondPart = (int)$parts[1];
                
                if ($firstPart > 12) {
                    // Must be DD/MM/YYYY format
                    $date = \Carbon\Carbon::createFromFormat('d/m/Y', $dateString);
                    return now()->isAfter($date);
                } elseif ($secondPart > 12) {
                    // Must be MM/DD/YYYY format
                    $date = \Carbon\Carbon::createFromFormat('m/d/Y', $dateString);
                    return now()->isAfter($date);
                } else {
                    // Both <= 12, ambiguous case - prefer DD/MM/YYYY (international standard)
                    $date = \Carbon\Carbon::createFromFormat('d/m/Y', $dateString);
                    return now()->isAfter($date);
                }
            }
            
            // For any other formats, let Carbon try to parse it
            else {
                $date = \Carbon\Carbon::parse($dateString);
                return now()->isAfter($date);
            }
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::warning("Failed to parse date '{$dateString}' for plan expiry check: " . $e->getMessage());
            return false; // Assume not expired if we can't parse the date
        }
    }

}
