<?php

namespace App\Models;

use CodeIgniter\Model;

class CompanyModel extends Model
{
    protected $table            = 'companies';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'array';
    protected $useSoftDeletes   = true;
    protected $protectFields    = true;
    protected $allowedFields    = [
        'company_name',
        'company_address',
        'area',
        'company_email',
        'hr_name',
        'hr_number',
        'manager_name',
        'manager_number',
        'total_workers',
        'contractual_workers',
        'payroll',
        'gst_tax_number',
        'status',
        'notes',
        'deleted_at'
    ];

    // Dates
    protected $useTimestamps = true;
    protected $dateFormat    = 'datetime';
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';
    protected $deletedField  = 'deleted_at';

    // Validation
    protected $validationRules      = [
        'company_name'     => 'required|max_length[255]|alpha_numeric_space',
        'company_address'  => 'required|max_length[500]',
        'area'             => 'required|in_list[Kachigam,Dabhel,Bhimpore,Kadaiya,Ringanwada,Somnath,Bhenslore,Jani Vankad]',
        'company_email'    => 'required|valid_email|valid_emails',
        'hr_name'          => 'permit_empty|max_length[255]',
        'hr_number'        => 'permit_empty|max_length[20]',
        'manager_name'     => 'permit_empty|max_length[255]',
        'manager_number'   => 'permit_empty|max_length[20]',
        'total_workers'    => 'required|integer|greater_than_equal_to[0]|less_than_equal_to[100000]',
        'contractual_workers' => 'required|integer|greater_than_equal_to[0]|less_than_equal_to[100000]',
        'payroll'          => 'permit_empty|integer|greater_than_equal_to[0]|less_than_equal_to[100000]',
        'gst_tax_number'   => 'permit_empty|regex_match[/^[0-9A-Z]{15}$/]',
        'status'           => 'required|in_list[Active,Inactive]',
    ];
    protected $validationMessages   = [
        'company_name' => [
            'required' => 'Company name is required.',
            'max_length' => 'Company name cannot exceed 255 characters.',
            'alpha_numeric_space' => 'Company name can only contain letters, numbers, and spaces.'
        ],
        'company_address' => [
            'required' => 'Company address is required.',
            'max_length' => 'Company address cannot exceed 500 characters.'
        ],
        'area' => [
            'required' => 'Area is required.',
            'in_list' => 'Please select a valid area.'
        ],
        'company_email' => [
            'required' => 'Company email is required.',
            'valid_email' => 'Please enter a valid email address.',
            'valid_emails' => 'Please enter a valid email address.'
        ],
        'hr_name' => [
            'max_length' => 'HR name cannot exceed 255 characters.'
        ],
        'hr_number' => [
            'max_length' => 'HR number cannot exceed 20 characters.'
        ],
        'manager_name' => [
            'max_length' => 'Manager name cannot exceed 255 characters.'
        ],
        'manager_number' => [
            'max_length' => 'Manager number cannot exceed 20 characters.'
        ],
        'total_workers' => [
            'required' => 'Total number of workers is required.',
            'integer' => 'Total workers must be a whole number.',
            'greater_than_equal_to' => 'Total workers must be 0 or greater.',
            'less_than_equal_to' => 'Total workers cannot exceed 100,000.'
        ],
        'contractual_workers' => [
            'required' => 'Number of contractual workers is required.',
            'integer' => 'Contractual workers must be a whole number.',
            'greater_than_equal_to' => 'Contractual workers must be 0 or greater.',
            'less_than_equal_to' => 'Contractual workers cannot exceed 100,000.'
        ],
        'payroll' => [
            'integer' => 'Payroll workers must be a whole number.',
            'greater_than_equal_to' => 'Payroll workers must be 0 or greater.',
            'less_than_equal_to' => 'Payroll workers cannot exceed 100,000.'
        ],
        'gst_tax_number' => [
            'regex_match' => 'GST/Tax number must be 15 characters alphanumeric.'
        ],
        'status' => [
            'required' => 'Status is required.',
            'in_list' => 'Please select a valid status.'
        ]
    ];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert   = [];
    protected $beforeUpdate   = [];

