<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use App\Models\OrganizationModel;
use App\Models\UserModel;
use App\Models\GroupModel;
use App\Models\PolicyModel;
use App\Models\PolicyDetailsModel;
use App\Models\ServiceModel;

class OrganizationController extends ResourceController
{
    protected $format    = 'json';
    protected $myLogger;
    protected $organizationModel;
    protected $userModel;
    protected $groupModel;
    protected $policyModel;
    protected $policyDetailsModel;
    protected $serviceModel;

    public function __construct()
    {
        $this->myLogger = \Config\Services::mylogger();
        $this->organizationModel = new OrganizationModel();
        $this->userModel = new UserModel();
        $this->groupModel = new GroupModel();
        $this->policyModel = new PolicyModel();
        $this->policyDetailsModel = new PolicyDetailsModel();
        $this->serviceModel = new ServiceModel();
    }


    public function index()
    {
        
        $organization = $this->organizationModel->findAll();

        if (!$organization) {
            return $this->failNotFound('No organizations found');
        }

        return $this->respond([
            'status' => 200,
            'message' => 'organization retrieved successfully',
            'data' => $organization
        ]);
    }

    public function create()
    {
       
        $data = $this->request->getPost(); 
       
        // Handle file upload
        $file = $this->request->getFile('logo');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $newName = $file->getRandomName(); // Generate a unique name
            $uploadPath = FCPATH.'assets/images/logo';
            
            // Move file to the specified directory
            $file->move($uploadPath, $newName);

            // Save file path in database
            $data['logo'] = $uploadPath . '/' . $newName;
        } else {
            // return $this->failValidationErrors(['passport_document' => 'Invalid file upload']);
        }

