package com.tmerclub.cloud.payment.controller;

import com.alibaba.fastjson2.JSON;
import com.tmerclub.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.tmerclub.cloud.api.multishop.feign.ShopWithdrawCashFeignClient;
import com.tmerclub.cloud.api.payment.allinpay.member.resp.CompanyInfo;
import com.tmerclub.cloud.api.payment.allinpay.member.resp.UpdateCompanyInfoResp;
import com.tmerclub.cloud.api.supplier.feign.SupplierDetailFeignClient;
import com.tmerclub.cloud.api.supplier.feign.SupplierWithdrawCashFeignClient;
import com.tmerclub.cloud.api.user.dto.UserExtensionDTO;
import com.tmerclub.cloud.api.user.feign.UserExtensionFeignClient;
import com.tmerclub.cloud.api.user.feign.UserWithdrawCashFeignClient;
import com.tmerclub.cloud.common.constant.AllinpayConstant;
import com.tmerclub.cloud.common.constant.AllinpayPayStatus;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.payment.allinpay.bean.OpenRequest;
import com.tmerclub.cloud.payment.allinpay.member.resp.IdCardCollectResultResp;
import com.tmerclub.cloud.payment.allinpay.member.resp.SetPayPwdResp;
import com.tmerclub.cloud.payment.allinpay.member.resp.SignAcctProtocolResp;
import com.tmerclub.cloud.payment.allinpay.member.resp.UpdatePhoneByPayPwdResp;
import com.tmerclub.cloud.payment.allinpay.order.req.GetOrderStatusReq;
import com.tmerclub.cloud.payment.allinpay.order.resp.GetOrderStatusResp;
import com.tmerclub.cloud.payment.allinpay.order.resp.OrderResultNotice;
import com.tmerclub.cloud.payment.allinpay.service.AllinpayOrderService;
import com.tmerclub.cloud.payment.config.AllinpayConfig;
import com.tmerclub.cloud.payment.manager.PayNoticeManager;
import com.tmerclub.cloud.payment.service.AllinpayCompanyService;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.Objects;

/**
 * 通联通知回调
 * @author lanhai
 */
@Hidden
@RestController
@RequestMapping("/ua/notice/allinpay/member")
public class AllinpayNoticeController {

    private static final Logger logger = LoggerFactory.getLogger(AllinpayNoticeController.class);

    @Autowired
    private AllinpayCompanyService allinpayCompanyService;
    @DubboReference
    private ShopDetailFeignClient shopDetailFeignClient;
    @DubboReference
    private ShopWithdrawCashFeignClient shopWithdrawCashFeignClient;
    @DubboReference
    private SupplierDetailFeignClient supplierDetailFeignClient;
    @DubboReference
    private SupplierWithdrawCashFeignClient supplierWithdrawCashFeignClient;
    @DubboReference
    private UserWithdrawCashFeignClient userWithdrawCashFeignClient;
    @DubboReference
    private UserExtensionFeignClient userExtensionFeignClient;
    @Autowired
    private PayNoticeManager payNoticeManager;
    @Autowired
    private AllinpayOrderService allinpayOrderService;
    @Autowired
    private AllinpayConfig allinpayConfig;

    /**
     * 设置企业信息回调
     */
    @RequestMapping("/setCompanyInfoResult")
    public ResponseEntity<String> setCompanyResult(HttpServletRequest request,
                                                   @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("企业信息回调:{}", openRequest.getBizContent());
        return ResponseEntity.ok("success");
    }

    /**
     * 修改企业信息回调
     * 企业信息修改后，系统准实时触发营业执照及法人证件OCR识别，将修改后信息与预留影印件不匹配的则更新OCR比对结果并通过【企业会员信息修改结果通知】，
     * 商户需根据OCR结果判断，是否需通过【影印件采集】接口，重新上传影印件。
     */
    @RequestMapping("/updateCompanyInfoResult")
    public ResponseEntity<String> updateCompanyResult(HttpServletRequest request,
                                                      @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("修改企业信息回调:{}", openRequest.getBizContent());
        UpdateCompanyInfoResp updateCompanyInfoResp = JSON.parseObject(openRequest.getBizContent(), UpdateCompanyInfoResp.class);
        Integer status = allinpayCompanyService.getIdCardStatus(updateCompanyInfoResp.getOcrRegnumComparisonResult(), updateCompanyInfoResp.getOcrIdcardComparisonResult());
        if (updateCompanyInfoResp.getBizUserId().contains(AllinpayConstant.SHOP)) {
            ServerResponseEntity<Void> response = shopDetailFeignClient.updateCompanyInfoResult(updateCompanyInfoResp.getBizUserId(), status, updateCompanyInfoResp.getResult(), updateCompanyInfoResp.getFailReason());
            if (!response.isSuccess()) {
                logger.error("更新店铺企业信息失败：{}", response.getMsg());
                throw new LuckException(response.getMsg());
            }
        } else if (updateCompanyInfoResp.getBizUserId().contains(AllinpayConstant.SUPPLIER)) {
            ServerResponseEntity<Void> response = supplierDetailFeignClient.updateCompanyInfoResult(updateCompanyInfoResp.getBizUserId(), status, updateCompanyInfoResp.getResult(), updateCompanyInfoResp.getFailReason());
            if (!response.isSuccess()) {
                logger.error("更新供应商企业信息失败：{}", response.getMsg());
                throw new LuckException(response.getMsg());
            }
        }
        return ResponseEntity.ok("success");
    }