    /**
     * Get companies with pagination and search
     *
     * @param int $perPage
     * @param string|null $search
     * @param string|null $area
     * @param string|null $status
     * @return array
     */
    public function getCompanies($perPage = 10, $search = null, $area = null, $status = null)
    {
        // Apply search filter
        if ($search) {
            $this->groupStart()
                 ->like('company_name', $search)
                 ->orLike('company_email', $search)
                 ->groupEnd();
        }

        // Apply area filter
        if ($area) {
            $this->where('area', $area);
        }

        // Apply status filter
        if ($status) {
            $this->where('status', $status);
        }

        // Exclude soft deleted records
        $this->where('deleted_at', null);

        // Order by created_at descending
        $this->orderBy('created_at', 'DESC');

        // Return paginated results
        return $this->paginate($perPage);
    }

    /**
     * Get all areas
     *
     * @return array
     */
    public function getAreas()
    {
        return [
            'Kachigam',
            'Dabhel',
            'Bhimpore',
            'Kadaiya',
            'Ringanwada',
            'Somnath',
            'Bhenslore',
            'Jani Vankad'
        ];
    }

    /**
     * Get companies for export
     *
     * @param string|null $search
     * @param string|null $area
     * @param string|null $status
     * @return array
     */
    public function getCompaniesForExport($search = null, $area = null, $status = null)
    {
        $builder = $this->builder();

        // Apply search filter
        if ($search) {
            $builder->groupStart()
                    ->like('company_name', $search)
                    ->orLike('company_email', $search)
                    ->groupEnd();
        }

        // Apply area filter
        if ($area) {
            $builder->where('area', $area);
        }

        // Apply status filter
        if ($status) {
            $builder->where('status', $status);
        }

        // Exclude soft deleted records
        $builder->where('deleted_at', null);

        // Order by created_at descending
        $builder->orderBy('created_at', 'DESC');

        return $builder->get()->getResultArray();
    }

    /**
     * Get company statistics
     *
     * @return array
     */
    public function getCompanyStats()
    {
        $builder = $this->builder();
        
        // Get total companies
        $totalCompanies = $builder->where('deleted_at', null)->countAllResults(false);
        
        // Get active companies
        $activeCompanies = $builder->where('status', 'Active')->countAllResults(false);
        
        // Get total workers
        $totalWorkers = $builder->selectSum('total_workers')->where('deleted_at', null)->get()->getRow()->total_workers ?? 0;
        
        // Get contractual workers
        $contractualWorkers = $builder->selectSum('contractual_workers')->where('deleted_at', null)->get()->getRow()->contractual_workers ?? 0;
        
        return [
            'total_companies' => $totalCompanies,
            'active_companies' => $activeCompanies,
            'total_workers' => $totalWorkers,
            'contractual_workers' => $contractualWorkers
        ];
    }

    /**
     * Get recent companies
     *
     * @param int $limit
     * @return array
     */
    public function getRecentCompanies($limit = 5)
    {
        return $this->select('id, company_name, created_at')
                    ->where('deleted_at', null)
                    ->orderBy('created_at', 'DESC')
                    ->limit($limit)
                    ->findAll();
    }

    /**
     * Override the update method to add debugging
     *
     * @param mixed $id
     * @param array $data
     * @return bool
     */
    public function update($id = null, $data = null): bool
    {
        // Log the update attempt for debugging
        log_message('info', 'Attempting to update company ID: ' . $id . ' with data: ' . json_encode($data));
        
        // Call the parent update method
        $result = parent::update($id, $data);
        
        // Log the result
        if ($result) {
            log_message('info', 'Successfully updated company ID: ' . $id);
        } else {
            log_message('error', 'Failed to update company ID: ' . $id . '. Errors: ' . json_encode($this->errors()));
        }
        
        return $result;
    }
}