<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class Base extends Model
{
    protected $table = '';
    //自动维护create_at创建时间 updated_at修改时间
    public $timestamps = true;
    //统一设置返回时间格式
    protected $casts = [
        'created_at' => 'datetime:Y-m-d H:i:s',
        'updated_at' => 'datetime:Y-m-d H:i:s',
    ];

    /**
     * 日期序列化 勿删 删了时间就不是东八区时间了哈
     * @param \DateTimeInterface $date
     * @return string
     * @author zbj
     * @date 2023/4/13
     */
    protected function serializeDate(\DateTimeInterface $date): string
    {
        return $date->format('Y-m-d H:i:s');
    }
    /**
     * @name 列表数据
     * @return void
     * @author :liyuhang
     * @method
     */
    public function lists($map, $page, $row, $order = 'id', $fields = ['*'], $sort = 'desc'): array
    {
        $query = $this->formatQuery($map);
        $query = $this->sortOrder($query,$order,$sort);
        $lists = $query->select($fields)->paginate($row, $fields, 'page', $page);
        if (empty($lists)) {
            return [];
        }
        $lists = $lists->toArray();
        return $lists;
    }
    /**
     * @name  :无分页列表
     * @param $map
     * @param $order
     * @param $fields
     * @return mixed
     * @author :liyuhang
     * @method
     */
    public function list($map = [],$order = 'id',$fields = ['*'],$sort = 'desc',$row = 0): array
    {
        $query = $this->formatQuery($map);
        if($row != 0){
            $query = $query->limit($row);
        }
        $query = $this->sortOrder($query,$order,$sort);
        $lists = $query->select($fields)->get();
        if (empty($lists)) {
            return [];
        }
        $lists = $lists->toArray();
        return $lists;
    }

    /**
     * @remark :获取数据详情
     * @name   :read
     * @author :lyh
     * @method :post
     * @time   :2023/8/21 17:19
     */
    public function read($condition,$filed = ['*'])
    {
        $query = $this->formatQuery($condition);
        $info = $query->select($filed)->first();
        if (empty($info)) {
            return false;
        }
        $info = $info->toArray();
        return $info;
    }

    /**
     * @remark :添加数据
     * @name   :add
     * @author :lyh
     * @method :post
     * @time   :2023/8/21 17:18
     */
    public function add($data){
        $data = $this->filterRequestData($data);
        $data['created_at'] = date('Y-m-d H:i:s');
        $data['updated_at'] = $data['created_at'];
        return $this->insert($data);
    }

    /**
     * @remark :保存返回数据主键
     * @name   :addReturnId
     * @author :lyh
     * @method :post
     * @time   :2023/8/21 17:17
     */
    public function addReturnId($data){
        $data = $this->filterRequestData($data);
        $data['created_at'] = date('Y-m-d H:i:s');
        $data['updated_at'] = $data['created_at'];
        return $this->insertGetId($data);
    }

    /**
     * @remark :统计数量
     * @name   :count
     * @author :lyh
     * @method :post
     * @time   :2024/9/26 10:52
     */
    public function counts($condition){
        $condition = $this->filterRequestData($condition);
        return $this->formatQuery($condition)->count();
    }
    /**
     * @remark :编辑
     * @name   :edit
     * @author :lyh
     * @method :post
     * @time   :2023/8/21 17:18
     */
    public function edit($data,$condition){
        if(isset($data['id']) && !empty($data['id'])){
            unset($data['id']);
        }
        $data = $this->filterRequestData($data);
        $query = $this->formatQuery($condition);
        $data['updated_at'] = date('Y-m-d H:i:s');
        return $query->update($data);

    }

    /**
     * @remark :删除数据
     * @name   :del
     * @author :lyh
     * @method :post
     * @time   :2023/8/21 17:18
     */
    public function del($condition){
        $query = $this->formatQuery($condition);
        return $query->delete();
    }

    /**
     * @name :参数处理查询
     * @param $map = ['$k'=>['like',$v],$k1]
     * @param $val
     * @return Base
     * @author :liyuhang
     * @method
     */
    public function formatQuery($map = [],$query = ''){
        $model = $query ?: $this;
        $query = $model->where(function ($query) use ($map){
            foreach ($map as $k => $v){
                if(!is_array($v)){
                    $query->where($k,$v);
                    continue;
                }
                switch ($v[0]){
                    case 'like':
                        // like查询 ['name|title'=> ['like','%a%']]
                        if (strpos($k, '|') !== false) {
                            $query->where(function ($query) use ($k,$v) {
                                $item = explode('|', $k);
                                foreach ($item as $vo) {
                                    $query->orWhere($vo, $v[0], $v[1]);
                                }
                            });
                        } else {
                            $query->where($k, $v[0], $v[1]);
                        }
                        break;
                    case 'not like':
                        $query->where($k, $v[0], $v[1]);
                        break;
                    case 'in':
                        // in查询 ['id'=>['in',[1,2,3]]]
                        $query->whereIn($k, $v[1]);
                        break;
                    case 'not in':
                        // in查询 ['id'=>['not in',[1,2,3]]]
                        $query->whereNotIn($k, $v[1]);
                        break;
                    case 'or':
                        // in查询 ['id'=>['or',[1,2,3]]]
                        $query->orWhere($k, $v[1]);
                        break;
                    case 'between':
                        // in查询 ['id'=>['between',[create1,create2]]]
                        $query->whereBetween($k, $v[1]);
                        break;
                    case 'not between':
                        // not between查询 ['created_at'=>['not between',['xxx', 'xxx]]]
                        $query->whereNotBetween($k, $v[1]);
                        break;
                    default:
                        $query->where($k,$v[0],$v[1]);
                        break;
                }
            }

        });
        return $query;
    }


    /**
     * @remark :排序
     * @name   :sortOrder
     * @author :lyh
     * @method :post
     * @time   :2023/8/21 8:54
     */
    public function sortOrder(&$query,$order,$sort){
        if(is_array($order)){
            foreach ($order as $v){
                $query = $query->orderBy($v,$sort);
            }
        }else{
            $query = $query->orderBy($order,$sort);
        }
        return $query;
    }

    /**
     * 监听模型事件
     * @author zbj
     * @date 2023/4/25
     */
    protected static function booted()
    {
        static::saved(function ($row) {
            //删除缓存
            $row->original &&  static::clearCache($row);
        });

        static::deleted(function ($row) {
            //删除缓存
            $row->original &&  static::clearCache($row);
        });
    }

    /**
     * 删除缓存 子类重写此方法
     *
     * @param $row
     * @return bool
     * @author zbj
     * @date 2023/4/25
     */
    public static function clearCache($row){
        return true;
    }

    /**
     * @remark :过滤掉请求数据中不存在于数据库表中的字段
     * @name   :filterRequestData
     * @author :lyh
     * @method :post
     * @time   :2024/6/14 10:49
     */
    public function filterRequestData(array $data)
    {
        // 获取表的字段列表
        $columns = Schema::connection($this->connection)->getColumnListing($this->table);
        // 过滤数据
        return array_filter($data, function ($key) use ($columns) {
            return in_array($key, $columns);
        }, ARRAY_FILTER_USE_KEY);
    }

    /**
     * @remark :查询一个字段返回数组
     * @name   :selectField
     * @author :lyh
     * @method :post
     * @time   :2024/7/15 17:11
     */
    public function selectField($data,$filed){
        $data = $this->filterRequestData($data);
        return $this->formatQuery($data)->pluck($filed)->toArray();
    }
}