<?php

namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
use App\Controllers\BaseController;
use App\Models\StaffModel;
use App\Models\ManagerIncentiveFileModel;

class StaffController extends ResourceController
{
    protected $db;
    protected $StaffModel;
    protected $ManagerIncentiveFileModel;

    public function __construct()
    {
        $this->db = \Config\Database::connect();
        $this->StaffModel = new StaffModel();
        $this->ManagerIncentiveFileModel = new ManagerIncentiveFileModel();
    }

    // List of all Staffs
    public function staffList()
    {
        try{
            $manager_id = $this->request->getGet('manager_id');
            $handler_id = $this->request->getGet('handler_id');

            if(!empty($manager_id))
            {
                $data = $this->StaffModel->select('partner_staff.* , R.role')
                ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                ->where('partner_staff.manager_id' , $manager_id )
                ->whereIn('partner_staff.role_id' , [1,2,3,4] )
                ->findAll();

            }else if(!empty($handler_id)){

                $data = $this->StaffModel->select('partner_staff.* , R.role')
                ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                ->where("JSON_CONTAINS(partner_staff.handler_id, '\"$handler_id\"')")
                // ->where('partner_staff.handler_id' , $handler_id )
                ->findAll();
            }
           

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => $data], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
       
    }

    public function staffListForEnquiryAssignDropdown()
    {
        try{
            $handler_id = $this->request->getGet('handler_id');
            $manager_id = $this->request->getGet('manager_id');

            $data = [];

            if(!empty($manager_id))
            {

                $staffData = $this->db->table('partner_staff ps')
                                            ->select("
                                                ps.id,
                                                ps.name,
                                                R.role,

                                                -- today's assigned count
                                                SUM(CASE WHEN DATE(pe.created_on) = CURDATE() THEN 1 ELSE 0 END) AS today_assigned,

                                                -- not completed today
                                                SUM(CASE WHEN pe.enquiry_status != 'Completed' 
                                                        AND DATE(pe.created_on) = CURDATE()
                                                    THEN 1 ELSE 0 END) AS total_pending
                                            ")
                                            ->join('partner_role_master R', 'R.id = ps.role_id', 'left')
                                            ->join('partner_enquiry pe', 'pe.assigned_to = ps.id AND pe.is_active = 1', 'left')
                                            ->where('ps.manager_id', $manager_id)
                                            ->groupStart()
                                                ->whereIn('ps.role_id', [2,3])
                                                ->orWhere('ps.id', $manager_id)
                                            ->groupEnd()
                                            ->where('ps.is_active', 1)
                                            ->groupBy('ps.id')
                                            ->orderBy('ps.name', 'ASC')
                                            ->get()
                                            ->getResultArray();

                // $staffData = $this->StaffModel->select('partner_staff.id, partner_staff.name , R.role')
                //                         ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                //                         ->where('partner_staff.manager_id' , $manager_id )
                //                         ->where('partner_staff.role_id' , 3 )
                //                         ->where('partner_staff.is_active' , 1 )
                //                         ->findAll();
                // $managerData = $this->StaffModel->select('partner_staff.id, partner_staff.name , R.role')
                //                         ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                //                         ->where('partner_staff.id', $manager_id )
                //                         ->where('partner_staff.is_active' , 1 )
                //                         ->first();
                //  $data = array_values(array_unique(array_merge($staffData, [$managerData]), SORT_REGULAR));

            }else if(!empty($handler_id)){


                $staffData = $this->db->table('partner_staff ps')
                                            ->select("
                                                ps.id,
                                                ps.name,
                                                R.role,

                                                -- today's assigned count
                                                SUM(CASE WHEN DATE(pe.created_on) = CURDATE() THEN 1 ELSE 0 END) AS today_assigned,

                                                -- not completed today
                                                SUM(CASE WHEN pe.enquiry_status != 'Completed' 
                                                        AND DATE(pe.created_on) = CURDATE()
                                                    THEN 1 ELSE 0 END) AS total_pending
                                            ")
                                            ->join('partner_role_master R', 'R.id = ps.role_id', 'left')
                                            ->join('partner_enquiry pe', 'pe.assigned_to = ps.id AND pe.is_active = 1', 'left')
                                            
                                            ->groupStart()
                                                ->where("JSON_CONTAINS(ps.handler_id, '\"$handler_id\"')")
                                                ->orWhere('ps.id', $handler_id)
                                            ->groupEnd()
                                            ->where('ps.is_active', 1)
                                            ->groupBy('ps.id')
                                            ->orderBy('ps.name', 'ASC')
                                            ->get()
                                            ->getResultArray();

                // $staffData = $this->StaffModel->select('partner_staff.id, partner_staff.name , R.role')
                //                         ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                //                         ->where("JSON_CONTAINS(partner_staff.handler_id, '\"$handler_id\"')")
                //                         ->where('partner_staff.role_id' , 3 )
                //                         ->where('partner_staff.is_active' , 1 )
                //                         ->findAll();
                // $handlerData = $this->StaffModel->select('partner_staff.id, partner_staff.name , R.role')
                //                         ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                //                         ->where('partner_staff.id', $handler_id )
                //                         ->where('partner_staff.is_active' , 1 )
                //                         ->first();
                //  $data = array_values(array_unique(array_merge($staffData, [$handlerData]), SORT_REGULAR));
            }

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => $staffData], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
        
    }

    public function handlerListForStaffCreationDropdown()
    {
        try{
            $manager_id = $this->request->getGet('manager_id');

            $data = $this->StaffModel->select('partner_staff.id, partner_staff.name , R.role')
                                    ->join('partner_role_master R', 'R.id = partner_staff.role_id', 'left')
                                    ->where('partner_staff.manager_id' , $manager_id )
                                    ->where('partner_staff.role_id' , 2 )
                                    ->where('partner_staff.is_active' , 1 )
                                    ->findAll();

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => $data], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
        
    }

    // Find a Staff
    public function findStaff()
    {
        try{

            $id = $this->request->getGet('id');

            $record = $this->StaffModel->find((int)$id);

            if (!$record) {
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200);
            }

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => $record], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
    }

    // CREATE Staff
    public function createStaff()
    {
        try{
            $data = $this->request->getJSON(true);

                // 1️⃣ Either email or mobile must be present
                if (empty($data['email']) && empty($data['mobile'])) {
                    return $this->respond([
                        'status' => 'failed',
                        'code'   => 422,
                        'data'   => [
                            'message' => 'Either email or mobile is required'
                        ]
                    ], 200);
                }

                // 2️⃣ Validation rules
                $rules = [
                    'email'  => 'permit_empty|valid_email|is_unique[partner_staff.email]',
                    'mobile' => 'permit_empty|numeric|min_length[10]|max_length[15]|is_unique[partner_staff.mobile]',
                    'name'   => 'required',
                    'role_id'=> 'required'
                ];

                $messages = [
                    'email' => [
                        'valid_email' => 'Invalid email format',
                        'is_unique'   => 'Email already exists'
                    ],
                    'mobile' => [
                        'numeric'   => 'Mobile must be numeric',
                        'min_length'=> 'Mobile must be at least 10 digits',
                        'max_length'=> 'Mobile must be at most 15 digits',
                        'is_unique' => 'Mobile number already exists'
                    ],
                    'name' => [
                        'required' => 'Name is required'
                    ],
                    'role_id' => [
                        'required' => 'Role is required'
                    ]
                ];

                if (!$this->validate($rules, $messages)) {
                    return $this->respond([
                        'status' => 'failed',
                        'code'   => 422,
                        'data'   => $this->validator->getErrors()
                    ], 200);
                }

                // 3️⃣ Insert data
                $insertData = [
                    'name'       => $data['name'],
                    'email'      => $data['email'] ?? null,
                    'mobile'     => $data['mobile'] ?? null,
                    'role_id'    => $data['role_id'],
                    'manager_id' => $data['manager_id'] ?? null,
                    'handler_id' => (isset($data['handler_id']) && !empty($data['handler_id'])) ? json_encode($data['handler_id']) : json_encode([]), 
                    'created_by' => $data['created_by']
                ];

            $this->StaffModel->insert($insertData);

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => []], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
    }

   // UPDATE Staff
   public function updateStaff()
   {
        try{

            $data = $this->request->getJSON(true);
            if (!isset($data['id'])) {
                    return $this->respond(['status' => 'failed', 'code' => 200, 'data' => 'ID Required'], 200);
            }

            $id = $data['id'];

            // check if Staff exists
            $Staff = $this->StaffModel->find((int)$id);
            if (!$Staff) {
                return $this->respond(['status' => 'failed', 'code' => 200, 'data' => 'Date Not Found'], 200);
            }

            $updateData = [
                'name'                 => $data['name'],
                'email'                => $data['email'],
                'mobile'               => $data['mobile'],
                'role_id'              => $data['role_id'],
                'handler_id'           => (isset($data['handler_id']) && !empty($data['handler_id'])) ? json_encode($data['handler_id']) : json_encode([]), 
                'updated_by'           => $data['updated_by'],
            ];

            $this->StaffModel->update($id, $updateData);

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => []], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
   }

   // ACTIVATE / DEACTIVATE Staff
    public function changeStaffStatus()
    {
        try {
            $data = $this->request->getJSON(true);

            // validate inputs
            if (!isset($data['id']) || !isset($data['is_active'])) {
                return $this->respond(['status' => 'failed', 'code'   => 200,'data'   => 'ID and Status are required'], 200);
            }

            $id     = $data['id'];
            $is_active = (int) $data['is_active']; // 0 or 1

            $status = ($is_active == 1) ? 0 : 1;

            // check if Staff exists
            $Staff = $this->StaffModel->find((int)$id);
            if (!$Staff) {
                return $this->respond(['status' => 'failed','code'   => 200, 'data'   => 'Staff not found'], 200);
            }

            // update status
            $this->StaffModel->update($id, ['is_active' => $status]);

            return $this->respond([
                'status'  => 'success', 'code'    => 200,'data'   => "Staff status updated"], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed','code'   => 500,'data'   => $e->getMessage()], 500);
        }
    }


    // List of all manager incentive files
    public function managerIncentiveFileList()
    {
        try{

            $manager_id = $this->request->getGet('manager_id');

            $data = $this->ManagerIncentiveFileModel->where('manager_id',$manager_id)->where('is_active',1)->findAll();

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => $data], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
        
    }



   // Download manager incentive file (proxy to external app)
    public function downloadManagerIncentiveFile()
    {
        try {
            
            $id = $this->request->getGet('id');


            // External API URL
            $url = "https://venbait.in/nhance/dev/user/download-incentive-file/" . urlencode($id);

            // Use CURL request to fetch the file
            $client = \Config\Services::curlrequest();
            $response = $client->get($url);

            if ($response->getStatusCode() === 200) {
                // Pass the file contents back as download
                return $this->response
                    ->setHeader('Content-Type', $response->getHeaderLine('Content-Type'))
                    ->setHeader('Content-Disposition', 'attachment; id="' . basename($id) . '"')
                    ->setBody($response->getBody());
            } else {
                return $this->respond([
                    'status'  => 'failed',
                    'code'    => 404,
                    'message' => 'Unable to fetch file from source'
                ], $response->getStatusCode());
            }
        } catch (\Exception $e) {
            return $this->respond(['status'  => 'failed', 'code' => 500,'data' => $e->getMessage()], 500);
        }
    }


    public function monthlyLoginCount()
    {
        $month = $this->request->getGet('month') ?? date('Y-m'); // Default: current month
        $manager_id = $this->request->getGet('manager_id');

        // Extract year-month format (e.g., '2025-10')
        $startDateTime = date('Y-m-01 00:00:00', strtotime($month));
        $endDateTime   = date('Y-m-t 23:59:59', strtotime($month));

        $db = \Config\Database::connect();
        $builder = $db->table('partner_staff_attendance a');
        $builder->select('a.staff_id , s.name AS staff_name, DATE_FORMAT(a.login_datetime, "%Y-%m") AS month, COUNT(a.id) AS login_count, s.manager_id');
        $builder->join('partner_staff s', 's.id = a.staff_id', 'left');
        $builder->where('a.login_datetime >=', $startDateTime);
        $builder->where('a.login_datetime <=', $endDateTime);
        $builder->where('a.manager_id ', $manager_id);
        $builder->groupBy('a.staff_id');
        $builder->groupBy('month');
        $builder->orderBy('s.name', 'ASC');

        $result = $builder->get()->getResultArray();

        foreach ($result as $key => $value) {
            // Skip (remove) rows that don't match the requested manager_id
            if (!empty($manager_id) && $value['manager_id'] != $manager_id) {
                unset($result[$key]);
                continue;
            }
           $result[$key]['month'] = date('M Y', strtotime($value['month']));
        }

        // Reindex array so JSON returns as an array, not an object
        $result = array_values($result);

        return $this->respond(['status' => 'success', 'code' => 200, 'month' => $month, 'data' => $result], 200);

    }


    public function staffLoggedDays()
    {
        $staffId = $this->request->getGet('staff_id');
        $month = $this->request->getGet('month') ?? date('Y-m');

        $startDateTime = date('Y-m-01 00:00:00', strtotime($month));
        $endDateTime   = date('Y-m-t 23:59:59', strtotime($month));


        $db = \Config\Database::connect();
        $builder = $db->table('partner_staff_attendance');
        $builder->select('id, DATE(login_datetime) AS login_date, MIN(login_datetime) AS first_login, MAX(logout_datetime) AS last_logout');
        $builder->where('staff_id', $staffId);
        $builder->where('login_datetime >=', $startDateTime);
        $builder->where('login_datetime <=', $endDateTime);
        $builder->groupBy('DATE(login_datetime)');
        $builder->orderBy('login_date', 'ASC');
    
        $records = $builder->get()->getResultArray();

        //get Staff name
        $staff = $this->StaffModel->where('id',$staffId)->first();
    
        // Format result
        $formatted = [];
        foreach ($records as $row) {
            $formatted[] = [
                'name'         => $staff['name'],
                'id'           => $row['id'],
                'date'         => $row['first_login'] ? date('d-m-Y', strtotime($row['first_login'])) : null,
                'login_time'   => $row['first_login'] ? date('h:i A', strtotime($row['first_login'])) : null,
                'logout_time'  => $row['last_logout'] ? date('h:i A', strtotime($row['last_logout'])) : null,
                'no_of_logged_in_time' => $this->getLoginDuration($row['first_login'], $row['last_logout'])

            ];
        }
    
        return $this->respond([
            'status' => 'success',
            'code'   => 200,
            'month'  => $month,
            'data'   => $formatted
        ], 200);

    }

    private function getLoginDuration($login, $logout)
    {
        if (empty($login) || empty($logout)) {
            return null;
        }

        $loginTime = strtotime($login);
        $logoutTime = strtotime($logout);
        $diffSeconds = $logoutTime - $loginTime;

        if ($diffSeconds < 0) {
            return null; // Invalid data
        }

        $hours = floor($diffSeconds / 3600);
        $minutes = floor(($diffSeconds % 3600) / 60);

        if ($hours > 0 && $minutes > 0) {
            return "{$hours}h {$minutes}m";
        } elseif ($hours > 0) {
            return "{$hours}h";
        } elseif ($minutes > 0) {
            return "{$minutes}m";
        } else {
            return "0m";
        }
    }







}
