<?php
/**
 *
 * @author：llbjj
 * @DateTime：2024/3/5 15:03
 * @Description：
 *
 */

namespace Application\Service\ToolSys;

use Application\Service\BaseService;
use Application\Service\Exceptions\InvalidArgumentException;
use Application\Service\HttpSv;
use Application\Service\Redis\RedisExtend;
use Application\Service\ToolSys\Config\ApiConfig;
use Application\Service\ToolSys\Config\SvConfig;
use Interop\Container\ContainerInterface;
use Laminas\Cache\Exception\ExceptionInterface;
use Laminas\Json\Decoder;
use Laminas\Json\Json;
use Laminas\View\Model\JsonModel;
use Zend\Stdlib\ArrayUtils;

class ToolSys extends BaseService
{
    CONST REDIS_KEY_NAME = __CLASS__;
    CONST ASYNC_REDIS_KEY_NAME = __CLASS__ . '_async';
    private HttpSv $httpSv;
    private string $domain;
    private string $appId;
    private string $secretKey;
    private string $redisNamespace;
    private string $redisTtl;
    private RedisExtend $redisExtend;
    public function __construct(ContainerInterface $container)
    {
        parent::__construct($container);

        $this->initConfig();

        $this->httpSv = $this->LocalService()->httpSv;
        $this->redisExtend = $this->LocalService()->redisExtend->setNamespace($this->redisNamespace)->setTtl($this->redisTtl);
    }

