//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.crm.pay.service.impl.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.pay.dto.callback.otc365.cn.Otc365CnCallbackResponseDataDto;
import com.crm.pay.dto.callback.otc365.cn.Otc365CnCallbackResponseDto;
import com.crm.pay.entity.callback.Otc365CnCallbackEntity;
import com.crm.pay.entity.otc365.cn.Otc365CnOrderEntity;
import com.crm.pay.entity.otc365.cn.Otc365CnResponseEntity;
import com.crm.pay.entity.property.Otc365CnPayPropertyEntity;
import com.crm.pay.service.FinanceDepositService;
import com.crm.pay.service.Otc365CnService;
import com.crm.pay.service.impl.base.BasePayServiceImpl;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.entity.custom.info.CustomInfoEntity;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositAddEntity;
import com.crm.pay.entity.FinanceDepositCallbackUpdateEntity;
import com.crm.rely.backend.model.pojo.table.FinanceDepositTable;
import com.crm.rely.backend.model.pojo.table.SysRemittanceChannelTable;
import com.crm.rely.backend.core.exception.PayValidatedException;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.HttpUtil;
import com.crm.rely.backend.util.MD5Util;
import com.crm.rely.backend.util.MapUtil;
import com.google.common.base.Strings;
import org.jsoup.Connection.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.LinkedHashMap;
import java.util.Map;

@Service
public class Otc365CnServiceImpl extends BasePayServiceImpl implements Otc365CnService {
    private static final Logger log = LoggerFactory.getLogger(Otc365CnServiceImpl.class);
    @Autowired
    private FinanceDepositService financeDepositService;

    public Otc365CnServiceImpl() {
    }

    public static void main(String[] args) {
        Otc365CnPayPropertyEntity propertyEntity = (Otc365CnPayPropertyEntity) JSON.parseObject("",
                Otc365CnPayPropertyEntity.class);
        JSONObject orderEntity = JSON.parseObject("");
        Map<String, String> map = new LinkedHashMap(14);
        orderEntity.forEach((k, v) -> {
            if (v != null && !"sign".equals(k)) {
                map.put(k, v.toString());
            }

        });
        map.put("secretKey", propertyEntity.getSecretKey());
        String signString = MapUtil.getString(MapUtil.sortByKey(map, false));
        String sign = MD5Util.getMD5(signString);
        System.out.println(sign);
    }

    private static String getSign(Otc365CnPayPropertyEntity propertyEntity, Otc365CnOrderEntity orderEntity) {
        Map<String, String> map = new LinkedHashMap(14);
        map.put("companyId", String.valueOf(orderEntity.getCompanyId()));
        map.put("kyc", orderEntity.getKyc());
        map.put("username", orderEntity.getUsername());
        map.put("phone", orderEntity.getPhone());
        map.put("orderType", String.valueOf(orderEntity.getOrderType()));
        map.put("companyOrderNum", orderEntity.getCompanyOrderNum());
        map.put("coinSign", orderEntity.getCoinSign());
        map.put("payCoinSign", orderEntity.getPayCoinSign());
        map.put("coinAmount", orderEntity.getCoinAmount().toString());
        map.put("total", orderEntity.getTotal().toString());
        map.put("orderTime", orderEntity.getOrderTime());
        map.put("syncUrl", orderEntity.getSyncUrl());
        map.put("asyncUrl", orderEntity.getAsyncUrl());
        map.put("secretKey", propertyEntity.getSecretKey());
        String signString = MapUtil.getString(MapUtil.sortByKey(map, false));
        String sign = MD5Util.getMD5(signString);
        log.info(String.format("orderNo:%s,sign string:%s,sign:%s", orderEntity.getCompanyOrderNum(),
                signString, sign));
        return sign;
    }

    @Override
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public String pay(FinanceDepositAddEntity balanceSaveEntity, CustomInfoEntity infoEntity) throws Exception {
        SysRemittanceChannelTable channel = getPayChannel(balanceSaveEntity.getPayType());
        Otc365CnPayPropertyEntity payProperty = getPayProperty(channel, Otc365CnPayPropertyEntity.class);
        balanceSaveEntity.setCurrency(channel.getCurrency());
        FinanceDepositTable balanceTable = financeDepositService.save(balanceSaveEntity, channel);
        String url = getUrl(balanceSaveEntity, payProperty, infoEntity, balanceTable);
        balanceTable.setFormUrl(url);
        
        return url;
    }

    @Override
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public Otc365CnCallbackResponseDto callback(Otc365CnCallbackEntity callbackEntity) throws Exception {
        log.info(String.format("callback orderNo:%s,callback data:%s", callbackEntity.getCompanyOrderNum(), JSON.toJSONString(callbackEntity)));
        Otc365CnPayPropertyEntity payProperty = getPayProperty(PayConstants.OTC_365_CN_PAY_KEY, false,
                Otc365CnPayPropertyEntity.class);
        Otc365CnCallbackResponseDto responseDto = new Otc365CnCallbackResponseDto();
        Otc365CnCallbackResponseDataDto dataDto = new Otc365CnCallbackResponseDataDto();
        dataDto.setOtcOrderNum(callbackEntity.getOtcOrderNum());
        dataDto.setCompanyOrderNum(callbackEntity.getCompanyOrderNum());
        responseDto.setData(dataDto);
        boolean flag = validate(callbackEntity, payProperty);
        if (!flag) {
            responseDto.setCode(500);
            responseDto.setMsg("fail");
            responseDto.setSuccess(false);
            return responseDto;
        } else {
            FinanceDepositCallbackUpdateEntity balanceCallbackUpdateEntity = getFinanceDepositCallbackUpdateEntity("1"
                    , callbackEntity.getCompanyOrderNum(), callbackEntity.getOtcOrderNum(), callbackEntity.getTradeStatus(), callbackEntity);
            if (PayConstants.CALLBACE_SUCCESS_STATUS.equals(balanceCallbackUpdateEntity.getCallbackStatus())) {
                balanceCallbackUpdateEntity.setTransformAmount(new BigDecimal(callbackEntity.getTotal()));
            }

            financeDepositService.updateCallback(balanceCallbackUpdateEntity);
            responseDto.setCode(200);
            responseDto.setMsg("success");
            responseDto.setSuccess(true);
            return responseDto;
        }
    }

