<?php

namespace App\Models;

use CodeIgniter\Model;

class BaseModel extends Model
{
    protected $DBGroup          = 'default';
    protected $table            = '';
    protected $primaryKey       = '';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useSoftDeletes   = false;
    protected $protectFields    = true;
    protected $allowedFields    = [];

    // Custom
    protected $select  = '';
    protected $orderBy = '';
    protected $sort    = 'DESC';
    protected $where   = '';

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

    // Validation
    protected $validationRules      = [];
    protected $validationMessages   = [];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert   = [];
    protected $afterInsert    = [];
    protected $beforeUpdate   = [];
    protected $afterUpdate    = [];
    protected $beforeFind     = [];
    protected $afterFind      = [];
    protected $beforeDelete   = [];
    protected $afterDelete    = [];

    public function field_name_exist($field_name)
    {
        $db = \Config\Database::connect();

        return $db->fieldExists($field_name, $this->table);
    }

    public function get_field_names()
    {
        $db = \Config\Database::connect();

        return $fields = $db->getFieldNames($this->table);
    }

    public function insert_batch($data)
    {
        $db      = \Config\Database::connect();
        $builder = $db->table($this->table);

        return $builder->insertBatch($data);
    }

    public function update_batch($data, $key)
    {
        $db      = \Config\Database::connect();
        $builder = $db->table($this->table);

        return $builder->updateBatch($data, $key);
    }

    public function get_total($filterRules = null)
    {
        $db      = \Config\Database::connect();
        $builder = $db->table($this->table);

        $builder->select($this->primaryKey);
        if ($filterRules) {
            $filterRules = json_decode($filterRules);

            foreach ($filterRules as $filter) {
                $value = $filter->value;
                $pecah = explode(';', $value);
                if (count($pecah) > 1) {
                    $builder->groupStart();

                    foreach ($pecah as $p) {
                        if (trim($p) !== '') {
                            $builder->orLike($filter->field, trim(urldecode($p)));
                        }
                    }
                    $builder->groupEnd();
                } else {
                    $builder->like($filter->field, trim(urldecode($value)));
                }
            }
        }
        if ($this->where !== '') {
            $builder->where($this->where);
        }

        return $builder->countAllResults();
    }

    public function get_rows($limit, $start = 0, $filterRules = null, $sortOrder = null)
    {
        $db      = \Config\Database::connect();
        $builder = $db->table($this->table);

        if ($this->select !== '') {
            $builder->select($this->select);
        }
        if ($filterRules) {
            $filterRules = json_decode($filterRules);

            foreach ($filterRules as $filter) {
                $value = $filter->value;
                $pecah = explode(';', $value);
                if (count($pecah) > 1) {
                    $builder->groupStart();

                    foreach ($pecah as $p) {
                        if (trim($p) !== '') {
                            $builder->orLike($filter->field, trim(urldecode($p)));
                        }
                    }
                    $builder->groupEnd();
                } else {
                    $builder->like($filter->field, trim(urldecode($value)));
                }
            }
        }

        if ($sortOrder) {
            $builder->orderBy($sortOrder);
        } else {
            if ($this->orderBy !== '') {
                $builder->orderBy($this->orderBy);
            } else {
                $builder->orderBy($this->primaryKey, $this->sort);
            }
        }

        $builder->limit($limit, $start);
        if ($this->where !== '') {
            $builder->where($this->where);
        }

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

    public function get_excel($limit, $filterRules = null, $sortOrder = null)
    {
        $db      = \Config\Database::connect();
        $builder = $db->table($this->table);

        if ($this->select !== '') {
            $builder->select($this->select);
        }
        if ($filterRules) {
            $filterRules = json_decode($filterRules);

            foreach ($filterRules as $filter) {
                $value = $filter->value;
                $pecah = explode(';', $value);
                if (count($pecah) > 1) {
                    $builder->groupStart();

                    foreach ($pecah as $p) {
                        if (trim($p) !== '') {
                            $builder->orLike($filter->field, trim(urldecode($p)));
                        }
                    }
                    $builder->groupEnd();
                } else {
                    $builder->like($filter->field, trim(urldecode($value)));
                }
            }
        }

        if ($sortOrder) {
            $builder->orderBy($sortOrder);
        } else {
            if ($this->orderBy !== '') {
                $builder->orderBy($this->orderBy);
            } else {
                $builder->orderBy($this->primaryKey, $this->sort);
            }
        }

        if ((int) $limit !== 0) {
            $builder->limit($limit, 0);
        }
        if ($this->where !== '') {
            $builder->where($this->where);
        }

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

    public function autocomplete($field, $term)
    {
        $db      = \Config\Database::connect();
        $builder = $db->table($this->table);

        $builder->select($field);
        $builder->distinct();
        $builder->like($field, $term);
        $builder->limit(0, 10);

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