    /**
     * 影印件采集回调
     */
    @RequestMapping("/idCardCollectResult")
    public ResponseEntity<String> idCardCollectResult(HttpServletRequest request,
                                                      @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("影印件回调：{}", openRequest.getBizContent());
        IdCardCollectResultResp idCardCollectResultResp = JSON.parseObject(openRequest.getBizContent(), IdCardCollectResultResp.class);
        allinpayCompanyService.deleteCache(idCardCollectResultResp.getBizUserId());
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(idCardCollectResultResp.getBizUserId());
        Integer status = allinpayCompanyService.getIdCardStatus(companyInfo.getOcrRegnumComparisonResult(), companyInfo.getOcrIdcardComparisonResult());
        if (idCardCollectResultResp.getBizUserId().contains(AllinpayConstant.SHOP)) {
            ServerResponseEntity<Void> response = shopDetailFeignClient.updateAllinpayIdCardStatus(idCardCollectResultResp.getBizUserId(), status);
            if (!response.isSuccess()) {
                logger.error("店铺影印件采集回调更新状态失败：{}", response.getMsg());
            }
        } else if (idCardCollectResultResp.getBizUserId().contains(AllinpayConstant.SUPPLIER)) {
            ServerResponseEntity<Void> response = supplierDetailFeignClient.updateAllinpayIdCardStatus(idCardCollectResultResp.getBizUserId(), status);
            if (!response.isSuccess()) {
                logger.error("供应商影印件采集回调更新状态失败：{}", response.getMsg());
            }
        }
        return ResponseEntity.ok("success");
    }

    /**
     * 签约账户提现协议回调
     */
    @RequestMapping("/signAcctProtocol")
    public ResponseEntity<String> signAcctProtocolResult(HttpServletRequest request,
                                                         @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("签约账户提现协议回调：{}", openRequest.getBizContent());
        SignAcctProtocolResp signAcctProtocolResp = JSON.parseObject(openRequest.getBizContent(), SignAcctProtocolResp.class);
        String bizUserId = signAcctProtocolResp.getBizUserId();
        if (Objects.equals(signAcctProtocolResp.getResult().toUpperCase(Locale.ROOT), AllinpayPayStatus.OK.value())) {
            if (bizUserId.contains(AllinpayConstant.USER)) {
                // 用户提现协议签约(更新用户拓展信息)
                logger.info("用户{}提现协议签约成功", bizUserId);
                UserExtensionDTO userExtensionDTO = new UserExtensionDTO();
                userExtensionDTO.setUserId(Long.valueOf(bizUserId));
                userExtensionDTO.setAllinpayProtocolSign(1);
                userExtensionFeignClient.updateExtension(userExtensionDTO);
            } else if (bizUserId.contains(AllinpayConstant.SHOP)) {
                // 商家提现协议签约
                logger.info("商家{}提现协议签约成功", bizUserId);
                // 企业会员-“企业名称”“法人姓名”变更后，需重新签约。
                Long shopId = Long.valueOf(bizUserId.substring(AllinpayConstant.SHOP_LENGTH));
                CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
                // 签约类型 1.个人 2.法人 3.企业
                Integer signAcctType = Objects.equals(companyInfo.getCompanyName(), signAcctProtocolResp.getSignAcctName()) ? 3 : 2;
                shopDetailFeignClient.updateAcctProtocolNoByType(shopId, signAcctType, signAcctProtocolResp.getAcctProtocolNo());
            } else if (bizUserId.contains(AllinpayConstant.SUPPLIER)) {
                // 商家提现协议签约
                logger.info("供应商{}提现协议签约成功", bizUserId);
                // 企业会员-“企业名称”“法人姓名”变更后，需重新签约。
                Long supplierId = Long.valueOf(bizUserId.substring(AllinpayConstant.SUPPLIER_LENGTH));
                CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(bizUserId);
                // 签约类型 1.个人 2.法人 3.企业
                Integer signAcctType = Objects.equals(companyInfo.getCompanyName(), signAcctProtocolResp.getSignAcctName()) ? 3 : 2;
                supplierDetailFeignClient.updateAcctProtocolNoByType(supplierId, signAcctType, signAcctProtocolResp.getAcctProtocolNo());
            }
        }
        return ResponseEntity.ok("success");
    }

