<?php

/**
 * +----------------------------------------------------------------------
 * | Created By PhpStorm
 * +----------------------------------------------------------------------
 * | DATE: 2021/7/19
 * +----------------------------------------------------------------------
 * | TIME: 17:07
 * +----------------------------------------------------------------------
 * | Author: YangXing(925032253@qq.com)
 * +----------------------------------------------------------------------
 * | Class: baseModel
 * +----------------------------------------------------------------------
 */

namespace servers;


use servers\validator;

/**
 * 基础Model
 * Class baseModel
 * @package model
 */
class baseModel extends \model
{
    /**
     * @var string
     */
    public $primary = 'ss_id';

    /**
     * 数据库表名
     * @var string
     */
    public $table;

    /**
     * 数据库搜索条件
     * @var array
     */
    public $where = [];

    /**
     * 搜索页数
     * @var int
     */
    public $page;

    /**
     * 条数
     * @var int
     */
    public $pageSize;

    /**
     * @var
     */
    public $sidx;

    /**
     * @var
     */
    public $sort;

    /**
     * @var string
     */
    public $orderby;

    /**
     * 筛选数据库字段
     * @var string|array
     */
    public $field = '*';

    /**
     * 连表
     * @var null|array
     */
    public $join = null;

    /**
     * 数据库字段
     * @var array
     */
    public $tableField = [];

    /**
     * @return array
     */
    public function list()
    {
        $where = $this->listWhere($this->where,$this->page,$this->pagesize,$this->sidx,$this->sort,$this->orderby);

        if($this->page > 0 && $this->pagesize > 0)
        {
            $pages = $this->paging($this->table,$where,$this->page,$this->pageSize);
            $where["limit"] = [$pages['limit'],$this->pageSize];
        }
        if(is_null($this->join)){
            $rows = $this->db->select($this->table,$this->field,$where);
        }else{
            $rows = $this->db->select($this->table,$this->join,$this->field,$where);
        }

        $data = [
            'page'=> $this->page,
            'total'=> $pages['total'],
            'records' => $pages['records'],
            'rows' => $rows
        ];
        return $data;
    }

    /**
     * @param $primary
     * @return $this
     */
    public function primary($primary)
    {
        $this->primary = $primary;
        return $this;
    }

    /**
     * @param $table
     * @return $this
     */
    public function table($table)
    {
        $this->table = $table;
        $this->where = [];
        $this->page = 0;
        $this->pageSize = 20;
        $this->sidx = '';
        $this->sort = '';
        $this->orderby = '';
        $this->field = '*';
        $this->join = null;
        return $this;
    }

    /**
     * @param $where
     * @return $this
     */
    public function where($where)
    {
        $this->where = $where;
        return $this;
    }

    public function hass()
    {
        if(is_null($this->join)){
            $bool = $this->db->has($this->table,$this->where);
        }else{
            $bool = $this->db->has($this->table,$this->join,$this->where);
        }
        return $bool;
    }

    /**
     *
     * TODO 多个唯一索引的时候不要用此方法，不可控
     * 存在就添加不存在就更新
     * @param array $data 支持一维和二维数组
     * @return int
     */
    public function updateOrInsert($data)
    {
        if(!is_array($data)){
            return 0;
        }
        if(!isset($data['0'])){
            $temp = $data;
            $data = [];
            $data['0'] = $temp;
        }
        $filed = array_keys($data['0']);

        $updateArr = array_map(function ($v){
            if($v !== $this->primary){
                return $v.'=VALUES('.$v.')';
            }
        },$filed);
        $updateArr = array_values(array_filter($updateArr));
        $filed = implode(',',$filed);
        $valueArr = array_map(function ($value){
            $value = array_map(function ($v){
                if(strpos($v,'SELECT') !== false) return $v;
                return empty($v) ? "''" : sprintf("'%s'",$v);
            },$value);
            return '('.implode(',',$value).')';
        },$data);

        $sql = sprintf("INSERT INTO %s (%s) VALUES %s ON DUPLICATE KEY UPDATE %s",$this->table,$filed,implode(',',$valueArr),implode(',',$updateArr));

        $result = $this->db->exec($sql);
        return $result->rowCount();
    }

    /**
     * @param $page
     * @return $this
     */
    public function page($page)
    {
        $this->page = $page;
        return $this;
    }

    /**
     * @param $pageSize
     * @return $this
     */
    public function pageSize($pageSize)
    {
        $this->pageSize = $pageSize;
        return $this;
    }

    /**
     * @param $sidx
     * @return $this
     */
    public function sidx($sidx)
    {
        $this->sidx = $sidx;
        return $this;
    }