        try {
            $data['services_ids'] =  json_encode($data['services_ids']);
            $this->organizationModel->insert($data);

            $organizationId = $this->organizationModel->insertID(); // Get the last inserted ID

            // Create Admin User for the Organization
            $adminData = [
                'first_name' => 'Admin', 
                'email'      => $data['sender_email'], 
                'password'   => password_hash('password', PASSWORD_DEFAULT), // Default password
                'role_id'    => 2,
                'org_id' => $organizationId
            ];
    
            $this->userModel->insert($adminData);

            return $this->respondCreated([
                'status'  => 201,
                'message' => 'organization created successfully',
                'data'    => $data
            ]);
        } catch (\Exception $e) {
            return $this->failServerError('Failed to create organization: ' . $e->getMessage());
        }
    }

    public function find($id = null)
    {
        if (!$id) {
            return $this->failNotFound('organization id is required');
        }

        // Fetch organization by ID
        $organization = $this->organizationModel->find($id);

        if (!$organization) {
            return $this->failNotFound('organization not found');
        }

        return $this->respond([
            'status' => 200,
            'message' => 'organization retrieved successfully',
            'data' => $organization
        ]);
    }

    public function update($id = null)
    {
        if (!$id){
            return $this->failNotFound('organization ID is required');
        }

        $data = $this->request->getPost(); 

        if (empty($data)) {
            return $this->failValidationErrors('No data provided for update');
        }

        // Check if organization exists
        $organization = $this->organizationModel->find($id);
        if (!$organization) {
            return $this->failNotFound('organization not found');
        }

         // Handle file upload
        $file = $this->request->getFile('logo');
        if ($file && $file->isValid() && !$file->hasMoved()) {
            $newName = $file->getRandomName(); // Generate a unique file name
            $uploadPath = FCPATH.'assets/images/logo';
            
            // Move file to the directory
            $file->move($uploadPath, $newName);

            // Delete the old file if it exists
            if (!empty($organization['logo']) && file_exists($organization['logo'])) {
                unlink($organization['logo']); // Remove old file
            }

            // Save the new file path
            $data['logo'] = $uploadPath . '/' . $newName;
        }

        // Update organization details
        try {
            $this->organizationModel->update($id, $data);
            return $this->respond([
                'status'  => 200,
                'message' => 'organization updated successfully',
                'data'    => $data
            ]);
        } catch (\Exception $e) {
            return $this->failServerError('Failed to update organization: ' . $e->getMessage());
        }
    }

    public function updateOrganizationStatus($id)
    {
        // Fetch organization by ID
        $organization = $this->organizationModel->find($id);

        if (!$organization) {
            return $this->failNotFound('organization not found');
        }

        // Toggle the is_active status
        $newStatus = $organization['is_active'] == 1 ? 0 : 1;

        // Update organization status
        $this->organizationModel->update($id, ['is_active' => $newStatus]);

        return $this->respond([
            'status' => 200,
            'message' => $newStatus ? 'organization activated successfully' : 'organization deactivated successfully',
            'is_active' => $newStatus
        ]);
    }

    public function testMail()
    {

        $data = $this->request->getJSON(true); 

        $to_mail = $data['to_mail'];

        $mail_config = [
                        'SMTPHost' => $data['mail_host'],
                        'SMTPUser' => $data['mail_user_name'],
                        'SMTPPass' => $data['mail_password'],
                        'SMTPPort' => $data['mail_port'],
                        'sender_email' => $data['sender_email']
                       ];


        return check_mail_config($to_mail, $mail_config);

    }



    //-------------------------------------------------Service---------------------------------------------------


    public function getServices()
    {
        $service = $this->serviceModel->findAll();

        if (!$service) {
            return $this->failNotFound('No service found');
        }

        return $this->respond([
            'status' => 200,
            'message' => 'service retrieved successfully',
            'data' => $service
        ]);
    }

    //------------------------------------------------Group-------------------------------------------------------


    public function getGroups()
    {

        $org_id = $this->request->getVar('org_id');

        $for = $this->request->getVar('for');

        if (isset($for) && $for === 'table_view') 
        {
            $group = $this->groupModel->select('m_group.*,  CONCAT_WS(U.first_name," ",U.last_name) as created_by,DP.name as domestic_policy_name , IP.name as international_policy_name')
                        ->join('m_users U', 'U.user_id = m_group.created_by ', 'left')
                        ->join('m_policy DP', 'DP.policy_id = m_group.domestic_policy_id ', 'left')
                        ->join('m_policy IP', 'IP.policy_id = m_group.international_policy_id ', 'left')
                        ->where('m_group.org_id',$org_id)
                        ->findAll();
        } else {
            $group = $this->groupModel->select('m_group.*,  CONCAT_WS(U.first_name," ",U.last_name) as created_by,DP.name as domestic_policy_name , IP.name as international_policy_name')
                        ->join('m_users U', 'U.user_id = m_group.created_by ', 'left')
                        ->join('m_policy DP', 'DP.policy_id = m_group.domestic_policy_id ', 'left')
                        ->join('m_policy IP', 'IP.policy_id = m_group.international_policy_id ', 'left')
                        ->where('m_group.org_id',$org_id)
                        ->where('m_group.is_active',1)
                        ->findAll();
        }





        if (!$group) {
            return $this->failNotFound('No group found');
        }

        return $this->respond([
            'status' => 200,
            'message' => 'group retrieved successfully',
            'data' => $group
        ]);
    }

    public function createGroup()
    {
       
        $data = $this->request->getJSON(true); 
       
        try {
            $insertedId = $this->groupModel->insert($data);

            if (!$insertedId) {
                return $this->fail('Data not inserted');
            }

            return $this->respondCreated([
                'status'  => 201,
                'message' => 'Group created successfully',
                'data'    => $data
            ]);
        } catch (\Exception $e) {
            return $this->failServerError('Failed to create Group: ' . $e->getMessage());
        }
    }

    public function findGroup($id = null)
    {
        if (!$id) {
            return $this->failNotFound('group id is required');
        }

        // Fetch group by ID
        $group = $this->groupModel->find($id);

        if (!$group) {
            return $this->failNotFound('group not found');
        }

        return $this->respond([
            'status' => 200,
            'message' => 'group retrieved successfully',
            'data' => $group
        ]);
    }

    public function updateGroup($id)
    {
       
        $data = $this->request->getJSON(true); 
       
        // Check if group exists
        $group = $this->groupModel->find($id);
        if (!$group) {
            return $this->failNotFound('group not found');
        }

    
        // Update group details
        try {
            $this->groupModel->update($id, $data);
            return $this->respond([
                'status'  => 200,
                'message' => 'group updated successfully',
                'data'    => $data
            ]);
        } catch (\Exception $e) {
            return $this->failServerError('Failed to update group: ' . $e->getMessage());
        }
    }

    public function updateGroupStatus($id)
    {
        // Fetch group by ID
        $group = $this->groupModel->find($id);

        if (!$group) {
            return $this->failNotFound('group not found');
        }

        // Toggle the is_active status
        $newStatus = $group['is_active'] == 1 ? 0 : 1;

        // Update group status
        $this->groupModel->update($id, ['is_active' => $newStatus]);

        return $this->respond([
            'status' => 200,
            'message' => $newStatus ? 'group activated successfully' : 'group deactivated successfully',
            'is_active' => $newStatus
        ]);
    }

    //---------------------------------------------------Policy---------------------------------------------------


    public function getPolicy()
    {

        $org_id = $this->request->getVar('org_id');

        $for = $this->request->getVar('for');

        if (isset($for) && $for === 'table_view') 
        {
            $policy = $this->policyModel->select('m_policy.*, CONCAT_WS(U.first_name," ",U.last_name) as created_by')
                        ->join('m_users U', 'U.user_id = m_policy.created_by ', 'left')
                        ->where('m_policy.org_id',$org_id)
                        ->findAll();
        } else {
            $policy = $this->policyModel->select('m_policy.*, CONCAT_WS(U.first_name," ",U.last_name) as created_by')
                        ->join('m_users U', 'U.user_id = m_policy.created_by ', 'left')
                        ->where('m_policy.org_id',$org_id)
                        ->where('m_policy.is_active',1)
                        ->findAll();
        }

        

        if (!$policy) {
            return $this->failNotFound('No policy found');
        }

        return $this->respond([
            'status' => 200,
            'message' => 'policy retrieved successfully',
            'data' => $policy
        ]);
    }


    public function createOrUpdatePolicy()
    {
       
        try {

            $json = $this->request->getJSON(true);
         
            // var_dump($json);die;
            // Check if policy_id exists
            if (!empty($json['policy_id'])) {
                $policy = $this->policyModel->find($json['policy_id']);
            }

            $json['services_ids'] = json_encode($json['services_ids']);
    
            if (isset($policy)) {
                // Update existing plan
                $this->policyModel->update($json['policy_id'], $json);
                $policyId = $json['policy_id'];
            } else {
                // Insert new plan
                $policyId = $this->policyModel->insert($json, true);
            }
    

            // Process related table
            if (!empty($json['policy_details'])) {
                $this->savePolicyDetails($json['policy_details'], $policyId);
            }
           
           
    
            return $this->respond([
                'status' => 200,
                'message' => 'Policy Date Affected successfully',
                'policy_id' => $policyId
            ]);
    
            } catch (\Exception $e) {
                return $this->failServerError('Failed to create : ' . $e->getMessage());
            }
    }

    private function savePolicyDetails($policyDetails, $policyId)
    {
        
        foreach ($policyDetails as $data) {
            $data['policy_id'] = $policyId;
            if (!empty($data['policy_details_id'])) {
                $this->policyDetailsModel->update($data['policy_details_id'], $data);
            } else {
                $this->policyDetailsModel->insert($data);
            }
        }
    }

    public function findPolicy($id = null)
    {
        if (!$id) {
            return $this->failNotFound('Policy id is required');
        }

        // Fetch policy by ID
        $policy = $this->policyModel->find($id);
        
        if (!$policy) {
            return $this->failNotFound('policy not found');
        }

        $policy['policy_details'] = $this->policyDetailsModel->where('policy_id',$id)->findAll();

        return $this->respond([
            'status' => 200,
            'message' => 'policy retrieved successfully',
            'data' => $policy
        ]);
    }

    public function updatePolicyStatus($id)
    {
        // Fetch policy by ID
        $policy = $this->policyModel->find($id);

        if (!$policy) {
            return $this->failNotFound('policy not found');
        }

        // Toggle the is_active status
        $newStatus = $policy['is_active'] == 1 ? 0 : 1;

        // Update policy status
        $this->policyModel->update($id, ['is_active' => $newStatus]);
        $this->policyDetailsModel->set(['is_active' => $newStatus])->where('policy_id',$id)->update();

        return $this->respond([
            'status' => 200,
            'message' => $newStatus ? 'policy activated successfully' : 'policy deactivated successfully',
            'is_active' => $newStatus
        ]);
    }











}
