package com.hzs.third.pay.controller.api;

import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.enums.EBankCardType;
import com.hzs.common.core.enums.EBindStatus;
import com.hzs.common.core.enums.EOrderPrefix;
import com.hzs.common.core.enums.EPayStatus;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.third.pay.TOnlineCard;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import com.hzs.third.pay.config.AllInPayConfig;
import com.hzs.third.pay.constants.AllInPayConstants;
import com.hzs.third.pay.controller.base.PayBaseController;
import com.hzs.third.pay.enums.EJdFastBankCode;
import com.hzs.third.pay.param.*;
import com.hzs.third.pay.service.IAllInPayService;
import com.hzs.third.pay.service.ITOnlineCardService;
import com.hzs.third.pay.service.ITOnlinePaymentService;
import com.hzs.third.pay.vo.BindCardVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.net.InetAddress;
import java.util.*;

/**
 * 通联快捷支付控制器
 */
@Slf4j
@RestController
@RequestMapping("/all-in-fast")
public class AllInPayFastController extends PayBaseController {

    @Autowired
    private AllInPayConfig allInPayConfig;
    @Autowired
    private ITOnlineCardService itOnlineCardService;
    @Autowired
    private ITOnlinePaymentService itOnlinePaymentService;
    @Autowired
    private IAllInPayService iAllInPayService;