    private String getUrl(FinanceDepositAddEntity balanceSaveEntity, Otc365CnPayPropertyEntity propertyEntity, CustomInfoEntity infoEntity, FinanceDepositTable balanceTable) throws ServiceException, IOException, PayValidatedException, ParseException {
        String timeImpl = String.valueOf(DateUtil.getTimestampByChina());
        Otc365CnOrderEntity otc365CnOrderEntity = new Otc365CnOrderEntity();
        otc365CnOrderEntity.setCoinAmount(balanceTable.getAmount().setScale(2, RoundingMode.HALF_UP));
        otc365CnOrderEntity.setCoinSign(propertyEntity.getCoinSign());
        otc365CnOrderEntity.setCompanyId(propertyEntity.getCompanyId());
        otc365CnOrderEntity.setCompanyOrderNum(balanceTable.getSerial() + "_" + balanceTable.getLogin());
        otc365CnOrderEntity.setKyc(propertyEntity.getKyc());
        otc365CnOrderEntity.setOrderTime(timeImpl);
        otc365CnOrderEntity.setOrderType(propertyEntity.getOrderType());
        otc365CnOrderEntity.setPayCoinSign(balanceTable.getTransformCurrency());
        otc365CnOrderEntity.setTotal(balanceTable.getTransformAmount().setScale(2, RoundingMode.HALF_UP));
        otc365CnOrderEntity.setPhone(infoEntity.getPhone());
        otc365CnOrderEntity.setSyncUrl(propertyEntity.getPickupUrl());
        otc365CnOrderEntity.setAsyncUrl(propertyEntity.getCallbackUrl());
        if (Strings.isNullOrEmpty(balanceSaveEntity.getName())) {
            otc365CnOrderEntity.setUsername(infoEntity.getName());
        } else {
            otc365CnOrderEntity.setUsername(balanceSaveEntity.getName());
        }

        String sign = getSign(propertyEntity, otc365CnOrderEntity);
        otc365CnOrderEntity.setSign(sign);
        Response response = HttpUtil.post(propertyEntity.getBaseUrl() + propertyEntity.getAddOrder(), JSON.toJSONString(otc365CnOrderEntity));
        Otc365CnResponseEntity otc365CnResponseEntity = (Otc365CnResponseEntity)JSON.parseObject(response.body(), Otc365CnResponseEntity.class);
        if (otc365CnResponseEntity != null && otc365CnResponseEntity.getCode() != null && otc365CnResponseEntity.getSuccess() != null && otc365CnResponseEntity.getCode().equals(200) && otc365CnResponseEntity.getSuccess()) {
            String url = otc365CnResponseEntity.getData().getLink();
            log.info(String.format("支付请求,请求orderNo:%s,请求url:%s", otc365CnOrderEntity.getCompanyOrderNum(), url));
            return url;
        } else if (otc365CnResponseEntity != null) {
            throw new PayValidatedException(otc365CnResponseEntity.getMsg());
        } else {
            throw new PayValidatedException("Payment platform is abnormal, please try again later or contact customer service.");
        }
    }

    private boolean validate(Otc365CnCallbackEntity callbackEntity, Otc365CnPayPropertyEntity payProperty) throws Exception {
        String _sign = callbackEntity.getSign();
        String sign = getSign(payProperty, callbackEntity);
        log.info(String.format("order no:%scallback result sign compare--callback sign:%s, encryption sign result:%s", callbackEntity.getCompanyOrderNum(), _sign, sign));
        return sign.equals(_sign);
    }

    private String getSign(Otc365CnPayPropertyEntity propertyEntity, Otc365CnCallbackEntity callbackEntity) {
        Map<String, String> map = new LinkedHashMap(13);
        map.put("companyOrderNum", callbackEntity.getCompanyOrderNum());
        map.put("otcOrderNum", callbackEntity.getOtcOrderNum());
        map.put("coinAmount", callbackEntity.getCoinAmount());
        map.put("coinSign", callbackEntity.getCoinSign());
        map.put("orderType", callbackEntity.getOrderType());
        map.put("tradeStatus", callbackEntity.getTradeStatus());
        map.put("tradeOrderTime", callbackEntity.getTradeOrderTime());
        map.put("unitPrice", callbackEntity.getUnitPrice());
        map.put("total", callbackEntity.getTotal());
        map.put("successAmount", callbackEntity.getSuccessAmount());
        map.put("secretKey", propertyEntity.getSecretKey());
        String signString = MapUtil.getString(MapUtil.sortByKey(map, false));
        String sign = MD5Util.getMD5(signString);
        log.info(String.format("回调结果加密处理--请求orderNo:%s,sign string:%s,sign:%s", callbackEntity.getCompanyOrderNum(), signString, sign));
        return sign;
    }
}
