<?php

namespace app\common\library\baidu;

use DateTime;

class OcrCard
{
    const CARDURL = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard';
    const TOKENURL = 'https://aip.baidubce.com/oauth/2.0/token';
    private int $status = 1;

    private string $msg = 'success';

    private array $data = [];
    private string $clientId;

    private string $clientSecret;

    public function __construct(string $clientId, string $clientSecret)
    {
        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
    }

    /**
     * @notes:图片状态
     * @param string $key
     * @author: wanghousheng
     */
    private function imageStatus(string $key)
    {
        $this->status = 0;
        switch ($key) {
            case 'normal':
                $this->status = 1;
                break;
            case 'reversed_side':
                $this->msg = '身份证正反面颠倒';
                break;
            case 'non_idcard':
                $this->msg = '上传的图片中不包含身份证';
                break;
            case'blurred':
                $this->msg = '身份证模糊';
                break;
            case'other_type_card':
                $this->msg = '非身份证类型照';
                break;
            case'over_exposure':
                $this->msg = '身份证关键字段反光或过曝';
                break;
            case'over_dark':
                $this->msg = '身份证欠曝(亮度过低)';
                break;
            default:
                "不合法的证件照";
                break;
        }
    }

    private function riskType(string $key)
    {
        $this->status = 0;
        switch ($key) {
            case 'normal':
                $this->status = 1;
                break;
            case 'copy':
                $this->msg = '不能上传复印件';
                break;
            case 'temporary':
                $this->msg = '临时身份证';
                break;
            case'screen':
                $this->msg = '身份证翻拍';
                break;
            default:
                "不合法的证件照";
                break;
        }
    }

    private function resultHandle(): array
    {
        return ['status' => $this->status, 'msg' => $this->msg, 'data' => $this->data];
    }

    /**
     * @notes:验证身份证正面信息
     * @param $data
     * @return void
     * @author: wanghousheng
     */
    private function validateFrontData($data): void
    {
        $address = '';
        $card_no = '';
        $birthday = '';
        $username = '';
        $sex = '';
        $nation = '';

        if (!empty($data->log_id) && !empty($data->image_status) && !empty($data->words_result) && !empty($data->words_result_num)) {
            $this->imageStatus($data->image_status);
            if (!$this->status) {
                return;
            }
            if (!empty($data->risk_type)) {
                $this->riskType($data->risk_type);
                if (!$this->status) {
                    return;
                }
            }
            $words_result_num = intval($data->words_result_num);
            if ($words_result_num != 6) {
                $this->msg = '身份信息不全';
                return;
            }
            //身份信息
            $arr = $data->words_result;
            if (!empty($arr->住址->words)) {
                $address = $arr->住址->words;
            }
            if (!empty($arr->公民身份号码->words)) {
                $card_no = $arr->公民身份号码->words;
            }
            if (!empty($arr->出生->words)) {
                $birthday = $arr->出生->words;
                $date = DateTime::createFromFormat('Ymd', $birthday);
                $birthday = $date->format('Y-m-d');
            }
            if (!empty($arr->姓名->words)) {
                $username = $arr->姓名->words;
            }
            if (!empty($arr->性别->words)) {
                $sex = $arr->性别->words;
            }
            if (!empty($arr->民族->words)) {
                $nation = $arr->民族->words;
            }
        } else {
            $this->msg = '接口异常';
        }
        $this->data = compact('address', 'sex', 'nation', 'birthday', 'username', 'card_no');
    }

    /**
     * @notes:验证身份证反面信息
     * @param $data
     * @return void
     * @author: wanghousheng
     */
    private function validateBackData($data): void
    {
        $invalid_date = '';
        $issuance_office = '';
        $issuance_date = '';
        if (!empty($data->log_id) && !empty($data->image_status) && !empty($data->words_result) && !empty($data->words_result_num)) {
            $this->imageStatus($data->image_status);
            if (!$this->status) {
                return;
            }
            if (!empty($data->risk_type)) {
                $this->riskType($data->risk_type);
                if (!$this->status) {
                    return;
                }
            }
            $words_result_num = intval($data->words_result_num);
            if ($words_result_num != 3) {
                $this->msg = '身份信息不全';
                return;
            }
            //身份信息
            $arr = $data->words_result;
            if (!empty($arr->失效日期->words)) {
                $invalid_date = $arr->失效日期->words;
                $date = DateTime::createFromFormat('Ymd', $invalid_date);
                $invalid_date = $date->format('Y-m-d');
            }
            if (!empty($arr->签发机关->words)) {
                $issuance_office = $arr->签发机关->words;
            }
            if (!empty($arr->签发日期->words)) {
                $issuance_date = $arr->签发日期->words;
                $date = DateTime::createFromFormat('Ymd', $issuance_date);
                $issuance_date = $date->format('Y-m-d');
            }
        } else {
            $this->msg = '接口异常';
        }
        $this->data = compact('invalid_date', 'issuance_date', 'issuance_office');
    }


    /**
     * @notes:获取token
     * @return mixed|string
     * @author: wanghousheng
     */
    private function getToken()
    {
        $token = '';
        $data['grant_type'] = 'client_credentials';
        $data['client_id'] = $this->clientId;
        $data['client_secret'] = $this->clientSecret;
        $result = $this->post(self::TOKENURL, $data);
        if (!empty($result->access_token)) {
            $token = $result->access_token;
        } else {
            $this->msg = '获取token失败';
        }
        return $token;
    }

    /**
     * @notes:
     * @param string $img_url //证件地址 可外网访问的
     * @param int $type //1 正面 2反面
     * @return array
     * @author: wanghousheng
     */
    public function checkCard(string $img_url, int $type = 1): array
    {
        $token = $this->getToken();
        if (!$token) {
            return $this->resultHandle();
        }
        $data['url'] = $img_url;
        $data['id_card_side'] = 'front';
        if ($type != 1) {
            $data['id_card_side'] = 'back';
        }
        $data['detect_risk'] = 'true';
        $url = self::CARDURL . '?access_token=' . $token;
        $result = $this->post($url, $data);
        if ($type == 1) {
            $this->validateFrontData($result);
        } else {
            $this->validateBackData($result);
        }
        return $this->resultHandle();
    }

    private function post(string $url, array $postData)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
        $response = curl_exec($curl);
        curl_close($curl);
        return json_decode($response);
    }
}