<?php
/**
 * Created by PhpStorm.
 * User: leo
 * Date: 2018/5/22
 * Time: 上午9:39
 */

namespace common\helpers\ocr;

use common\helpers\Cache;
use common\helpers\ocr\baidu\AipOcr;
use common\helpers\Tool;
use yii\base\BaseObject;
use yii\base\StaticInstanceTrait;

class OcrApi extends BaseObject {
    use StaticInstanceTrait;

    const TYPE_BAIDU = 'baidu';
    const BAIDU_CONFIGS = [
        'appId' => 'string',
        'apiKey' => 'string',
        'secretKey' => 'string',
    ];

    private $_type;
    private $_typeClass;
    private $_ocrApiObj;
    private $_errorCode;

    /**
     * 初始化
     * @throws \yii\base\InvalidConfigException
     */
    public function init() {
        parent::init();
        // 获取当前使用的ocr识别接口
        $ocrApiConfig = Cache::getOcrApiConfig();
        $this->_type = $ocrApiConfig['API_NAME'];
        $this->_typeClass = null;
        $apiConfig = [];
        if ($ocrApiConfig['API_NAME'] == self::TYPE_BAIDU) {
            $this->_typeClass = AipOcr::class;
            foreach ($ocrApiConfig['CONFIG'] as $value) {
                $apiConfig[] = $value;
            }
        }
        $this->_errorCode = require_once \Yii::getAlias('@common/helpers/ocr/baidu/') . 'errorCode.php';
        // 创建ocr识别接口对象
        $this->_ocrApiObj = \Yii::createObject($this->_typeClass, $apiConfig);
    }

    /**
     * 身份证识别
     * @param $image
     * @param array $params
     * [
     *      'idCardSide' => 'front' | 'back',
     *      'options' => [
     *          'detect_direction' => false,
     *          'detect_risk' => false,
     *      ],
     * ]
     * @return null | array
     */
    public function idCard($image, array $params = []) {
        $result = null;
        $image = file_get_contents($image);
        if ($this->_type === self::TYPE_BAIDU) {
            $default = [
                'idCardSide' => 'front',
                'options' => [
                    'detect_direction' => false,
                    'detect_risk' => false,
                ],
            ];
            $argv = Tool::deepParse($params, $default);
            $tempResult = $this->_ocrApiObj->idcard($image, $argv['idCardSide'], $argv['options']);
            $errorCode = $this->_errorCode;
            if (isset($tempResult['error_code'])) {
                $result = [
                    'success' => false,
                    'message' => $errorCode[$tempResult['error_code']]['zh'] ?? '未知错误',
                ];
            } else {
                $message = '';
                switch ($tempResult['image_status']) {
                    case 'normal':
                        $message = '识别正常';
                        break;
                    case 'reversed_side':
                        $message = '未摆正身份证';
                        break;
                    case 'non_idcard':
                        $message = '上传的图片中不包含身份证';
                        break;
                    case 'blurred':
                        $message = '身份证模糊';
                        break;
                    case 'over_exposure':
                        $message = '身份证关键字段反光或过曝';
                        break;
                    case 'unknown':
                        $message = '未知错误';
                        break;
                    default :
                        $message = '未知错误';
                        break;
                }
                $result = [
                    'success' => $tempResult['image_status'] == 'normal' ? true : false,
                    'message' => $message,
                    'address' => $tempResult['words_result']['住址']['words'] ?? null,
                    'idCardNo' => $tempResult['words_result']['公民身份号码']['words'] ?? null,
                    'birthDay' => $tempResult['words_result']['出生']['words'] ?? null,
                    'realName' => $tempResult['words_result']['姓名']['words'] ?? null,
                    'sex' => $tempResult['words_result']['性别']['words'] ?? null,
                    'nation' => $tempResult['words_result']['民族']['words'] ?? null,
                ];
            }
        }
        return $result;
    }

    /**
     * 增值税发票识别
     * @param $image
     * @param array $params
     * [
     *      'options' => [
     *          'accuracy' => normal,
     *      ],
     * ]
     * @return array|null
     */
    public function vatInvoice($image, array $params = []) {
        $result = null;
        $image = file_get_contents($image);
        if ($this->_type === self::TYPE_BAIDU) {
            $default = [
                'options' => [
                    'accuracy' => 'normal',
                ],
            ];
            $argv = Tool::deepParse($params, $default);
            $tempResult = $this->_ocrApiObj->vatInvoice($image, $argv['options']);
            $errorCode = $errorCode = $this->_errorCode;;
            if (isset($tempResult['error_code'])) {
                $result = [
                    'success' => false,
                    'message' => $errorCode[$tempResult['error_code']]['zh'] ?? '未知错误',
                ];
            } else {
                $result = [
                    'success' => true,
                    'message' => '识别正常',
                    'invoiceCode' => $tempResult['words_result']['InvoiceCode'] ?? null,
                    'invoiceNum' => $tempResult['words_result']['InvoiceNum'] ?? null,
                    'invoiceDate' => $tempResult['words_result']['InvoiceDate'] ?? null,
                    'amount' => $tempResult['words_result']['AmountInFiguers'] ?? null,
                    'taxRate' => $tempResult['words_result']['CommodityTaxRate'][0]['word'] ?? null,
                    'purchaserName' => $tempResult['words_result']['PurchaserName'] ?? null,
                    'purchaserRegisterNum' => $tempResult['words_result']['PurchaserRegisterNum'] ?? null,
                    'purchaserAddress' => $tempResult['words_result']['PurchaserAddress'] ?? null,
                    'purchaserBank' => $tempResult['words_result']['PurchaserBank'] ?? null,
                    'sellerName' => $tempResult['words_result']['SellerName'] ?? null,
                    'sellerRegisterNum' => $tempResult['words_result']['SellerRegisterNum'] ?? null,
                    'sellerAddress' => $tempResult['words_result']['SellerAddress'] ?? null,
                    'sellerBank' => $tempResult['words_result']['SellerBank'] ?? null,
                    'itemName' => $tempResult['words_result']['CommodityName'][0]['word'] ?? null,
                    'invoiceRemark' => $tempResult['words_result']['Remarks'] ?? null,
                ];
                //$result = array_merge($result, $tempResult);
            }
        }
        return $result;
    }

    /**
     * 获取api设置的字段
     * @param $apiName
     * @return array
     */
    public static function apiConfigs($apiName) {
        $allApiModelData = \common\models\OcrApi::getAllData();
        $result = [];
        if ($apiName == self::TYPE_BAIDU) {
            $result = [
                'appId' => ['TITLE' => 'AppId', 'CONFIG_NAME' => 'appId', 'INPUT_TYPE' => 1, 'OPTIONS' => null, 'VALUE' => $allApiModelData[self::TYPE_BAIDU]['CONFIG']['appId'] ?? null],
                'apiKey' => ['TITLE' => 'ApiKey', 'CONFIG_NAME' => 'apiKey', 'INPUT_TYPE' => 1, 'OPTIONS' => null, 'VALUE' => $allApiModelData[self::TYPE_BAIDU]['CONFIG']['apiKey'] ?? null],
                'secretKey' => ['TITLE' => 'SecretKey', 'CONFIG_NAME' => 'secretKey', 'INPUT_TYPE' => 1, 'OPTIONS' => null, 'VALUE' => $allApiModelData[self::TYPE_BAIDU]['CONFIG']['secretKey'] ?? null],
            ];
        }
        return $result;
    }
}