    /**
     * @param $sort
     * @return $this
     */
    public function sort($sort)
    {
        $this->sort = $sort;
        return $this;

    }

    /**
     * @param $orderBy
     * @return $this
     */
    public function orderBy($orderBy)
    {
        $this->orderby = $orderBy;
        return $this;
    }

    /**
     * @param $join
     * @return $this
     */
    public function join($join)
    {
        $this->join = $join;
        return $this;
    }

    /**
     * @param $field
     * @return $this
     */
    public function field($field)
    {
        $this->field = $field;
        return $this;
    }

    /**
     * @param $id
     * @return array|false|mixed
     */
    public function find($param)
    {

        $id = (int) $param[$this->primary];
        if($id <= 0) return [];
        $this->where[$this->primary] = $id;
        if(!empty($this->orderby)){
            $this->where = array_merge($this->where,$this->orderby);
        }

        if(is_null($this->join)){
            $list = $this->db->get($this->table,$this->field,$this->where);
        }else{
            $list = $this->db->get($this->table,$this->join,$this->field,$this->where);
        }

        return $list ?: [];
    }

    /**
     * @param $data
     * @return false|\PDOStatement
     */
    public function update($data)
    {
        return $this->db->update($this->table,$data,$this->where);
    }

    public function gets()
    {
        if(is_null($this->join)){
            $list = $this->db->get($this->table,$this->field,$this->where);
        }else{
           $list = $this->db->get($this->table,$this->join,$this->field,$this->where);
        }

        return $list;
    }

    /**
     * 获取全部记录
     * @return array|false
     */
    public function getAll()
    {
        $list = is_null($this->join) ? $this->db->select($this->table,$this->field,$this->where) : $this->db->select($this->table,$this->join,$this->field,$this->where);
        return $list;
    }

    /**
     * 根据某一个值获取数据库中一列
     * @param $param
     * @return false|mixed
     */
    public function getFieldByOne($param)
    {
        $this->where = [$param['field'] => $param['value']];
        return is_null($this->join) ? $this->db->get($this->table,$this->field,$this->where) : $this->db->get($this->table,$this->join,$this->field,$this->where) ;
    }

    /**
     * 根据摸一个值获取一个列表
     * @param $param
     * @return false|mixed
     */
    public function getFieldByList($param)
    {
        $this->where = [$param['field'] => $param['value']];
        return is_null($this->join) ? $this->db->get($this->table,$this->field,$this->where) : $this->db->get($this->table,$this->join,$this->field,$this->where) ;
    }

    /**
     * @param $data
     * @return false|\PDOStatement
     */
    public function add($data)
    {
        //$data = $this->getData($data);
        //$this->validator($this->getRules(),$data);
        $this->db->insert($this->table,$data);
        return $this->db->id();
    }

    public function addAll($data)
    {
        $this->db->insert($this->table,$data);
        return $this->db->id();
    }

    public function getRules()
    {
        return [];
    }

    protected function getData($param)
    {
        $data = [];
        if(in_array('create_time',$this->tableField))
        {
            $time = date('Y-m-d H:i:s');
        }
        foreach ($this->tableField as $item)
        {
            if ($item == 'create_time')
            {
                $data[$item] = $time;
                continue;
            }
            if($item == 'update_time')
            {
                $data[$item] = $time;
                continue;
            }
            if($item == 'opuser')
            {
                $data[$item] = $_SESSION['userID'];
                continue;
            }
            $data[$item] = $param[$item];
        }
        return $data;
    }

    /**
     * 删除
     * @param array $where
     * @return false|\PDOStatement
     */
    public function delete($where = [])
    {
        if(!empty($where)){
            foreach ($where as $k => $v)
            {
                $this->where[$k] = $v;
            }
        }
        return $this->db->delete($this->table,$this->where);
    }

    /**
     * 表单验证
     * @param $rules
     * @param $param
     * @return bool
     */
    private function validator($rules,$param)
    {
        $validator = new Validator($rules);
        $validator->validate($param);
        //如果有错误直接返回
        if($validator->getError()){
            echo json_encode(['code' => 500,'msg' => $validator->getError()]);exit;
        }
        return true;
    }

    /**
     * 调用部存在的类时直接访问db类
     * @param $name
     * @param $arguments
     * @return false|mixed
     * @throws \Exception
     */
    public function __call($name, $arguments)
    {
        try {
            if(empty($arguments)){
                return $this->db->$name();
            }else{
                return call_user_func_array([$this->db,$name],$arguments);
            }
        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }
    }
}