    /**
     * 设置支付密码回调
     */
    @RequestMapping("/setPayPwdResult")
    public ResponseEntity<String> setPayPwdResult(HttpServletRequest request,
                                                  @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("设置支付密码回调内容: {}", openRequest.getBizContent());
        SetPayPwdResp setPayPwdResp = JSON.parseObject(openRequest.getBizContent(), SetPayPwdResp.class);
        // 更新用户拓展信息
        if (Objects.equals(AllinpayPayStatus.OK.value(), setPayPwdResp.getStatus())) {
            logger.info("用户{}设置支付密码成功", setPayPwdResp.getBizUserId());
            UserExtensionDTO userExtensionDTO = new UserExtensionDTO();
            userExtensionDTO.setUserId(Long.valueOf(setPayPwdResp.getBizUserId()));
            userExtensionDTO.setAllinpayPayPwdSet(1);
            userExtensionFeignClient.updateExtension(userExtensionDTO);
        }
        return ResponseEntity.ok("success");
    }

    /**
     * 修改支付密码回调
     */
    @RequestMapping("/updatePayPwdResult")
    public ResponseEntity<String> updatePayPwd(HttpServletRequest request,
                                               @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("修改支付密码回调内容: {}", openRequest.getBizContent());
        return ResponseEntity.ok("success");
    }

    /**
     * 重置支付密码回调
     */
    @RequestMapping("/resetPayPwdResult")
    public ResponseEntity<String> resetPayPwd(HttpServletRequest request,
                                              @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("重置支付密码回调内容: {}", openRequest.getBizContent());
        return ResponseEntity.ok("success");
    }

    /**
     * 修改绑定手机（密码校验版）
     */
    @RequestMapping("/updatePhoneByPayPwdResult")
    public ResponseEntity<String> updatePhoneByPayPwdResult(HttpServletRequest request,
                                                            @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("修改绑定手机回调内容: {}", openRequest.getBizContent());
        UpdatePhoneByPayPwdResp updatePhoneResp = JSON.parseObject(openRequest.getBizContent(), UpdatePhoneByPayPwdResp.class);
        return ResponseEntity.ok("success");
    }

    /**
     * 提现申请
     */
    @RequestMapping("/withdrawApply")
    public ResponseEntity<String> withdrawApply(HttpServletRequest request,
                                                @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("提现回调内容: {}", openRequest.getBizContent());
        OrderResultNotice orderResultNotice = JSON.parseObject(openRequest.getBizContent(), OrderResultNotice.class);
        String failStr = "";
        if (Objects.equals(orderResultNotice.getStatus(), AllinpayPayStatus.ERROR.value())) {
            GetOrderStatusResp getOrderStatusResp = allinpayOrderService.getOrderStatus(new GetOrderStatusReq(orderResultNotice.getBizOrderNo()));
            failStr = getOrderStatusResp.getErrorMessage();
        }
        if (orderResultNotice.getBuyerBizUserId().contains(AllinpayConstant.SHOP)) {
            ServerResponseEntity<Void> response = shopWithdrawCashFeignClient.withdrawBack(orderResultNotice.getBizOrderNo(), orderResultNotice.getStatus(), orderResultNotice.getBuyerBizUserId(), failStr);
            if (!response.isSuccess()) {
                logger.error("店铺提现回调失败,{}", orderResultNotice);
                return ResponseEntity.ok(ResponseEnum.UNAUTHORIZED.value());
            }
        } else if (orderResultNotice.getBuyerBizUserId().contains(AllinpayConstant.SUPPLIER)) {
            ServerResponseEntity<Void> response = supplierWithdrawCashFeignClient.withdrawBack(orderResultNotice.getBizOrderNo(), orderResultNotice.getStatus(), orderResultNotice.getBuyerBizUserId(), failStr);
            if (!response.isSuccess()) {
                logger.error("供应商提现回调失败,{}", orderResultNotice);
                return ResponseEntity.ok(ResponseEnum.UNAUTHORIZED.value());
            }
        } else {
            ServerResponseEntity<Void> response = userWithdrawCashFeignClient.withdrawBack(orderResultNotice.getBizOrderNo(), orderResultNotice.getStatus(), failStr);
            if (!response.isSuccess()) {
                logger.error("用户余额提现回调失败,{}", orderResultNotice);
                return ResponseEntity.ok(ResponseEnum.UNAUTHORIZED.value());
            }
        }
        return ResponseEntity.ok("success");
    }

    /**
     * 充值申请
     */
    @RequestMapping("/rechargeApply")
    public ResponseEntity<String> rechargeApply(HttpServletRequest request,
                                                @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("充值回调内容：{}", openRequest.getBizContent());
        OrderResultNotice orderResultNotice = JSON.parseObject(openRequest.getBizContent(), OrderResultNotice.class);
        if (orderResultNotice.getBuyerBizUserId().contains(AllinpayConstant.SHOP)) {
            payNoticeManager.noticeAllinpayShopRecharge(orderResultNotice);
        }
        return ResponseEntity.ok("success");
    }
}
