<?php

/**
 * +----------------------------------------------------------------------
 * | Created By PhpStorm
 * +----------------------------------------------------------------------
 * | DATE: 2021/8/23
 * +----------------------------------------------------------------------
 * | TIME: 9:50
 * +----------------------------------------------------------------------
 * | Author: YangXing(925032253@qq.com)
 * +----------------------------------------------------------------------
 * | Class: apiErrorLog
 * +----------------------------------------------------------------------
 */

namespace model;


use GuzzleHttp\Client;
use phpDocumentor\Reflection\Types\False_;
use PHPUnit\Util\Exception;

class apiErrorLog extends \model
{

    /**
     *给对象赋值后使用的方法
     * @var object $object
     */
    public $object = null;

    /**
     * 主键ID
     * @var string
     */
    public $key = 'id';

    /**
     * 数据表
     * @var string
     */
    public $table = 'api_error_log';

    /**
     * 访问接口错误记录表
     * @param $data
     * @return false|\PDOStatement
     */
    public function add($data)
    {
       $data['create_time'] = $this->getDateTime();
       $data['update_time'] = $this->getDateTime();
       $data['is_success'] = 1;
       if(!isset($data['success_key'])){
           $data['success_key'] = 'result';
       }
       if(!isset($data['success_value'])){
           $data['success_value'] = 'success';
       }
       return $this->db->insert('api_error_log',$data);
    }

    public function apiReset()
    {
        $this->db->get();
    }

    public function save()
    {
        if(is_null($this->object))
        {
            throw new \Exception('Param is error');
        }
        $data = get_object_vars($this->object);
        if(isset($data[$this->key]) && $data[$this->key] > 0){
            $id = $data[$this->key];
            unset($data[$this->key]);
            $result = $this->db->update($this->table,$data,[$this->key => $id]);
        }else{
            $result = $this->db->insert($this->table,$data);
            $key = $this->key;
            $this->object->$key = $this->db->id();
        }
        if($result !== false){
            return $this->object;
        }
        return false;
    }

    public function __set($n,$v)
    {
       if(is_null($this->object)){
           $this->object = new \stdClass();
       }
       $this->object->$n = $v;
    }

    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());
        }
    }

    /**
     * 生成器
     * @return \Generator
     */
    public function generator()
    {
        $map[':is_success'] = [
            0,
            \PDO::PARAM_INT
        ];

        $sql = 'SELECT * FROM '.$this->table .'  WHERE is_success = :is_success';
        $query = $this->db->exec($sql,$map);
        while ($row = $query->fetch(\PDO::FETCH_OBJ)){
            yield $row;
        }
    }

    public function handle()
    {
        foreach ($this->generator() as $row) $this->call($row);
    }


    /**
     * 调用3次API
     * @param object $row 失败的请求
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function call($row)
    {
        for ($i = 0; $i <= 2; $i++)
        {
            $result = $this->reset($row);

            if($result === true)
            {
                //成功了,把表更新为成功
                $this->db->update($this->table,[
                    'is_success' => 1,
                    'update_time' => $this->getDateTime()
                ],['id' => $row->id]);
                break;
            }
        }
    }

    /**
     *  重新调用API
     * @param $row
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function reset($row)
    {
        try {

            $client= new Client(['timeout' => 1]);

            $param['headers'] = $this->getHeader();

            if($row->method == 'POST')
            {
                $param['form_params'] = !empty($row->param) ? json_decode($row->param,true) : [];
            }

            $response = $client->request($row->method,$row->apl_url,$param);

            $result = $response->getBody()->getContents();

            if(\mvc::isJson($result))
            {
                $result = json_decode($result,true);
                if($result[$row->success_key] == $row->success_value)
                {
                    //当改变接口返回正确的时候要修改本机的时候
                    if(!empty($row->class))
                    {
                        $classArr = explode(',',$row->class);

                        foreach ($classArr as $class)
                        {
                            if(class_exists($class))
                                if (!isset($this->object[$class])) $this->object[$class] = new $class();
                                if(method_exists($this->object[$class],'apiReturnSuccess'))
                                    return $this->object[$class]->apiReturnSuccess($row,json_decode($result)) !== false ? true : false;
                            else
                                return false;
                        }
                    }
                    return true;
                }
            }
            return false;
        }catch (\Throwable $e) {
            return false;
        }

    }

    /**
     * 设置请求header
     * @return string[]
     */
    private function getHeader()
    {
        return [
            'Accept:application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding:gzip, deflate',
            'Accept-Language:zh-CN',
            'Content-Type:application/json',
            'Expect:'
        ];
    }
}
