package com.fs.tzBank.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.fs.huifuPay.dto.*;
import com.fs.tzBank.TzBankService;
import com.fs.store.domain.TzConfigInfoDTO;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.google.gson.Gson;
import com.tzbank.util.TZBClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * tzBank服务实现类
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class TzBankServiceImpl implements TzBankService {

    private static final String urlBase = "https://open.tzbank.com/ApiGateWay/";
    private static final String getTokenUrl = urlBase+"auth/getToken";
    private static final String payCreateOrderUrl = urlBase+"apihandle/prod/1.0/payCreateOrder";
    private static final String miniProgramCodeUrl = urlBase+"apihandle/prod/1.0/miniProgramCode";
    private static final String payQueryOrderUrl = urlBase+"apihandle/prod/1.0/payQueryOrder";
    private static final String payRefund = urlBase+"apihandle/prod/1.0/payRefund";


    /**
     * tzbank配置
     */
    private static TzConfigInfoDTO tzConfigInfoDTO;
    @Autowired
    public void setTzConfig(SysConfigMapper sysConfigMapper){
        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("store.pay");
        tzConfigInfoDTO =
                new Gson().fromJson(sysConfig.getConfigValue(), TzConfigInfoDTO.class);
    }

    /**
     * tzbank客户端
     */
    private final TZBClient tzbClient;


    @Override
    public ReqTokenResultDTO getToken() {
        String result = null;
        try {
            result = tzbClient.tokenRequest(
                    getTokenUrl,
                    tzConfigInfoDTO.getAppKey(),
                    tzConfigInfoDTO.getAppSecret(), tzConfigInfoDTO.getUuid(),
                    tzConfigInfoDTO.getPublicKey(),
                    tzConfigInfoDTO.getPrivateKey());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        ReqTokenResultDTO reqTokenResultDTO = JSONObject.parseObject(result, ReqTokenResultDTO.class);

        if(ObjectUtil.notEqual(reqTokenResultDTO.getRetCode(),"00000000")){
            throw new RuntimeException("获取token失败");
        }

        return reqTokenResultDTO;
    }

    @Override
    public TzReqResultDTO<TzPayCreateOrderRspDTO> payCreateOrder(RequestDTO<TzPayCreateOrderReqBodyDTO> requestDTO) throws Exception {

        ReqTokenResultDTO token = this.getToken();


        String result = tzbClient.clientRequest(payCreateOrderUrl,
                tzConfigInfoDTO.getAppKey(),
                token.getRandomSec(),
                JSONObject.toJSONString(requestDTO),
                tzConfigInfoDTO.getPublicKey(),
                tzConfigInfoDTO.getPrivateKey(),
                token.getToken()
        );

        log.info(result);
        TypeReference<TzReqResultDTO<TzPayCreateOrderRspDTO>> typeReference = new TypeReference<TzReqResultDTO<TzPayCreateOrderRspDTO>>(){};

        return JSONObject.parseObject(result, typeReference);
    }

    @Override
    public TzReqResultDTO<TzMiniProgramCodeRespDTO> miniProgramCode(RequestDTO<TzMiniProgramCodeReqDTO> requestDTO) throws Exception {
        ReqTokenResultDTO token = this.getToken();
        String result = tzbClient.clientRequest(miniProgramCodeUrl,
                tzConfigInfoDTO.getAppKey(),
                token.getRandomSec(),
                JSONObject.toJSONString(requestDTO),
                tzConfigInfoDTO.getPublicKey(),
                tzConfigInfoDTO.getPrivateKey(),
                token.getToken()
        );
        log.info(result);

        TypeReference<TzReqResultDTO<TzMiniProgramCodeRespDTO>> typeReference = new TypeReference<TzReqResultDTO<TzMiniProgramCodeRespDTO>>(){};

        return JSONObject.parseObject(result, typeReference);
    }

    @Override
    public TzReqResultDTO<QueryOrderInfoDTO> payQueryOrder(RequestDTO<QueryOrderRestDTO> requestDTO) throws Exception {
        ReqTokenResultDTO token = this.getToken();
        String result = tzbClient.clientRequest(payQueryOrderUrl,
                tzConfigInfoDTO.getAppKey(),
                token.getRandomSec(),
                JSONObject.toJSONString(requestDTO),
                tzConfigInfoDTO.getPublicKey(),
                tzConfigInfoDTO.getPrivateKey(),
                token.getToken()
        );
        log.info(result);

        TypeReference<TzReqResultDTO<QueryOrderInfoDTO>> typeReference = new TypeReference<TzReqResultDTO<QueryOrderInfoDTO>>(){};

        return JSONObject.parseObject(result, typeReference);
    }

    @Override
    public TzReqResultDTO<TzRefundNotifyDTO> payRefund(RequestDTO<TzPayRefundDTO> requestDTO) throws Exception {
        ReqTokenResultDTO token = this.getToken();
        String result = tzbClient.clientRequest(payRefund,
                tzConfigInfoDTO.getAppKey(),
                token.getRandomSec(),
                JSONObject.toJSONString(requestDTO),
                tzConfigInfoDTO.getPublicKey(),
                tzConfigInfoDTO.getPrivateKey(),
                token.getToken()
        );
        log.info(result);

        TypeReference<TzReqResultDTO<TzRefundNotifyDTO>> typeReference = new TypeReference<TzReqResultDTO<TzRefundNotifyDTO>>(){};

        return JSONObject.parseObject(result, typeReference);
    }
}