    /**
     * 绑卡列表
     *
     * @return
     */
    @GetMapping("/list")
    public AjaxResult list() {
        List<BindCardVO> resultList = new ArrayList<>();

        List<TOnlineCard> tOnlineCardList = itOnlineCardService.queryBankList(SecurityUtils.getUserId(), allInPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
        for (TOnlineCard tOnlineCard : tOnlineCardList) {
            String bankName = tOnlineCard.getBankName();
            if (StringUtils.isEmpty(bankName)) {
                EJdFastBankCode jdFastBankCode = EJdFastBankCode.getEnumByValue(tOnlineCard.getBankCode());
                bankName = (null == jdFastBankCode ? tOnlineCard.getBankCode() : jdFastBankCode.getLabel());
            }

            resultList.add(BindCardVO.builder()
                    .bindCode(tOnlineCard.getCode())
                    // 银行卡只显示后4位
                    .bankNo(tOnlineCard.getBankNo().substring(tOnlineCard.getBankNo().length() - 4))
                    .bankName(bankName)
                    .build());
        }
        return AjaxResult.success(resultList);
    }

    /**
     * 快捷绑卡
     *
     * @param param
     * @return
     */
    @RepeatSubmitSimple
    @PostMapping("/bind")
    public AjaxResult bind(@RequestBody FastBindParam param) {
        if (StringUtils.isAnyEmpty(param.getName(), param.getIdCard(), param.getBankNo(), param.getPhone())) {
            return AjaxResult.error("缺少参数");
        }
        // 当前用户
        Long userId = SecurityUtils.getUserId();
        // 所属国家
        Integer pkCountry = SecurityUtils.getPkCountry();

        // 银行卡号去空格
        String bankNo = StringUtils.deleteWhitespace(param.getBankNo());

        try {
            TOnlineCard checkCard = itOnlineCardService.checkUserBankExist(userId, bankNo, allInPayConfig.getCustomerNum(), pkCountry);
            if (checkCard != null) {
                return AjaxResult.error("已经绑定过该卡，不能重复绑定");
            }

            // 绑卡编号
            String bindCode = CommonUtil.createSerialNumber(EOrderPrefix.THIRD_CODE);

            TreeMap<String, String> params = new TreeMap<>();
            params.put("appid", allInPayConfig.getAppId());
            params.put("cusid", allInPayConfig.getCustomerNum());
            params.put("randomstr", System.currentTimeMillis() + "");
            params.put("signtype", AllInPayConstants.SIGN_TYPE);
            params.put("version", AllInPayConstants.VERSION);
            params.put("reqip", InetAddress.getLocalHost().getHostAddress());
            params.put("reqtime", DateUtils.parseDateTimeToStr(DateUtils.YAMMERERS, new Date()));

            params.put("meruserid", userId.toString());
            params.put("accttype", AllInPayConstants.ACCTTYPE_00);
            params.put("acctno", bankNo);
            params.put("idno", param.getIdCard().toUpperCase());
            params.put("acctname", param.getName());
            params.put("mobile", param.getPhone());

            log.info("通联快捷绑卡请求参数：{}", params);

            Map<String, String> resultMap = iAllInPayService.doRequest(allInPayConfig.getRequestUrl() + "/qpay/agreeapply", params);

            log.info("通联快捷绑卡返回参数： {}", resultMap);

            if (AllInPayConstants.SMS_SUCCESS.equals(resultMap.get("trxstatus"))) {
                // 返回成功
                // 插入银行卡明细表
                TOnlineCard tOnlineCard = new TOnlineCard();
                tOnlineCard.setCode(bindCode);
                tOnlineCard.setBindType(EBankCardType.DEBIT.getValue());
                tOnlineCard.setName(param.getName());
                tOnlineCard.setIdCard(param.getIdCard());
                tOnlineCard.setBankNo(bankNo);
                tOnlineCard.setPhone(param.getPhone());
                tOnlineCard.setCustomerNum(allInPayConfig.getCustomerNum());
                tOnlineCard.setValiddate(param.getValiddate());
                tOnlineCard.setCvv2(param.getCvv2());
                tOnlineCard.setPkCreator(userId);
                tOnlineCard.setPkCountry(pkCountry);
                tOnlineCard.setThirdInfo(resultMap.get("thpinfo"));
                if (itOnlineCardService.save(tOnlineCard)) {
                    return AjaxResult.success("", bindCode);
                } else {
                    log.error("通联快捷绑卡入库失败");
                }
            }
        } catch (Exception e) {
            log.error("通联快捷绑卡处理异常!", e);
        }
        return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED_FLUSH));
    }

    /**
     * 绑卡确认
     *
     * @param param
     * @return
     */
    @RepeatSubmitSimple
    @PostMapping("/bind-confirm")
    public AjaxResult bindConfirm(@RequestBody FastBindConfirmParam param) {
        if (StringUtils.isAnyEmpty(param.getBindCode(), param.getSmsCode())) {
            return AjaxResult.error("缺少参数");
        }
        // 当前用户
        Long userId = SecurityUtils.getUserId();

        try {
            TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(param.getBindCode(), userId, allInPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
            if (null == tOnlineCard) {
                return AjaxResult.error("用户未绑定该银行卡");
            }

            if (EBindStatus.BIND.getValue() == tOnlineCard.getBindStatus()) {
                // 如果已经绑定成功，则直接返回
                return AjaxResult.success();
            }

            TreeMap<String, String> params = new TreeMap<>();
            params.put("appid", allInPayConfig.getAppId());
            params.put("cusid", allInPayConfig.getCustomerNum());
            params.put("randomstr", System.currentTimeMillis() + "");
            params.put("signtype", AllInPayConstants.SIGN_TYPE);
            params.put("version", AllInPayConstants.VERSION);
            params.put("reqip", InetAddress.getLocalHost().getHostAddress());
            params.put("reqtime", DateUtils.parseDateTimeToStr(DateUtils.YAMMERERS, new Date()));

            params.put("meruserid", userId.toString());
            params.put("accttype", AllInPayConstants.ACCTTYPE_00);
            params.put("acctno", tOnlineCard.getBankNo());
            params.put("idno", tOnlineCard.getIdCard().toUpperCase());
            params.put("acctname", tOnlineCard.getName());
            params.put("mobile", tOnlineCard.getPhone());
            params.put("smscode", param.getSmsCode());
            params.put("thpinfo", tOnlineCard.getThirdInfo());

            log.info("通联绑卡确认请求参数： {}", params);

            Map<String, String> resultMap = iAllInPayService.doRequest(allInPayConfig.getRequestUrl() + "/qpay/agreeconfirm", params);

            log.info("通联绑卡确认返回参数： {}", resultMap);

            if (AllInPayConstants.SUCCESS_CODE.equals(resultMap.get("trxstatus"))) {
                // 返回成功

                // 更新银行卡明细表
                tOnlineCard.setBindId(resultMap.get("agreeid"));
                tOnlineCard.setBindStatus(EBindStatus.BIND.getValue());
                tOnlineCard.setBankCode(resultMap.get("bankcode"));
                tOnlineCard.setBankName(resultMap.get("bankname"));
                tOnlineCard.setPkModified(userId);
                tOnlineCard.setModifiedTime(new Date());
                if (itOnlineCardService.updateBankInfo(tOnlineCard) > 0) {
                    return AjaxResult.success();
                } else {
                    log.error("通联绑卡确认入库失败");
                }
            } else {
                log.error("通联绑卡确认返回失败! msg: {}", resultMap.get("errmsg"));
                return AjaxResult.error(resultMap.get("errmsg"));
            }
        } catch (Exception e) {
            log.error("通联绑卡确认处理异常!", e);
        }
        return AjaxResult.error("绑卡失败，请刷新后重试");
    }

    /**
     * 银行卡解绑
     *
     * @param param
     * @return
     */
    @PostMapping("/unbind")
    public AjaxResult unbind(@RequestBody FastUnBindParam param) {
        if (StringUtils.isEmpty(param.getBindCode())) {
            return AjaxResult.error("缺少参数");
        }
        // 当前用户
        Long userId = SecurityUtils.getUserId();

        try {
            TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(param.getBindCode(), userId, allInPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
            if (null == tOnlineCard) {
                return AjaxResult.error("用户未绑定该银行卡");
            }

            TreeMap<String, String> params = new TreeMap<>();
            params.put("cusid", allInPayConfig.getCustomerNum());
            params.put("appid", allInPayConfig.getAppId());
            params.put("version", AllInPayConstants.VERSION);
            params.put("randomstr", System.currentTimeMillis() + "");
            params.put("signtype", AllInPayConstants.SIGN_TYPE);
            params.put("agreeid", tOnlineCard.getBindId());

            log.info("通联解绑请求参数： {}", params);

            Map<String, String> resultMap = iAllInPayService.doRequest(allInPayConfig.getRequestUrl() + "/qpay/unbind", params);

            log.info("通联解绑返回数据： {}", resultMap);

            // 解绑银行卡
            itOnlineCardService.unBindBank(tOnlineCard.getCode(), userId, allInPayConfig.getCustomerNum());
            return AjaxResult.success();
        } catch (Exception e) {
            log.error("通联解绑处理异常!", e);
        }
        return AjaxResult.error("解绑失败，请刷新后重试");
    }

    /**
     * 快捷确认支付
     *
     * @param param
     * @return
     */
    @RepeatSubmitSimple
    @PostMapping("/pay-confirm")
    public AjaxResult payConfirm(@RequestBody FastPayOrderParam param) {
        if (StringUtils.isAnyEmpty(param.getBindCode(), param.getOrderCode(), param.getSmsCode())) {
            return AjaxResult.error("缺少参数");
        }
        // 当前用户
        Long userId = SecurityUtils.getUserId();

        try {
            // 查询用户绑卡信息
            TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(param.getBindCode(), userId, allInPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
            if (null == tOnlineCard) {
                return AjaxResult.error("用户未绑定该银行卡");
            }

            // 查询用户支付信息
            TOnlinePayment tOnlinePayment = itOnlinePaymentService.queryByBusinessCode(param.getOrderCode(), userId);
            if (null == tOnlinePayment || EPayStatus.PAID.getValue() == tOnlinePayment.getPayStatus()) {
                return AjaxResult.error("用户支付信息不存在或已支付");
            }

            TreeMap<String, String> params = new TreeMap<>();
            params.put("appid", allInPayConfig.getAppId());
            params.put("cusid", allInPayConfig.getCustomerNum());
            params.put("randomstr", System.currentTimeMillis() + "");
            params.put("signtype", AllInPayConstants.SIGN_TYPE);
            params.put("version", AllInPayConstants.VERSION);

            params.put("reqsn", tOnlinePayment.getOriginalOrder());
            params.put("smscode", param.getSmsCode());
            params.put("agreeid", tOnlineCard.getBindId());
            params.put("thpinfo", tOnlineCard.getThirdInfo());

            log.info("通联银行卡确认支付请求参数： {}", params);

            Map<String, String> resultMap = iAllInPayService.doRequest(allInPayConfig.getRequestUrl() + "/qpay/payagreeconfirm", params);

            log.info("通联银行卡确认支付返回数据： {}", resultMap);

            if (AllInPayConstants.SUCCESS_CODE.equals(resultMap.get("trxstatus"))
                    || AllInPayConstants.SUCCESS_2000.equals(resultMap.get("trxstatus"))
                    || AllInPayConstants.SUCCESS_2008.equals(resultMap.get("trxstatus"))) {
                // 返回订单状态为 交易处理 或 成功， 则返回请求成功
                return AjaxResult.success();
            }
            log.error("通联银行卡确认支付失败: {}", resultMap.get("errmsg"));
        } catch (Exception e) {
            log.error("通联银行卡确认支付处理异常!", e);
        }
        return AjaxResult.error("支付失败，请刷新后重试");
    }


}
