package com.czg.service.order.service.impl;

import cn.hutool.core.util.IdUtil;
import com.czg.PayCst;
import com.czg.account.entity.ShopUser;
import com.czg.account.entity.UserInfo;
import com.czg.account.service.ShopUserService;
import com.czg.account.service.UserInfoService;
import com.czg.constant.TableValueConstant;
import com.czg.constants.PayTypeConstants;
import com.czg.enums.CzgPayEnum;
import com.czg.exception.CzgException;
import com.czg.market.service.MkDistributionConfigService;
import com.czg.market.vo.MkDistributionConfigVO;
import com.czg.order.dto.MkDistributionPayDTO;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderPaymentService;
import com.czg.pay.CzgPayBaseReq;
import com.czg.resp.CzgResult;
import com.czg.service.market.service.impl.WxServiceImpl;
import com.czg.service.order.service.DistributionPayService;
import com.czg.utils.AssertUtil;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author Administrator
 */
@Service
public class DistributionPayServiceImpl implements DistributionPayService {
    private final BigDecimal MONEY_RATE = new BigDecimal("100");

    @Resource
    private OrderPaymentService paymentService;
    @Resource
    private MkDistributionConfigService configService;
    @Resource
    private WxServiceImpl wxService;
    @Resource
    private PayServiceImpl payService;

    @DubboReference
    private ShopUserService shopUserService;
    @DubboReference
    private UserInfoService userInfoService;


    @Accessors(chain = true)
    @Data
    private static class InitInfo {
        public OrderPayment payment;
        public MkDistributionConfigVO config;
        public ShopUser shopUser;
        private String openId;
    }

    private InitInfo initPayment(Long userId, MkDistributionPayDTO payParam, boolean isRecharge) {
        MkDistributionConfigVO detail = configService.detail(payParam.getShopId());
        AssertUtil.isTrue(detail.getIsEnable() != 1, "分销未开启");
        if (!isRecharge && !TableValueConstant.DistributionConfig.OpenType.PAY.getCode().equals(detail.getOpenType())) {
            throw new CzgException("当前未开启购买分销配置");
        }
        ShopUser shopUserInfo = shopUserService.getShopUserInfo(payParam.getShopId(), userId);

        OrderPayment orderPayment = new OrderPayment().setShopId(payParam.getShopId()).setSourceId(isRecharge ? payParam.getShopId() : shopUserInfo.getId())
                .setSourceType(isRecharge ? PayTypeConstants.SourceType.DISTRIBUTION_RECHARGE : PayTypeConstants.SourceType.DISTRIBUTION)
                .setPayType(PayTypeConstants.PayType.PAY)
                .setOrderNo(payParam.getPlatformType() + IdUtil.getSnowflakeNextId())
                .setAmount(isRecharge ? payParam.getAmount() : detail.getPayAmount());
        paymentService.save(orderPayment);

        InitInfo initInfo = new InitInfo().setConfig(detail);
        if (isRecharge) {
            String openId = wxService.getOpenId(payParam.getCode());
            initInfo.setOpenId(openId);
            initInfo.setPayment(orderPayment);
        } else {
            UserInfo userInfo = userInfoService.getById(userId);
            initInfo.setPayment(orderPayment).setShopUser(shopUserInfo)
                    .setOpenId(PayCst.Type.ALIPAY.equals(payParam.getPayType()) ? userInfo.getAlipayOpenId() : userInfo.getWechatOpenId());
        }
        return initInfo;
    }

    @Override
    public CzgResult<Map<String, Object>> ltPayOrder(String clintIp, MkDistributionPayDTO payParam) {
        InitInfo initInfo = initPayment(payParam.getUserId(), payParam, false);
        return payService.pay(payParam.getShopId(), CzgPayEnum.LT_PAY,
                CzgPayBaseReq.ltPayReq(initInfo.payment.getOrderNo(), "分销员开通", initInfo.payment.getAmount().multiply(MONEY_RATE).longValue(),
                        payParam.getPayType(), initInfo.getOpenId(), clintIp));
    }

    @Override
    public Map<String, String> mchRecharge(MkDistributionPayDTO payParam) {
        InitInfo initInfo = initPayment(payParam.getUserId() == null ? payParam.getShopId() : payParam.getUserId(), payParam, true);
        return wxService.v3Pay(initInfo.openId, payParam.getAmount(), "商户运营余额充值", initInfo.payment.getOrderNo(), initInfo.payment.getSourceType());
    }
}
