package org.springblade.modules.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springblade.modules.app.config.SmartPayConfig;
import org.springblade.modules.app.entity.ApiLog;
import org.springblade.modules.app.service.IApiLogService;
import org.springblade.modules.app.service.ISmartPayService;
import org.springblade.modules.app.vo.SignContractVo;
import org.springblade.modules.app.vo.SmartPayVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.czb.gateway.api.APIConnection;
import com.czb.gateway.api.APIConstance;
import com.czb.gateway.api.APITools;
import com.czb.gateway.api.KeyStoreUtil;

import java.util.HashMap;

@Service
@Slf4j
public class SmartPayServiceImpl implements ISmartPayService {

	@Autowired
	private SmartPayConfig smartPayConfig;

    @Autowired
    private IApiLogService apiLogService;

    @Override
    public JSONObject queryBank() {
        String method = APITools.nvl(APIConstance.getConfig("queryBankMethod"));
        String version = APITools.nvl(APIConstance.getConfig("queryBankVersion"));
        String merId = APITools.nvl(APIConstance.getConfig("merId"));
        String date = APITools.getNow("yyyyMMddHHmmss");
        String branchName = "";
        String bankType = "";
        String cityCode = "";
        String origin = method + version + merId + date + branchName + bankType + cityCode;
        String sign = KeyStoreUtil.signData(origin);

        HashMap<String, String> reqParams = new HashMap<String, String>();
        reqParams.put("method", method);
        reqParams.put("version", version);
        reqParams.put("merId", merId);
        reqParams.put("date", date);
        reqParams.put("branchName", branchName);
        reqParams.put("bankType", bankType);
        reqParams.put("cityCode", cityCode);
        reqParams.put("sign", sign);

        String respData = APIConnection.execute(APIConstance.getConfig("interfaceURL"), reqParams);
        JSONObject respJson = JSONObject.parseObject(respData);
        String code = respJson.getString("code");
        if ("ZF00000".equals(code)) {
            return respJson;
        }
        log.error("return data {}", respJson);
        return null;
    }

    @Override
    public String accountSign(SignContractVo signContractVo) {
        String method = APITools.nvl(APIConstance.getConfig("bindCollectionMethod"));
        String version = APITools.nvl(APIConstance.getConfig("bindCollection2Version"));
        String merId = APITools.nvl(APIConstance.getConfig("merId"));
        String date = APITools.getNow("yyyyMMddHHmmss");
        String accountNo = APITools.nvl(signContractVo.getAccountNo());
        String accountName = APITools.nvl(signContractVo.getAccountName());
        String mobile = APITools.nvl(signContractVo.getMobile());
        String identityNo = APITools.nvl(signContractVo.getIdentityNo());
        String singleLimit = APITools.nvl(signContractVo.getSingleLimit());
        String dailyLimit = APITools.nvl(signContractVo.getDailyLimit());
        String totalLimit = APITools.nvl(signContractVo.getTotalLimit());
        String startDate = APITools.nvl(signContractVo.getStartDate());
        String endDate = APITools.nvl(signContractVo.getEndDate());
        String mobileCode = APITools.nvl(signContractVo.getMobileCode());
        String mobileSerial = APITools.nvl(signContractVo.getMobileSerial());

        String origin = method + version + merId + date + accountNo + accountName + mobile + identityNo + singleLimit + dailyLimit + totalLimit + startDate + endDate + mobileCode + mobileSerial;
        String sign = KeyStoreUtil.signData(origin);

        HashMap<String, String> reqParams = new HashMap<String, String>();
        reqParams.put("method", method);
        reqParams.put("version", version);
        reqParams.put("merId", merId);
        reqParams.put("date", date);
        reqParams.put("accountNo", accountNo);
        reqParams.put("accountName", accountName);
        reqParams.put("mobile", mobile);
        reqParams.put("identityNo", identityNo);
        reqParams.put("singleLimit", singleLimit);
        reqParams.put("dailyLimit", dailyLimit);
        reqParams.put("totalLimit", totalLimit);
        reqParams.put("startDate", startDate);
        reqParams.put("endDate", endDate);
        reqParams.put("mobileCode", mobileCode);
        reqParams.put("mobileSerial", mobileSerial);
        reqParams.put("sign", sign);
        String respData = APIConnection.execute(APIConstance.getConfig("interfaceURL"), reqParams);
        JSONObject respJson = JSONObject.parseObject(respData);
        String code = respJson.getString("code");
        String respOrigin = null;
		if ("ZF00000".equals(code)) {
			respOrigin = code + respJson.getString("msg") + respJson.getString("date") + respJson.getString("collectionSerialNo");
		} else {
			respOrigin = code + respJson.getString("msg") + respJson.getString("date");
		}
		String respSign = respJson.getString("sign");
		if (KeyStoreUtil.verifySignData(respOrigin, respSign) == 0) {
			String collectionSerialNo = respJson.getString("collectionSerialNo");
			return collectionSerialNo;
		} else {
			return null;
		}
    }

