<?php


namespace App\Models;

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

class BaseModel extends Model
{
    use Criteria;
    //use ApiSoftDeletes; laravels 下常驻内存 as Name 会出问题
    /**
     * 插入时间字段
     */
    const CREATED_AT = 'create_time';

    /**
     * 更新时间字段
     */
    const UPDATED_AT = 'update_time';

    /**
     * 状态字段
     */
    const DELETED_AT = 'status';

    /**
     * 正常状态
     */
    const STATUS_ENABLED = 0;
    /**
     * 禁用状态
     */
    const STATUS_DISABLED = 1;

    /**
     * 删除状态
     */
    const STATUS_DELETED = 2;

    /**
     * 该模型是否被自动维护时间戳
     *
     * @var bool
     */
    public $timestamps = true;
    /**
     * 别名名称
     * @var null
     */
    protected $aliasName = null;

    /**
     * 模型的日期字段保存格式。
     *
     * @var string
     */
    protected $dateFormat = 'Y-m-d H:i:s';

   /* public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        //自动添加字段
        $this->setFillable();
    }*/

    /**
     * 自动获取数据库表字段
     */
    protected function setFillable()
    {
        $key = get_class($this);
        $cache = Cache::store('file')->get($key);
        if (empty($cache)) {
            $columns = Schema::getColumnListing($this->table);
            $cache = $columns;
            Cache::store('file')->put($key, $columns, config('cache.columns'));
        }
        $this->fillable = $cache;
    }

    /**
     * 过滤掉非数据库字段的数据
     * @param $data
     * @return array
     */
    public function filter($data)
    {
        if(empty($this->fillable)){
            $this->setFillable();
        }
        $result = [];
        if(empty($data) || !is_array($data)){
            return $result;
        }
        foreach($this->fillable as $item){
            if(isset($data[$item])){
                $result[$item] = $data[$item];
            }
        }
        return $result;
    }

    /**
     * 覆盖setCreatedAt 不添加createAt字段
     *
     * @param  mixed $value
     * @return $this
     */
    public function setCreatedAt($value)
    {
        if (!empty(static::CREATED_AT)) {
            $this->{static::CREATED_AT} = $value;
        }
        if (!empty(static::UPDATED_AT)) {
            $this->{static::UPDATED_AT} = $value;
        }
        return $this;
    }

    /**
     * Set the value of the "updated at" attribute.
     *
     * @param  mixed $value
     * @return $this
     */
    public function setUpdatedAt($value)
    {
        if (!empty(static::UPDATED_AT)) {
            $this->{static::UPDATED_AT} = $value;
        }
        return $this;
    }

    /**
     * 别名
     * @param $name
     */
    public function alias($name)
    {
        $this->aliasName = $name;
        return $this->from($this->getTable().' as '.$name);
    }

    /**
     * 获取别名名称
     * @return null
     */
    public function getAliasName(){
        return $this->aliasName;
    }

    /**
     * Set the table associated with the model.
     *
     * @param  string  $table
     * @return $this
     */
    public function setTable($table)
    {
        $table = trim($table);
        $this->table = $table;
        if(strpos($table,' as ')){
            list($table, $alias) = explode(' as ', $table);
            if(!empty($alias)){
                $this->aliasName = trim($alias);
            }
        }
        return $this;
    }
    /*  @param DateTimeInterface $date
     *
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }


    /**
     * 获取分页行数
     * @param $data
     * @return int
     */
    protected function getPageSize($data)
    {
        return $data['page_size'] ?? config('app.app_rows');
    }

    /**
     * 获取页码
     * @param $data
     * @return int
     */
    protected function getPageNo($data)
    {
        return $data['page'] ?? config('app.app_page_no');
    }

    /**
     * 获取查询偏移量
     * @param $data
     * @return int
     */
    protected function getSkip($page,$pageSize)
    {
        return ($page - 1) * $pageSize;;
    }

    /**
     * 获取分页参数
     * */
    protected function getPaginatorParams($params){

        $pageSize = $this->getPageSize($params);
        $page =  $this->getPageNo($params);
        $skip =  $this->getSkip($page,$pageSize);
        return array($pageSize, $page,$skip);
    }

    /**
     * 构造返回页面数据
     * @param $data //数据
     * @param $formNb //开始数量
     * @param $page //页数
     * @param $perPageSize //每页数量
     * @param $total //总数量
     * @return mixed
     */
    public function buildPaginator($data = [], $formNb = 0, $page = 1, $perPageSize = 10, $total = 0)
    {
        $lastPage = ceil($total / $perPageSize);
        $toNb = $page * $perPageSize;
        if (empty($formNb)) {
            $formNb = $toNb - $perPageSize;
        }
        if ($toNb > $total) {
            $toNb = $total;
        }
        $resultDdata = array(
            'current_page' => $page,
            'data' => $data,
            'from' => $formNb,
            'last_page' => $lastPage,
            'per_page' => $perPageSize,
            'to' => $toNb,
            'total' => $total,
        );
        return $resultDdata;
    }

    /**
     * 字段唯一性性验证
     * 返回ture 代表数据库不存在,是唯一的 false 代表数据库存在,不是唯一的
     * @param $field
     * @param $value
     * @param $criteria
     * @return bool
     */
    public function checkFieldUnique($field, $criteria)
    {
        $existData = $this->newInstance()->buildQuery($criteria)->selectRaw(DB::raw($field))->exists();
        if ($existData) {
            return false;
        }else{
            return true;
        }
    }

}
