myLogger = \Config\Services::mylogger(); $this->userModel = new UserModel(); $this->roleModel = new RoleModel(); $this->teamModel = new TeamModel(); $this->userTeamsModel = new UserTeamsModel(); $this->bookStack = new BookStackUserHelper(); $this->authHistoryModel = new AuthHistoryModel(); $this->userActivityHistoryModel = new UserActivityHistoryModel(); $this->partnerStaffModel = new PartnerStaffModel(); $this->partnerManagerIncentiveFileModel = new PartnerManagerIncentiveFileModel(); $this->nhanceBranchModel = new NhanceBranchModel(); } public function list() { $data['tab_name'] = 'Users'; $data['page_name'] = 'Users'; $this->myLogger->logme('error','User list function called'); $data['UserList'] = $this->userModel->getUserList(); // echo '
';
        // print_r($data); die;
        $data['roleData'] = $this->roleModel->select('id, role')->findAll();        
        $data['teamData'] = $this->teamModel->select('id, name')->where('is_active',1)->findAll();
        $data['user_data'] = $this->userModel->where('is_active',1)->findAll();
        $data['NHanceBranchData'] = $this->nhanceBranchModel->select('id, branch_name')->where('is_active',1)->findAll();
        $this->loadLayout('UserList', $data);
    }


    public function create()
    {
        $this->myLogger->logme('error', 'User create function called');
        // dd($this->request->getPost());
        $teams = $this->request->getPost('team');

        //if this is get method return to user creation page
        if (!$this->request->getPost()) {
            return redirect()->to(base_url('/user/list'));
        } else {

            // $userData = $this->request->getPost();
            $data      = $this->request->getPost();
            $userData  = sanitizeInputArrayAdvanced($data);
            $rules = [

                // ======================
                // Nhance Branch
                // ======================
                'nhance_branch_id' => [
                    'rules'  => 'required|integer',
                    'errors' => [
                        'required' => 'Nhance Branch is required',
                        'integer'  => 'Invalid Nhance Branch selected'
                    ]
                ],

                // ======================
                // Reporting Manager
                // ======================
                'rm_id' => [
                    'rules'  => 'required|integer',
                    'errors' => [
                        'required' => 'Reporting Manager is required',
                        'integer'  => 'Invalid Reporting Manager selected'
                    ]
                ],

                // ======================
                // Employee Code
                // ======================
                'emp_code' => [
                    'label'  => 'Employee Code',
                    'rules'  => 'required|min_length[3]|max_length[15]|regex_match[/^[a-zA-Z0-9_\-\/]+$/]|is_unique[user_profiles.emp_code]',
                    'errors' => [
                        'required'    => 'Employee Code is required',
                        'min_length'  => 'Employee Code must be at least 3 characters',
                        'max_length'  => 'Employee Code cannot exceed 15 characters',
                        'regex_match' => 'Employee Code can only contain letters, numbers, underscores, hyphens, and forward slashes (/).',
                        'is_unique'   => 'This Employee Code already exists.'
                    ]
                ],

                // ======================
                // First Name
                // ======================
                'first_name' => [
                    'rules'  => 'required|alpha_space|min_length[2]|max_length[100]',
                    'errors' => [
                        'required'    => 'Name is required',
                        'alpha_space' => 'Name can contain only letters and spaces',
                        'min_length'  => 'Name must be at least 2 characters',
                        'max_length'  => 'Name cannot exceed 100 characters'
                    ]
                ],

                // ======================
                // Email
                // ======================
                'email' => [
                    'rules'  => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]|is_unique[user_profiles.email]',
                    'errors' => [
                        'required'    => 'Email address is required.',
                        'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).',
                        'is_unique'   => 'This Email address already exists.'
                    ]
                ],

                // ======================
                // Mobile
                // ======================
                'mobile' => [
                    'rules'  => 'required|regex_match[/^[6-9][0-9]{9}$/]|is_unique[user_profiles.mobile]',
                    'errors' => [
                        'required'     => 'Mobile number is required',
                        'regex_match'  => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9',
                        'is_unique'    => 'This Mobile number already exists.'
                    ]
                ],

                // ======================
                // Role
                // ======================
                'role' => [
                    'rules'  => 'required|integer',
                    'errors' => [
                        'required' => 'User Role is required',
                        'integer'  => 'Invalid User Role selected'
                    ]
                ],

                // ======================
                // Team (Multiple select)
                // ======================
                'team' => [
                    'rules'  => 'required',
                    'errors' => [
                        'required' => 'At least one User Team must be selected'
                    ]
                ],
            ];
           if (!$this->validate($rules)) {
                return redirect()->to(base_url('/user/list'))
                    ->withInput()
                    ->with('errors', $this->validator->getErrors());
            }

            $userData['created_by'] =  get_session_userid();
            $temp_team = $userData['team'];
            unset($userData['team']);

            $insert = $this->userModel->insert($userData);

            // $bookStackData = [
            //     'name' => $userData['first_name'],
            //     'email' => $userData['email'],
                
            // ];
            // $this->bookStack->createEditUser($bookStackData);

            if ($insert) {

                $teamData['user_id'] = $insert;
                foreach ($teams as $value) {
                    $teamData['team_id'] = $value;
                    $teamData['created_by'] =  get_session_userid();
                    $this->userTeamsModel->insert($teamData);
                }

                // $db = \Config\Database::connect();
                // $tableName = 'hdz_staff';
                
                // // Set default values
                // $admin = 0;
                // $acm = 0;
                // $acm_id = null;
                
                // if ($userData['role'] == 3) {
                //     $admin = 0;
                //     $acm = 1;
                //     $acm_id = $insert;
                // } else if (in_array($userData['role'], [1, 5])) {
                //     $admin = 1;
                //     $acm = 0;
                //     $acm_id = null;
                // }
                
                // $password = '12345678'; // Default password
                // $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
                
                // $hdz_staff = [
                //     'emp_code' => $userData['emp_code'],
                //     'fullname' => $userData['first_name'],
                //     'username' => strtolower($userData['first_name']),
                //     'email' => $userData['email'],
                //     'admin' => $admin,
                //     'acm' => $acm,
                //     'acm_id' => $acm_id,
                //     'registration' => time(),
                //     'password' => $hashedPassword,
                //     'active' => 1,
                //     'department' => 'a:7:{i:0;s:1:"1";i:1;s:1:"2";i:2;s:1:"5";i:3;s:1:"3";i:4;s:1:"9";i:5;s:1:"4";i:6;s:2:"10";}',
                // ];
                
                // $db->table($tableName)->insert($hdz_staff);
                
            }
        }
        $this->myLogger->logme('error', 'User create Successfully created by id {data}', ['data' =>  get_session_userid()]);
        return redirect()->to(base_url('/user/list'));
    }

    public function getuser($id = null)
    {
        $userTeamData = $this->userTeamsModel->where('user_id', $id)->findAll();
        $data         = $this->userModel->getUserById($id);
        if($data){
           echo json_encode(array("status" => true , 'data' => $data, 'userTeamData' => $userTeamData));
        }else{
            echo json_encode(array("status" => false));
        }
    }

    public function edit()
    {

        // echo ":/ in 159";  
        if (!$this->request->getPost()) {
            return redirect()->to(base_url('/user/list'));
        } else {
            
            $data      = $this->request->getPost();
            $userData  = sanitizeInputArrayAdvanced($data);
            $id = $userData['PrimaryKey'];
            $rules = [

                // ======================
                // Nhance Branch
                // ======================
                'nhance_branch_id' => [
                    'rules'  => 'required|integer',
                    'errors' => [
                        'required' => 'Nhance Branch is required',
                        'integer'  => 'Invalid Nhance Branch selected'
                    ]
                ],

                // ======================
                // Reporting Manager
                // ======================
                'rm_id' => [
                    'rules'  => 'required|integer',
                    'errors' => [
                        'required' => 'Reporting Manager is required',
                        'integer'  => 'Invalid Reporting Manager selected'
                    ]
                ],

                // ======================
                // Employee Code
                // ======================
                'emp_code' => [
                    'rules'  => "required|min_length[3]|max_length[15]|regex_match[/^[a-zA-Z0-9_\-\/]+$/]|is_unique[user_profiles.emp_code,id,{$id}]",
                    'errors' => [
                        'required'    => 'Employee Code is required',
                        'min_length'  => 'Employee Code must be at least 3 characters',
                        'max_length'  => 'Employee Code cannot exceed 15 characters',
                        'regex_match' => 'Employee Code can only contain letters, numbers, underscores, hyphens, and forward slashes (/).',
                        'is_unique'   => 'This Employee Code already exists.'
                    ]
                ],

                // ======================
                // First Name
                // ======================
                'first_name' => [
                    'rules'  => 'required|alpha_space|min_length[2]|max_length[100]',
                    'errors' => [
                        'required'    => 'Name is required',
                        'alpha_space' => 'Name can contain only letters and spaces',
                        'min_length'  => 'Name must be at least 2 characters',
                        'max_length'  => 'Name cannot exceed 100 characters'
                    ]
                ],

                // ======================
                // Email
                // ======================
                'email' => [
                    'rules'  => "required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]|is_unique[user_profiles.email,id,{$id}]",
                    'errors' => [
                        'required'    => 'Email address is required.',
                        'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).',
                        'is_unique'   => 'This Email address already exists.'
                    ]
                ],

                // ======================
                // Mobile
                // ======================
                'mobile' => [
                    'rules'  => "required|regex_match[/^[6-9][0-9]{9}$/]|is_unique[user_profiles.mobile,id,{$id}]",
                    'errors' => [
                        'required'     => 'Mobile number is required',
                        'regex_match'  => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9',
                        'is_unique'    => 'This Mobile number already exists.'
                    ]
                ],

                // ======================
                // Role
                // ======================
                'role' => [
                    'rules'  => 'required|integer',
                    'errors' => [
                        'required' => 'User Role is required',
                        'integer'  => 'Invalid User Role selected'
                    ]
                ],

                // ======================
                // Team (Multiple select)
                // ======================
                'team' => [
                    'rules'  => 'required',
                    'errors' => [
                        'required' => 'At least one User Team must be selected'
                    ]
                ],
            ];
            if (!$this->validate($rules)) {
                return redirect()->to(base_url('/user/list'))
                    ->withInput()
                    ->with('errors', $this->validator->getErrors());
            }
            
            $data      = $this->request->getPost();
            $userData  = sanitizeInputArrayAdvanced($data);
            $id = $userData['PrimaryKey'];
            $teams = $userData['team'];
            
            unset($userData['csrf_test_name']);
            unset($userData['PrimaryKey']);

            $existingData = $this->userModel->where('id',$id)->first();;
            // dd($existingData);die;

            // Update data in the 'users' table based on the $id
            $userData['updated_by'] =  get_session_userid();
            $update = $this->userModel->where('id', $id)->set($userData)->update();

            // $bookStackData = [
            //     'name' => $userData['first_name'],
            //     'email' => $userData['email'],
            // ];

            // $this->bookStack->createEditUser($bookStackData,$existingData);


            if ($update) {

                if ($teams) {
                    $this->userTeamsModel->where('user_id', $id)->delete();
                    $teamData['user_id'] = $id;
                    foreach ($teams as $value) {
                        $teamData['team_id'] = $value;
                        $teamData['created_by'] =  get_session_userid();
                        $this->userTeamsModel->insert($teamData);
                    }
                }

            //     $db = \Config\Database::connect();
            //     $tableName = 'hdz_staff';
                
            //     $hdz_staff = [
            //         'emp_code' => $userData['emp_code'],
            //         'fullname' => $userData['first_name'],
            //         'username' => strtolower($userData['first_name']),
            //         'email' => $userData['email'],
            //         'registration' => time(),
            //         'active' => 1,
            //         'department' => 'a:7:{i:0;s:1:"1";i:1;s:1:"2";i:2;s:1:"5";i:3;s:1:"3";i:4;s:1:"9";i:5;s:1:"4";i:6;s:2:"10";}',
            //     ];
                
            //     if ($userData['role'] == 3) {
            //         $hdz_staff['admin'] = 0;
            //         $hdz_staff['acm'] = 1;
            //         $hdz_staff['acm_id'] = $id;
            //     } elseif (in_array($userData['role'], [1, 5])) {
            //         $hdz_staff['admin'] = 1;
            //         $hdz_staff['acm'] = 0;
            //         $hdz_staff['acm_id'] = null;
            //     } else {
                    
            //         return redirect()->to(base_url('/user/list'));
            //     }
                
            //     // Check if staff data exists
            //     $staffData = $db->table($tableName)
            //         // ->where('emp_code', $userData['emp_code'])
            //         ->where('email', $userData['email'])
            //         ->get()->getResult();
                
            //     if (!empty($staffData)) {

            //         // Update existing record
            //         $db->table($tableName)
            //             // ->where('emp_code', $userData['emp_code'])
            //             ->where('email', $userData['email'])
            //             ->set($hdz_staff)->update();

            //     } else {

            //         $password = '12345678'; // Default password
            //         $hdz_staff['password'] = password_hash($password, PASSWORD_DEFAULT);
                
            //         // Insert new record
            //         $db->table($tableName)->insert($hdz_staff);
            //     }
                
            }

            return redirect()->to(base_url('/user/list'));
        }
    }

    public function deactive($id = null)
    {   
        $model = new UserModel();

        $emailToDelete = $model->where('id', $id)->first();
        $deactive = $model->where('id', $id)->set(['is_active' => 0])->update();

        // $this->bookStack->deleteUser($emailToDelete);
        if($deactive)
        {
            // $db = \Config\Database::connect();
            // $tableName = 'hdz_staff'; 

            // $db->table($tableName)->insert($hdz_staff);
                 

           echo json_encode(array("status" => true));
        }else{
           echo json_encode(array("status" => false));
        }
    }

    public function activateUser($id = null)
    {   
        $model = new UserModel();

        $emailToDelete = $model->where('id', $id)->first();
        $deactive = $model->where('id', $id)->set(['is_active' => 1])->update();

        // $this->bookStack->deleteUser($emailToDelete);
        if($deactive)
        {
            // $db = \Config\Database::connect();
            // $tableName = 'hdz_staff'; 

            // $db->table($tableName)->insert($hdz_staff);
                 

           echo json_encode(array("status" => true));
        }else{
           echo json_encode(array("status" => false));
        }
    }

    public function getRolesAndTeams()
    {
        $roleData = $this->roleModel->select('id, role')->findAll();
        $teamData = $this->teamModel->select('id, name')->findAll();
        echo json_encode(array("status" => true , 'roleData' => $roleData, 'teamData' => $teamData,));
    }


    // public function getUserActivityHistory()
    // {
    //     $user_id = $this->request->getVar('user_id');
    //     $pre_hr_id = $this->request->getVar('pre_hr_id');
    //     $user_type = $this->request->getVar('user_type');

    //     // echo $user_id.' - '.$pre_hr_id;
    //     $field_for_where_condition = 'user_id';
    //     if($user_id == 0 || $user_id == NULL)
    //     {
    //         $field_for_where_condition = 'pre_hr_id';
    //         $user_id = $pre_hr_id;
    //     }

    //     if($field_for_where_condition == "pre_hr_id"){
    //         //get login history
    //         $auth_data =  $this->authHistoryModel->where('is_active', 1)->where('user_id',$user_id)->where('user_type', $user_type)->findAll();
    //     }else{
    //         $preDB = \Config\Database::connect('preDB');
    //         $auth_data = $preDB->table('auth_history')->where('is_active', 1)->where('user_id',$user_id)->where('user_type', $user_type)->get()->getResultArray();
    //     }

    //     //get activity history
    //     $activity_data = $this->userActivityHistoryModel->where($field_for_where_condition,$user_id)->where('user_type', $user_type)->findAll();

    // }


    // public function getUserActivityHistory()
    // {
    //     try {
    //         $client_id   = $this->request->getVar('client_id');
    //         $user_id   = $this->request->getVar('user_id');
    //         $pre_hr_id = $this->request->getVar('pre_hr_id');
    //         $user_type = $this->request->getVar('user_type');

    //         $clientController = new ClientController;

    //         if (empty($client_id)) {
    //             return $this->respond(['status'  => false,'message' => 'Client Id is required'], 400);
    //         }

    //         if (empty($user_type)) {
    //             return $this->respond(['status'  => false,'message' => 'User type is required'], 400);
    //         }

    //         $field_for_where_condition = 'user_id';

    //         if (empty($user_id) || $user_id == 0) {
    //             if (empty($pre_hr_id)) {
    //                 return $this->respond(['status'  => false,'message' => 'user_id or pre_hr_id must be provided'], 400);
    //             }

    //             $field_for_where_condition = 'pre_hr_id';
    //             $user_id = $pre_hr_id;
    //         }

    //         // Get login/auth history
    //         if ($field_for_where_condition == 'user_id') {
    //             $auth_data = $this->authHistoryModel
    //                 ->where('is_active', 1)
    //                 ->where('user_id', $user_id)
    //                 ->where('user_type', $user_type)
    //                 ->orderBy('created_at', 'desc')
    //                 ->findAll();
    //             // print_r(db_connect()->getLastQuery()); die;
    //         } else {
    //             $preDB = \Config\Database::connect('preDB');
    //             $auth_data = $preDB->table('auth_history')
    //                 ->where('is_active', 1)
    //                 ->where('user_id', $user_id)
    //                 ->where('user_type', $user_type)
    //                 ->orderBy('created_at', 'desc')
    //                 ->get()
    //                 ->getResultArray();
    //         }

    //         // Get activity history
    //         $activity_data = $this->userActivityHistoryModel
    //             ->where($field_for_where_condition, $user_id)
    //             ->where('user_type', $user_type)
    //             ->findAll();

    //         $merged_data = $this->getMergedUserHistory($auth_data, $activity_data);

    //         return $this->respond([
    //             'status'        => true,
    //             'message'       => 'User history fetched successfully',
    //             'auth_history'  => $auth_data,
    //             'activity_log'  => $activity_data,
    //             'merged_data'   => $merged_data,
    //         ]);

    //     } catch (\Exception $e) {
    //         $this->myLogger->logme("error", ($e->getMessage().' --- '.$e->getLine() . '----' . $e->getTraceAsString()));
    //         return $this->respond([
    //             'status'  => false,
    //             'message' => 'Error: ' . $e->getMessage()
    //         ], 500);
    //     }
    // }    
    
    public function getUserActivityHistory()
    {
        try {
            $this->myLogger->logme("error", "User activity history fetch initiated.");

            $client_id = $this->request->getVar('client_id');
            $startDate = $this->request->getVar('startDate');
            $endDate = $this->request->getVar('endDate');
            $user_type = 'hr';
            $clientController = new ClientController;

            // Convert to DB format with full time range
            $startDateTime = null;
            $endDateTime = null;

            if (!empty($startDate)) {
                $startDateTime = \DateTime::createFromFormat('d-m-Y', $startDate)->format('Y-m-d 00:00:00');
                $endDateTime   = \DateTime::createFromFormat('d-m-Y', $endDate)->format('Y-m-d 23:59:59');
            }


            $this->myLogger->logme("error", "Received client_id: " . $client_id);

            if (empty($client_id)) {
                $this->myLogger->logme("warning", "Client ID is missing.");
                return $this->respond(['status' => false, 'message' => 'Client Id is required'], 400);
            }

            $hr_access_data = $clientController->getHrAccessData($client_id)['hr_access_data'] ?? [];
            $this->myLogger->logme("error", "Fetched HR access data: " . json_encode($hr_access_data));

            if (empty($hr_access_data)) {
                $this->myLogger->logme("error", "No HR access data found for client_id: $client_id");
                $html = view('hr_activity_history');
                return $this->respond(['status' => true, 'data' => $html, 'list_of_activity_data' => []], 200);
            }

            $activityMap = [
                'export_empdata'       => 'Exporting post employee data',
                'export_cddata'        => 'Exporting cd data',
                'export_cdsummary'     => 'Exporting cd summary data',
                'export_preempdata'    => 'Exporting pre employee data',
                'import_enrollempdata' => 'Import enrolment file',
            ];

            $list_of_activity_data = [];

            foreach ($hr_access_data as $key => $value) {
                $this->myLogger->logme("error", "Processing HR user: " . json_encode($value));

                $auth_data = [];
                $activity_data = [];

                $hr_name = $value['hr_name'] ?? '';
                $hr_mail = $value['hr_mail'] ?? '';

                if (!empty($value['pre_hr_id']) && !empty($value['post_hr_id'])) {
                    $this->myLogger->logme("error", "Both pre_hr_id and post_hr_id found. Using post DB for user_id: {$value['post_hr_id']}");

                    // Fetch Auth History
                    $auth_query = $this->authHistoryModel
                        ->select("DATE_FORMAT(created_at, '%d-%m-%Y %r') AS created_at")
                        ->where('is_active', 1)
                        ->where('user_id', $value['post_hr_id'])
                        ->where('user_type', $user_type);

                    if (!empty($startDate)) {
                        $auth_query->where('created_at >=', $startDateTime)
                                ->where('created_at <=', $endDateTime);
                    }

                    $auth_data = $auth_query->orderBy('created_at', 'desc')->findAll();


                    // Fetch User Activity
                    $activity_query = $this->userActivityHistoryModel
                        ->select("DATE_FORMAT(created_at, '%d-%m-%Y %r') AS created_at, activity")
                        ->where('user_id', $value['post_hr_id'])
                        ->where('user_type', $user_type);

                    if (!empty($startDate)) {
                        $activity_query->where('created_at >=', $startDateTime)
                                    ->where('created_at <=', $endDateTime);
                    }

                    $activity_data = $activity_query->findAll();


                } elseif (!empty($value['post_hr_id'])) {
                    $this->myLogger->logme("error", "Only post_hr_id found. user_id: {$value['post_hr_id']}");

                    $auth_query = $this->authHistoryModel
                        ->select("DATE_FORMAT(created_at, '%d-%m-%Y %r') AS created_at")
                        ->where('is_active', 1)
                        ->where('user_id', $value['post_hr_id'])
                        ->where('user_type', $user_type);

                    if (!empty($startDate)) {
                        $auth_query->where('created_at >=', $startDateTime)
                                ->where('created_at <=', $endDateTime);
                    }

                    $auth_data = $auth_query->orderBy('created_at', 'desc')->findAll();

                    $activity_query = $this->userActivityHistoryModel
                        ->select("DATE_FORMAT(created_at, '%d-%m-%Y %r') AS created_at, activity")
                        ->where('user_id', $value['post_hr_id'])
                        ->where('user_type', $user_type);

                    if (!empty($startDate)) {
                        $activity_query->where('created_at >=', $startDateTime)
                                    ->where('created_at <=', $endDateTime);
                    }

                    $activity_data = $activity_query->findAll();

                } elseif (!empty($value['pre_hr_id'])) {
                    $this->myLogger->logme("error", "Only pre_hr_id found. user_id: {$value['pre_hr_id']}");

                    $preDB = \Config\Database::connect('preDB');

                    $auth_query = $preDB->table('auth_history')
                        ->select("DATE_FORMAT(created_at, '%d-%m-%Y %r') AS created_at")
                        ->where('is_active', 1)
                        ->where('user_id', $value['pre_hr_id'])
                        ->where('user_type', $user_type);

                    if (!empty($startDate)) {
                        $auth_query->where('created_at >=', $startDateTime)
                                ->where('created_at <=', $endDateTime);
                    }

                    $auth_data = $auth_query->orderBy('created_at', 'desc')->get()->getResultArray();

                    $activity_query = $this->userActivityHistoryModel
                        ->select("DATE_FORMAT(created_at, '%d-%m-%Y %r') AS created_at, activity")
                        ->where('pre_hr_id', $value['pre_hr_id'])
                        ->where('user_type', $user_type);

                    if (!empty($startDate)) {
                        $activity_query->where('created_at >=', $startDateTime)
                                    ->where('created_at <=', $endDateTime);
                    }

                    $activity_data = $activity_query->findAll();
                }

                foreach ($auth_data as &$entry) {
                    $entry['user_name'] = $hr_name;
                    $entry['user_mail'] = $hr_mail;
                    $entry['activity'] = "Login";
                }

                foreach ($activity_data as &$entry) {
                    $entry['user_name'] = $hr_name;
                    $entry['user_mail'] = $hr_mail;

                    if (!empty($entry['activity']) && isset($activityMap[$entry['activity']])) {
                        $entry['activity'] = $activityMap[$entry['activity']];
                    }
                }

                $merged_data = array_merge($auth_data, $activity_data);
                $list_of_activity_data = array_merge($list_of_activity_data, $merged_data);

                $this->myLogger->logme("error", "Merged data count after processing: " . count($list_of_activity_data));
            }

            usort($list_of_activity_data, function ($a, $b) {
                return strtotime($b['created_at']) <=> strtotime($a['created_at']);
            });

            $this->myLogger->logme("error", "Final sorted list_of_activity_data count: " . count($list_of_activity_data));

            $html = view('hr_activity_history', ['data' => $list_of_activity_data]);

            return $this->respond([
                'status'        => true,
                'message'       => 'User history fetched successfully',
                'data'          => $html,
                'list_of_activity_data' => $list_of_activity_data,
            ]);

        } catch (\Exception $e) {
            $this->myLogger->logme("error", $e->getMessage() . ' --- ' . $e->getLine() . ' ---- ' . $e->getTraceAsString());
            return $this->respond([
                'status'  => false,
                'message' => 'Error: ' . $e->getMessage()
            ], 500);
        }
    }

    public function partner()
    {
        $method = $this->request->getMethod(); // get, post
        try{
            // Listing
            if ($method === 'get') {  
                $manager = $this->partnerStaffModel->where('role_id',1)->findAll();
                if (empty($manager)) {
                    return $this->response->setJSON(['status'  => 'error','message' => 'No Manager found'])->setStatusCode(404);
                }
                return $this->response->setJSON(['status' => 'success','data'   => $manager])->setStatusCode(200);
            } 
            
            // add/update
            if ($method === 'post') {

                $rules = [
                    // ======================
                    // Partner Name
                    // ======================
                    'name' => [
                        'rules'  => 'required|alpha_space|min_length[2]|max_length[100]',
                        'errors' => [
                            'required'    => 'Partner name is required',
                            'alpha_space' => 'Partner name can contain only letters and spaces',
                            'min_length'  => 'Partner name must be at least 2 characters',
                            'max_length'  => 'Partner name cannot exceed 100 characters'
                        ]
                    ],
                    // ======================
                    // Mobile Number
                    // ======================
                    'mobile' => [
                        'rules'  => 'required|regex_match[/^[6-9][0-9]{9}$/]',
                        'errors' => [
                            'required'    => 'Mobile number is required',
                            'regex_match' => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9',
                        ]
                    ],

                    // ======================
                    // Email
                    // ======================
                    'email' => [
                        'rules'  => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
                        'errors' => [
                            'required'    => 'Email address is required.',
                            'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
                        ]
                    ],
                    // ======================
                    // Retention Rate
                    // ======================
                     'retention_rate' => [
        'rules'  => [
            'required',
            'regex_match[/^(100(\.0{1,2})?|([0-9]{1,2})(\.[0-9]{1,2})?)$/]'
        ],
        'errors' => [
            'required'    => 'Retention Rate is required',
            'regex_match' => 'Retention Rate must be between 0 to 100 with up to 2 decimal places'
        ]
        ],
                    // ======================
                    // Nhance Branch
                    // ======================
                    'nhance_branch_id' => [
                        'rules'  => 'required|integer',
                        'errors' => [
                            'required' => 'Nhance Branch is required',
                            'integer'  => 'Invalid Nhance Branch selected'
                        ]
                    ],
                ];
                if (! $this->validate($rules)) {
                return $this->response->setStatusCode(400)->setJSON([
                    'status'  => false,
                    'message' => 'Input validation failed',
                    'code'    => 400,
                    'errors'  => $this->validator->getErrors()
                ]);
            }


                $data           = $this->request->getPost();
                $sanitized_post_data = sanitizeInputArrayAdvanced($data);
                $id = !empty($sanitized_post_data['PrimaryKey']) ? $sanitized_post_data['PrimaryKey'] : null;
                unset($sanitized_post_data['pk']); 
                
                // don't forgot same means just unset the key because partner_staff some UNIQUE KEY sets in table thats why
                if ($id) {
                    $existing = $this->partnerStaffModel->find((int)$id);
                    if ($existing) {
                        if ($sanitized_post_data['email'] === $existing['email']) { unset($sanitized_post_data['email']); }
                        if ($sanitized_post_data['mobile'] === $existing['mobile']) { unset($sanitized_post_data['mobile']); }
                    }
                }

                $errors = [];

                // Check Email Duplicate (if it wasn't unset)
                if (isset($sanitized_post_data['email'])) {
                    $count = $this->partnerStaffModel->where('email', $sanitized_post_data['email'])->countAllResults();
                    if ($count > 0) $errors['email'] = "This email is already taken by another user.";
                }

                // Check Mobile Duplicate (if it wasn't unset)
                if (isset($sanitized_post_data['mobile'])) {
                    $count = $this->partnerStaffModel->where('mobile', $sanitized_post_data['mobile'])->countAllResults();
                    if ($count > 0) $errors['mobile'] = "This mobile is already taken by another user.";
                }

                // If there are duplicates, stop and return error
                if (!empty($errors)) {
                    return $this->response->setJSON([
                        'status'  => 'error',
                        'message' => 'Duplicate detected',
                        'errors'  => $errors
                    ])->setStatusCode(400);
                }

                // --- Save/Update ---
                if ($id) {
                    $text   = "update";            
                    $sanitized_post_data['updated_by'] =  get_session_userid();
                    
                    $result = $this->partnerStaffModel->update($id, $sanitized_post_data);
                } else {
                    $text = "create";
                    $sanitized_post_data['role_id'] = 1;
                    $sanitized_post_data['created_by'] = get_session_userid();
                    $id = $this->partnerStaffModel->insert($sanitized_post_data);
                    if($id){
                        $details['manager_id'] = $id;
                        $details['updated_by'] =  get_session_userid();
                        $this->partnerStaffModel->update($id, $details);
                    }
                    $result = true;
                    
                }

                 

                return $this->response->setJSON([ 
                    'status'  => $id ? 'success' : 'error',
                    'message' => $id ? "Staff {$text}d successfully" : "Unable to {$text} staff. Please try again.",
                    'id'      => $id
                ])->setStatusCode($id ? 200 : 400);

            }
            // delete
            if ($method === 'put') {
                    $data = $this->request->getRawInput();
                    $id   = $data['id'] ?? null;

                    if (!$id) {
                        return $this->response->setJSON(['status'  => 'error', 'message' => 'ID is required'])->setStatusCode(400);
                    }

                    $staff = $this->partnerStaffModel->find((int)$id);
                    if (!$staff) {
                        return $this->response->setJSON(['status'  => 'error','message' => 'Staff not found'])->setStatusCode(404);
                    }
                    $role = $staff['role_id'];
                    $text = $role == 1 ? "Manager" : "Staff";

                    if ($staff['is_active'] == 1) {
                      if($role == 1){  // manager 
                        $result = $this->partnerStaffModel->updateByKey($id);
                        $message = $result;
                      }else{ // staff
                        $result = $this->partnerStaffModel->update($id, ['is_active' => 0]);
                        $message = $text." deleted successfully";
                      }
                    } else {
                        return $this->response->setJSON(['status'  => 'error','message' => $text.' already deleted'])->setStatusCode(400);
                    }

                    return $this->response->setJSON([
                        'status'  => $result ? 'success' : 'error',
                        'message' => $result ? $message : "Unable to delete ".$text.". Please try again.",
                        'id'      => $id
                    ])->setStatusCode($result ? 200 : 400);
            }
            return $this->response->setJSON([ 'status'  => 'error', 'message' => 'Invalid request method' ])->setStatusCode(405);
        } 
            catch (\Throwable $e) {
                $code = ($e->getCode() && $e->getCode() >= 100 && $e->getCode() < 600) ? $e->getCode() : 500;

                $isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException 
                            || $e instanceof \mysqli_sql_exception 
                            || $e instanceof \PDOException;

                $context = ['title'   => get_class($e),'type'    => get_class($e),'code'    => $code,'message' => $e->getMessage(),'file'    => $e->getFile(),'line'    => $e->getLine()];

                $this->myLogger->logme('error', "Exception: {message} in {file} on line {line}", $context, 0);
    
                return $this->response->setJSON([ 'status'  => 'error', 'message' => $isDbError ? 'Data Access Error' : $e->getMessage(),
                                                'ref'     => $isDbError ? 'database - ' : 'application - ' . $code . ' - ' . $e->getLine()
                ])->setStatusCode($code);
            }
    }
    
    public function partnerIncentive()
    {
        $method = $this->request->getMethod(); // get, post
        try{
            // Listing
            if ($method === 'get') {  
                $manager_id = $this->request->getGet('manager_id');
                $files = $this->partnerManagerIncentiveFileModel->where('manager_id', $manager_id)->findAll();
                if (empty($files)) {
                    return $this->response->setJSON(['status'  => 'error','message' => 'No Records found'])->setStatusCode(404);
                }
                return $this->response->setJSON(['status' => 'success','data'   => $files])->setStatusCode(200);
            } 
            
            // add/update
            if ($method === 'post') {
    
                $file = $this->request->getFile('incentive_file_name');
                $month = $this->request->getPost('incentive_month');
                $managerId = $this->request->getPost('manager_id');
                $fileId = $this->request->getPost('id');

                if ($file && $file->isValid() && !$file->hasMoved()) {

                        if (!validate_upload_extension($file, UPLOAD_EXT_EXCEL)) {
                            return $this->response->setJSON([
                                'status'  => 'error',
                                'message' => 'Only Excel files (xls, xlsx, ods, csv) are allowed.',
                            ])->setStatusCode(400);
                        }

                        $originalName = sanitize_upload_filename($file->getClientName());
                        $extension    = $file->getExtension();  

                        $fileName = pathinfo($originalName, PATHINFO_FILENAME) . '_' . date('Ymd_His') . '.' . $extension;

                        $path = WRITEPATH . 'uploads/incentives';
                        $file->move($path, $fileName);
                        $data = [
                            'manager_id' => $managerId,
                            'incentive_month' => date('M Y', strtotime($month)),
                            'incentive_file_name' => $fileName,
                            'created_by' =>   get_session_userid()
                        ];

                        if ($fileId) {
                            $text   = "update";            
                            $this->partnerManagerIncentiveFileModel->update($fileId, $data);
                            $updateID = $data['id'];
                        } else {
                            $text   = "create";        
                            $insertID  = $this->partnerManagerIncentiveFileModel->insert($data);
                            $result = true;
                        }

                        $id = isset($insertID) && !empty($insertID) ? $insertID : ($updateID ?? null);

                        return $this->response->setJSON([ 
                            'status'  => $id ? 'success' : 'error',
                            'message' => $id ? "File {$text}d successfully" : "Unable to {$text} file. Please try again.",                            
                            'id'      => $id
                        ])->setStatusCode($id ? 200 : 400);
                }
                        return $this->response->setJSON([ 
                            'status'  => 'error',
                            'message' => "Unable to Upload file. Please try again.",
                            'id'      => ''
                        ])->setStatusCode(400);
            }

            // delete
            if ($method === 'put') {
                    $data = $this->request->getRawInput();
                    $id   = $data['id'] ?? null;

                    if (!$id) {
                        return $this->response->setJSON(['status'  => 'error', 'message' => 'ID is required'])->setStatusCode(400);
                    }

                    $files = $this->partnerManagerIncentiveFileModel->find((int)$id);
                    if (!$files) {
                        return $this->response->setJSON(['status'  => 'error','message' => 'No Records found'])->setStatusCode(404);
                    }

                    if ($files['is_active'] == 1) {
                        $result = $this->partnerManagerIncentiveFileModel->update($id, ['is_active' => 0]);
                        $message = "Files deleted successfully";
                    } else {
                        return $this->response->setJSON(['status'  => 'error','message' => 'files already deleted'])->setStatusCode(400);
                    }

                    return $this->response->setJSON([
                        'status'  => $result ? 'success' : 'error',
                        'message' => $result ? $message : "Unable to delete staff. Please try again.",
                        'id'      => $id
                    ])->setStatusCode($result ? 200 : 400);
            }
            return $this->response->setJSON([ 'status'  => 'error', 'message' => 'Invalid request method' ])->setStatusCode(405);
        } 
            catch (\Throwable $e) {
                $code = ($e->getCode() && $e->getCode() >= 100 && $e->getCode() < 600) ? $e->getCode() : 500;

                $isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException 
                            || $e instanceof \mysqli_sql_exception 
                            || $e instanceof \PDOException;

                $context = ['title'   => get_class($e),'type'    => get_class($e),'code'    => $code,'message' => $e->getMessage(),'file'    => $e->getFile(),'line'    => $e->getLine()];

                $this->myLogger->logme('error', "Exception: {message} in {file} on line {line}", $context, 0);
    
                return $this->response->setJSON([ 'status'  => 'error', 'message' => $isDbError ? 'Data Access Error' : $e->getMessage(),
                                                'ref'     => $isDbError ? 'database - ' : 'application - ' . $code . ' - ' . $e->getLine()
                ])->setStatusCode($code);
            }
    }

    // public function downloadIncentivesFile($file_id)
    // {
    //     try {
    //         $result = $this->partnerManagerIncentiveFileModel->where('id', $file_id)->first();

    //         if (!$result || empty($result['incentive_file_name'])) {
    //             throw new \Exception("File Name Not Found");
    //         }

    //         $incentive_file_name = $result['incentive_file_name'];
    //         $file_name = basename($incentive_file_name);
    //         $filePath = WRITEPATH . 'uploads/incentives/' . $file_name;

    //         if (file_exists($filePath)) {
    //             return $this->response->download($filePath, null);
    //         } else {
    //             throw new \Exception("File Not Found");
    //         }

    //     } catch (\Exception $e) {
            
    //         $this->myLogger->logme('error', $e->getMessage());

    //         // Show 404 error view
    //         $data['message'] = $e->getMessage();
    //         return view('errors/404', $data);
    //     }
    // }

    public function downloadIncentivesFile($file_id)
    {
        try {
            $result = $this->partnerManagerIncentiveFileModel->where('id', $file_id)->first();

            if (!$result || empty($result['incentive_file_name'])) {
                throw new \Exception("File Name Not Found for ID {$file_id}");
            }

            $incentive_file_name = $result['incentive_file_name'];
            $file_name = basename($incentive_file_name);
            $filePath = WRITEPATH . 'uploads/incentives/' . $file_name;

            if (!file_exists($filePath)) {
                throw new \Exception("File Not Found: {$file_name}");
            }

            return $this->response->download($filePath, null);
        } catch (\Throwable $e) {
            // Catch all kinds of exceptions
            $this->myLogger->logme('error', $e->getMessage());

            // Return proper 404 for missing file, else 500 for unexpected error
            if (str_contains($e->getMessage(), 'Not Found')) {
                return $this->response->setStatusCode(404)->setBody($e->getMessage());
            }

            return $this->response->setStatusCode(500)->setBody('Internal Server Error');
        }
    }

}