    @Override
    public Boolean accountCancel(SignContractVo signContractVo) {
        String method = APITools.nvl(APIConstance.getConfig("unbindCollectionMethod"));
		String version = APITools.nvl(APIConstance.getConfig("unbindCollectionVersion"));
		String merId = APITools.nvl(APIConstance.getConfig("merId"));
		String date = APITools.getNow("yyyyMMddHHmmss");
		String collectionSerialNo = APITools.nvl(signContractVo.getAccountSerial());
		String mobileCode = APITools.nvl(signContractVo.getMobileCode());
		String mobileSerial = APITools.nvl(signContractVo.getMobileSerial());

		String origin = method + version + merId + date + collectionSerialNo + mobileCode + mobileSerial;
		String sign = KeyStoreUtil.signData(origin);

		HashMap<String, String> reqParams = new HashMap<String, String>();
		reqParams.put("method", method);
		reqParams.put("version", version);
		reqParams.put("merId", merId);
		reqParams.put("date", date);
		reqParams.put("collectionSerialNo", collectionSerialNo);
		reqParams.put("mobileCode", mobileCode);
		reqParams.put("mobileSerial", mobileSerial);
		reqParams.put("sign", sign);

		String respData = APIConnection.execute(APIConstance.getConfig("interfaceURL"), reqParams);
		JSONObject respJson = JSONObject.parseObject(respData);
		String code = respJson.getString("code");
		String respOrigin = null;
		if ("ZF00000".equals(code)) {
			respOrigin = code + respJson.getString("msg") + respJson.getString("date");
		} else {
			respOrigin = code + respJson.getString("msg") + respJson.getString("date");
		}
		String respSign = respJson.getString("sign");
		if (KeyStoreUtil.verifySignData(respOrigin, respSign) == 0) {
			return true;
		} else {
			return false;
		}
    }

    @Override
    public String sendSms(String mobile,String type) {
        ApiLog apiLog = new ApiLog();

        String method = APITools.nvl(APIConstance.getConfig("sendMessageMethod"));
		String version = APITools.nvl(APIConstance.getConfig("sendMessageVersion"));
		String merId = APITools.nvl(APIConstance.getConfig("merId"));
		String date = APITools.getNow("yyyyMMddHHmmss");
		String smsType = APITools.nvl(type);
		String mobileMark = APITools.nvl(mobile);

		String origin = method + version + merId + date + smsType + mobileMark;
		String sign = KeyStoreUtil.signData(origin);

		HashMap<String, String> reqParams = new HashMap<String, String>();
		reqParams.put("method", method);
		reqParams.put("version", version);
		reqParams.put("merId", merId);
		reqParams.put("date", date);
		reqParams.put("smsType", smsType);
		reqParams.put("mobileMark", mobileMark);
		reqParams.put("sign", sign);

		apiLog.setReqData(reqParams.toString());

		String respData = APIConnection.execute(APIConstance.getConfig("interfaceURL"), reqParams);
		apiLog.setResData(respData);
		apiLog.setUrl(APIConstance.getConfig("interfaceURL"));
		apiLogService.save(apiLog);
		JSONObject respJson = JSONObject.parseObject(respData);
		String code = respJson.getString("code");
		String respOrigin = null;
		if ("ZF00000".equals(code)) {
			respOrigin = code + respJson.getString("msg") + respJson.getString("date") + respJson.getString("mobileSerial");
		} else {
			respOrigin = code + respJson.getString("msg") + respJson.getString("date");
		}
		String respSign = respJson.getString("sign");
		if (KeyStoreUtil.verifySignData(respOrigin, respSign) == 0) {
			if ("ZF00000".equals(code)) {
				String mobileSerial = respJson.getString("mobileSerial");
				return mobileSerial;
			} else {
				return null;
			}
		} else {
			return null;
		}
    }

