<?php

namespace Modules\User\Models\Traits;

use GuzzleHttp\Client;
use Illuminate\Support\Facades\Storage;

trait CertificationTrait
{
    protected $params = [];

    protected $header = [];

    protected $errorMessage = '';

    /**
     * Notes  : 自动认证操作
     *
     * @Author: Mr.wang
     * @Date  : 2021/12/7 13:53
     * @param $keys
     * @return array|int[]
     */
    public function autoVerified($keys): array
    {
        if (config('userCertification.is_open')) {
            if (config('userCertification.is_ocr_open')) {
                $verified = $this->ocrVerified(Storage::url($keys['front_card']), 'front');
                if (! $verified) {
                    return [
                        'code'    => 0,
                        'message' => $this->getErrorMessage(),
                    ];
                } else {
                    if ($verified['words_result']['姓名']['words'] != $keys['name']) {
                        return [
                            'code'    => 0,
                            'message' => '正面图片与填写信息不符',
                        ];
                    }
                    if ($verified['words_result']['公民身份号码']['words'] != $keys['idcard']) {
                        return [
                            'code'    => 0,
                            'message' => '正面图片与填写信息不符',
                        ];
                    }
                }
                $verified = $this->ocrVerified(Storage::url($keys['back_card']), 'back');

                if (! $verified) {
                    return [
                        'code'    => 0,
                        'message' => $this->getErrorMessage(),
                    ];
                } else {
                    if ($verified['image_status'] != 'normal') {
                        return [
                            'code'    => 0,
                            'message' => '背面图片与填写信息不符',
                        ];
                    }
                }
            }
            $base = [
                'name'   => $keys['name'],
                'idcard' => $keys['idcard'],
            ];
            $data = $this->check($base);
            if ($data === false) {
                return [
                    'code'    => 0,
                    'message' => $this->getErrorMessage(),
                ];
            } else {
                return [
                    'code' => 1,
                ];
            }
        } else {
            return [
                'code' => 1,
            ];
        }
    }

    /**
     * Notes  : ocr认证
     *
     * @Author: Mr.wang
     * @Date  : 2021/12/7 13:54
     * @param $image
     * @param $type
     * @return bool
     */
    public function ocrVerified($image, $type): bool
    {
        $AppID     = config('userCertification.ocr_appid');
        $SecretKey = config('userCertification.ocr_secretkey');

        if (empty($AppID)) {
            $this->setErrorMessage('请配置接口AppID');

            return false;
        }
        if (empty($SecretKey)) {
            $this->setErrorMessage('请配置接口SecretKey');

            return false;
        }
        $access = $this->getAccess($AppID, $SecretKey);
        if ($access === false) {
            $this->setErrorMessage('access_token不正确');

            return false;
        }
        $token  = $access->access_token;
        $apiUrl = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard';
        $result = $this->getOcr($apiUrl, $token, $image, $type);
        if (($result['error_code'] ?? 0) == 100) {
            $this->setErrorMessage($result['error_msg'] ?? '未知错误');

            return false;
        } else {
            if (empty($result['words_result']) || ! isset($result['words_result'])) {
                $this->setErrorMessage('图片未识别');

                return false;
            }

            return $result;
        }
    }

    protected function getAccess($AppID, $SecretKey)
    {
        $authUrl = 'https://aip.baidubce.com/oauth/2.0/token';
        try {
            $Client   = new Client();
            $response = $Client->post($authUrl, [
                'query' => [
                    'grant_type'    => 'client_credentials',
                    'client_id'     => $AppID,
                    'client_secret' => $SecretKey,
                ],
            ]);
            $result   = json_decode($response->getBody()->getContents());

            return $result;
        } catch (\Exception $e) {
            return false;
        }
    }

    protected function getOcr($url, $token, $image, $type)
    {
        $url    = $url.'?access_token='.$token;
        $params = [
            'url'          => $image,
            'id_card_side' => $type,
        ];
        try {
            $Client   = new Client();
            $response = $Client->post($url, ['form_params' => $params]);
            $result   = json_decode($response->getBody()->getContents(), true);

            return $result;
        } catch (\Exception $e) {
            return false;
        }
    }

    public function getErrorMessage()
    {
        return $this->errorMessage;
    }

    protected function setErrorMessage($message)
    {
        $this->errorMessage = $message;
    }

    /**
     * Notes   : 网络验证
     *
     * @Date   : 2021/9/25 15:42
     * @Author : Mr.wang
     * @param $keys
     * @return bool|mixed
     */
    protected function check($keys): bool
    {
        $apiUrl = config('userCertification.url');
        if (empty($apiUrl)) {
            $this->setErrorMessage('请配置接口地址');

            return false;
        }
        $apiCode = config('userCertification.code');
        if (empty($apiCode)) {
            $this->setErrorMessage('请配置接口Code');

            return false;
        }
        $this->setParams($keys);
        $this->setHeaders();
        $result = $this->dopost($apiUrl);
        try {
            if (config('userCertification.type') == 2) {
                if ($result->code == 0 && $result->message == '成功') {
                    if ($result->result->res == 1) {
                        return true;
                    } else {
                        $this->setErrorMessage('信息'.$result->result->description);

                        return false;
                    }
                } else {
                    $this->setErrorMessage('信息'.$result->result->description);

                    return false;
                }
            } else {
                if ($result->code == 200 && $result->success === true) {
                    if ($result->data->result == 0) {
                        return true;
                    } else {
                        $this->setErrorMessage($result->data->desc);

                        return false;
                    }
                } else {
                    $this->setErrorMessage($result->msg);

                    return false;
                }
            }
        } catch (\Exception $e) {
            return $result;
        }
    }

    protected function setParams($keys)
    {
        $this->params = $keys;
    }

    protected function setHeaders()
    {
        $this->header = [
            "Authorization" => 'APPCODE '.config('userCertification.code'),
            "Accept"        => "application/json",
        ];
    }

    protected function dopost($url)
    {
        try {
            $Client   = new Client();
            $response = $Client->get($url, ['query' => $this->params, 'headers' => $this->header]);
            //            switch (config('usercertification.request_method')) {
            //                case 'get':
            //                    $response = $Client->get($url, ['query' => $this->params, 'headers' => $this->header]);
            //                    break;
            //                case 'post':
            //                    $response = $Client->post($url, ['query' => $this->params, 'headers' => $this->header]);
            //                    break;
            //                default:
            //                    $this->setErrorMessage('不允许的请求方式');
            //
            //                    return false;
            //                    break;
            //            }
            $result = json_decode($response->getBody()->getContents());

            return $result;
        } catch (\Exception $e) {
            preg_match_all('/[\x{4e00}-\x{9fff}]+/u', $e->getmessage(), $cn_name);
            $this->setErrorMessage($cn_name[0][0]);

            return false;
        }
    }
}