    /**
     * Notes: 全文识别
     * User: llbjj
     * DateTime: 2024/3/5 15:31
     *
     * @param array $data
     * @throws ExceptionInterface
     */
    public function pushTextOcr(array $data)
    {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken(),
        ])->post($this->domain . ApiConfig::OCR_TEXT_API, $data);
    }

    /**
     * Notes: 自定义模板识别
     * User: llbjj
     * DateTime: 2024/3/5 15:31
     *
     * @param array $data
     * @throws ExceptionInterface
     */
    public function pushCustomOcr(array $data)
    {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken(),
        ])->post($this->domain . ApiConfig::OCR_CUSTOM_API, $data);
    }

    /**
     * Notes: 表格识别
     * User: llbjj
     * DateTime: 2024/3/5 15:31
     *
     * @param array $data
     * @throws ExceptionInterface
     */
    public function pushTableOcr(array $data)
    {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken(),
        ])->post($this->domain . ApiConfig::OCR_TABLE_API, $data);
    }

    /**
     * @throws ExceptionInterface
     */
    public function pullCustomOcr(array $data)
    {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken()
        ])->post($this->domain . ApiConfig::PULL_OCR_CUSTOM_API, $data);
    }

    /**
     * @throws ExceptionInterface
     */
    public function pullTableOcr(array $data) {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken()
        ])->post($this->domain . ApiConfig::PULL_OCR_TABLE_API, $data);
    }

    /**
     * @throws ExceptionInterface
     */
    public function pullTextOcr(array $data) {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken()
        ])->post($this->domain . ApiConfig::PULL_OCR_TEXT_API, $data);
    }

    public function pullExportSas(array $data) {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken()
        ])->post($this->domain . ApiConfig::SAS_EXPORT_RESULT_API, $data);
    }

    /**
     * @throws ExceptionInterface
     */
    public function sasSourceData(string $sv, string $method, array $params = []) {
        if (!in_array($sv, SvConfig::SV_WHITE_LIST))
            throw new InvalidArgumentException("无权限调用{$sv}服务！");

        $this->getAccessToken();

        if( in_array($method, ['getOneFieldVal', 'fetchCol']) ) return $this->LocalService()->{$sv}->{$method}($params['field'], $params['where']);
        else return $this->LocalService()->{$sv}->{$method}($params);
    }

    /**
     * @throws ExceptionInterface
     * @throws \Exception
     */
    public function exportSas(array $data) {
        $exportResult = $this->httpSv->setHeader([
            'token' => $this->getAccessToken(),
            'esdToken' => $this->LocalService()->identity->getToken()
        ])->setTimeout(-1)->post($this->domain . ApiConfig::SAS_EXPORT_API, $data);

        if($exportResult['isValid']) {
            $exportId = $this->LocalService()->exportSas->getOneFieldVal('id', [
                'item_id' => $data['item_id'],
                'category' => $data['category'],
                'itemsig_id' => $data['itemsig_id'],
                'date_ym' => $data['date_ym'],
                'export_form_id' => $data['export_form_id'],
                'export_create_user_id' => $data['export_create_user_id'],
            ]);

            $dbResult = $this->LocalService()->exportSas->save([
                'id' => $exportId ?: 0,
                'item_id' => &$data['item_id'],
                'mode'  => &$data['mode'],
                'path' => $exportResult['result'] ?: '',
                'itemsig_id' => &$data['itemsig_id'],
                'export_form_id' => &$data['export_form_id'],
                'export_create_user_id' => &$data['export_create_user_id'],
                'type'  => $data['type'] ?? 0,
                'category' => $data['category'] ?? 0,
                'status' => $data['type'] ? 0 : 1,
                'date_ym' => &$data['date_ym'],
                'update_time' => time(),
                'update_user_id' => $this->LocalService()->identity->getId()
            ]);

            $exportId = $exportId ?: $dbResult;
            $logRemark = sprintf("(新版) %s - 申请导出", $this->LocalService()->exportSas->getCategoryText((int) $data['category']));
            /*if($data['category']) {
                switch ($data['category']) {
                    case 1:
                        $logRemark = '（新版）受试者进度表-横表-申请导出';
                        break;
                    case 2:
                        $logRemark = '（新版）受试者进度表-纵表-申请导出';
                        break;
                    case 3:
                        $logRemark = "（新版）表单日志-申请导出";
                        break;
                    default:
                        $logRemark = 'SAS申请导出';
                        break;
                }
            }*/
            // 添加申请日志
            $this->LocalService()->log->saveFileLog($exportId, 'exportSas', [
                'mode'  => &$data['mode'],
                'itemsig_id' => &$data['itemsig_id'],
                'type' => $data['type'] ?? 0,
                'category' => $data['category'] ?? 0,
            ], 0, $logRemark, $data['item_id'], '', ['item_id' => $data['item_id']]);
        }
        return $exportResult;
    }

    public function formLogList($data) {
        return $this->httpSv->setHeader([
            'token' => $this->getAccessToken(),
        ])->post($this->domain . ApiConfig::FORM_LOG_LIST_API, $data);
    }

    /**
     * Notes: 获取微信用户的当前状态
     *
     * @param string $openid
     * @param string $userType user: 用户表  patient: 受试者
     *
     * @throws ExceptionInterface
     *
     */
    public function getWechatUserStatus(string $openid, string $userType = 'patient') {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken()
        ])->post($this->domain . ApiConfig::WECHAT_USER_STATUS_API, [ 'openid' => $openid, 'user_type' => $userType ]);
    }

    /**
     * @throws ExceptionInterface
     */
    public function wechatUserStatusList(array $params = []) {
        return $this->httpSv->setHeader([
            'Token' => $this->getAccessToken()
        ])->post($this->domain . ApiConfig::WECHAT_USER_STATUS_LIST_API, $params);
    }

    /**
     * Notes: 获取授权token
     * User: llbjj
     * DateTime: 2024/3/5 15:05
     *
     * @throws ExceptionInterface
     */
    public function getAccessToken() {
        $accessToken = '';
        if(!$this->redisExtend->hasItem(self::REDIS_KEY_NAME)) {
            $authResult = $this->httpSv->post($this->domain . ApiConfig::AUTH_API, [
                'appID' => $this->appId,
                'secretKey' => $this->secretKey,
            ]);

            $accessToken = $authResult['access_token'];

            if(!$accessToken) throw new InvalidArgumentException('ToolSys授权登录失败！');
        }

        if(empty($accessToken)) $accessToken = $this->redisExtend->getItem(self::REDIS_KEY_NAME);

        // $this->redisExtend->setTtl($this->redisTtl)->setItem(self::REDIS_KEY_NAME, $accessToken);
        return $accessToken;
    }


    /**
     * Notes: 初始配置
     * User: llbjj
     * DateTime: 2024/3/5 15:05
     *
     */
    private function initConfig() {
        $toolSys = $this->LocalService()->config['toolSys'];
        if(empty($toolSys)) throw new InvalidArgumentException('请配置ToolSys信息！');

        foreach($toolSys as $configKey => $configVal) {
            $this->{$configKey} = $configVal;
        }
    }
}