    @Override
    public String quickPayOrder(SmartPayVo smartPayVo) {
    	ApiLog apiLog = new ApiLog();
        String method = APITools.nvl(APIConstance.getConfig("smartPayMethod"));
		String version = APITools.nvl(APIConstance.getConfig("smartPayVersion"));
		String merId = APITools.nvl(APIConstance.getConfig("merId"));
		String date = APITools.getNow("yyyyMMddHHmmss");
		String tradeNo = APITools.nvl(smartPayVo.getTradeNo());
		String totalAmount = APITools.nvl(smartPayVo.getAmount().toString());
		String coupon = APITools.nvl("");
		String totalCouponAmount = APITools.nvl("0");
		String payAmount = APITools.nvl(smartPayVo.getAmount().toString());
		String payChannel = APITools.nvl("1");
		String bankChoiceType = APITools.nvl("");
		String payAccountNo = APITools.nvl("");
		String payAccountName = APITools.nvl("");
		String payAccountType = APITools.nvl("1");
		String payAccountKind = APITools.nvl("");
		String payAccountBank = APITools.nvl("");
		String payerCertId = APITools.nvl("");
		String payerMobile = APITools.nvl("");
		String collectionSerialNo = APITools.nvl(smartPayVo.getCollectionSerial());
		String depositType = APITools.nvl("0");
		String receiptInfo = APITools.nvl(JSONObject.toJSONString(smartPayVo.getReceiptVo()));
		String totalCommissionAmount = APITools.nvl("0");
		String pageNotifyUrl = APITools.nvl(smartPayConfig.getNotifyUrl());
		String orderId = APITools.nvl(smartPayVo.getOrderId());

		String origin = method + version + merId + date + tradeNo + totalAmount + coupon + totalCouponAmount +
		       payAmount + payChannel + bankChoiceType +payAccountNo+payAccountName + payAccountType +
		       payAccountKind + payAccountBank + payerCertId + payerMobile + collectionSerialNo +
		       depositType + receiptInfo + totalCommissionAmount + pageNotifyUrl + orderId;
		String sign = KeyStoreUtil.signData(origin);

		HashMap<String, String> reqParams = new HashMap<String, String>();
		reqParams.put("method", method);
		reqParams.put("version", version);
		reqParams.put("merId", merId);
		reqParams.put("date", date);
		reqParams.put("tradeNo", tradeNo);
		reqParams.put("totalAmount", totalAmount);
		reqParams.put("coupon", coupon);
		reqParams.put("totalCouponAmount", totalCouponAmount);
		reqParams.put("payAmount", payAmount);
		reqParams.put("payChannel", payChannel);
		reqParams.put("bankChoiceType", bankChoiceType);
		reqParams.put("payAccountNo", payAccountNo);
		reqParams.put("payAccountName", payAccountName);
		reqParams.put("payAccountType", payAccountType);
		reqParams.put("payAccountKind", payAccountKind);
		reqParams.put("payAccountBank", payAccountBank);
		reqParams.put("payerCertId", payerCertId);
		reqParams.put("payerMobile", payerMobile);
		reqParams.put("collectionSerialNo", collectionSerialNo);
		reqParams.put("depositType", depositType);
		reqParams.put("receiptInfo", receiptInfo);
		reqParams.put("totalCommissionAmount", totalCommissionAmount);
		reqParams.put("pageNotifyUrl", pageNotifyUrl);
		reqParams.put("orderId", orderId);
		reqParams.put("sign", sign);

		apiLog.setReqData(reqParams.toString());

		String respData = APIConnection.execute(APIConstance.getConfig("interfaceURL"), reqParams);

		apiLog.setResData(respData);
		apiLog.setUrl(APIConstance.getConfig("interfaceURL"));
		apiLogService.save(apiLog);

		JSONObject respJson = JSONObject.parseObject(respData);
		String code = respJson.getString("code");
		String respOrigin = null;
		String respSign = respJson.getString("sign");
		if ("ZF00000".equals(code)) {
			if (KeyStoreUtil.verifySignData(respOrigin, respSign) == 0) {
				String redirectMethod = APITools.nvl(APIConstance.getConfig("smartPayPgMethod"));
				String redirectVersion = APITools.nvl(APIConstance.getConfig("smartPayPgVersion"));
				String redirectToken = respJson.getString("token");
				return redirectToken;
			}
		} else {
			return null;
		}
        return null;
    }

	@Override
	public Boolean quickPay(SmartPayVo smartPayVo) {
    	ApiLog apiLog = new ApiLog();
    	String method = APITools.nvl(APIConstance.getConfig("smartPayPgMethod"));
		String version = APITools.nvl(APIConstance.getConfig("smartPayPgVersion"));
		String merId = APITools.nvl(APIConstance.getConfig("merId"));
		String date = APITools.getNow("yyyyMMddHHmmss");
		String token = APITools.nvl(smartPayVo.getPayToken());

		String mobileCode = APITools.nvl(smartPayVo.getMobileCode());
		String mobileSerial = APITools.nvl(smartPayVo.getMobileSerial());

		String origin = method + version + merId + date + token + mobileCode + mobileSerial;
		String sign = KeyStoreUtil.signData(origin);

		HashMap<String, String> reqParams = new HashMap<String, String>();
		reqParams.put("method", method);
		reqParams.put("version", version);
		reqParams.put("merId", merId);
		reqParams.put("date", date);
		reqParams.put("token", token);
		reqParams.put("mobileCode", mobileCode);
		reqParams.put("mobileSerial", mobileSerial);
		reqParams.put("sign", sign);
		apiLog.setReqData(reqParams.toString());
		String respData = APIConnection.execute(APIConstance.getConfig("interfaceURL"), reqParams);
		apiLog.setResData(respData);
		apiLog.setUrl(APIConstance.getConfig("interfaceURL"));
		apiLogService.save(apiLog);

		JSONObject respJson = JSONObject.parseObject(respData);
		String code = respJson.getString("code");
		String respOrigin = null;
		if ("ZF00000".equals(code)) {
			String respSign = respJson.getString("sign");
			if (KeyStoreUtil.verifySignData(respOrigin, respSign) == 0) {
				return true;
			}
		} else {
			return false;
		}
		return false;
	}


}
