package com.hzs.activity.draw.controller.api;

import cn.hutool.core.bean.BeanUtil;
import com.hzs.activity.base.service.IAcBaseConfigService;
import com.hzs.activity.draw.param.AcDrawRewardNumParam;
import com.hzs.activity.draw.param.DrawGiftConfigParam;
import com.hzs.activity.draw.service.IAcDrawGiftRuleConfigService;
import com.hzs.activity.draw.service.IAcDrawRewardNumService;
import com.hzs.activity.draw.service.IAcDrawRewardRecordService;
import com.hzs.activity.draw.vo.CuMemberPayAccountVO;
import com.hzs.activity.draw.vo.DrawGiftConfigVo;
import com.hzs.activity.draw.vo.DrawRewardNumVO;
import com.hzs.common.core.constant.msg.ActivityMsgConstants;
import com.hzs.common.core.constant.msg.FinanceMsgConstants;
import com.hzs.common.core.constant.msg.MemberMsgConstants;
import com.hzs.common.core.enums.EYesNo;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.activity.base.AcBaseConfig;
import com.hzs.common.domain.activity.draw.AcDrawRewardNum;
import com.hzs.common.domain.activity.draw.ext.AcDrawGiftRuleConfigExt;
import com.hzs.common.domain.activity.draw.ext.AcDrawRewardNumExt;
import com.hzs.common.domain.member.account.CuMemberAccount;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.core.utils.TransactionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 会员抽奖 前端控制器
 * </p>
 *
 * @author hzs
 * @since 2023-04-21
 */
@RestController
@RequestMapping("/api/draw")
@Slf4j
public class ApiAcDrawRewardNumController extends BaseController {

    private IAcBaseConfigService acBaseConfigService;

    private IAcDrawRewardRecordService acDrawRewardRecordService;

    private IAcDrawGiftRuleConfigService acDrawGiftRuleConfigService;

    private IAcDrawRewardNumService acDrawRewardNumService;

    @Autowired
    public void setAcDrawRewardNumService(IAcDrawRewardNumService acDrawRewardNumService) {
        this.acDrawRewardNumService = acDrawRewardNumService;
    }

    @Autowired
    public void setAcBaseConfigService(IAcBaseConfigService acBaseConfigService) {
        this.acBaseConfigService = acBaseConfigService;
    }

    @Autowired
    public void setAcDrawGiftRuleConfigService(IAcDrawGiftRuleConfigService acDrawGiftRuleConfigService) {
        this.acDrawGiftRuleConfigService = acDrawGiftRuleConfigService;
    }

    @Autowired
    public void setAcDrawRewardRecordService(IAcDrawRewardRecordService acDrawRewardRecordService) {
        this.acDrawRewardRecordService = acDrawRewardRecordService;
    }

    /*
     * @description: 抽奖
     * @author: sui q
     * @date: 2023/4/21 17:33
     * @param: null null
     **/
    @PostMapping("/lottery-draw")
    public AjaxResult lotteryDraw(@RequestBody AcDrawRewardNumParam drawRewardNumParam) {
        drawRewardNumParam.setPkMember(SecurityUtils.getUserId());
        drawRewardNumParam.setPkCountry(SecurityUtils.getPkCountry());
        // 验证会员是否有抽奖次数， 可用次数
        AcDrawRewardNum acDrawRewardNum = acDrawRewardNumService.queryAcDrawRewardNum(drawRewardNumParam);
        if (acDrawRewardNum == null || acDrawRewardNum.getTotalSurplusNum() + acDrawRewardNum.getAvailableSurplusNum() <= 0) {
            return AjaxResult.error(ActivityMsgConstants.DRAW_AVAILABLE_NUMBER);
        }
        AcDrawGiftRuleConfigExt acDrawGiftRuleConfigExt;
        if (acDrawRewardNum.getAvailableSurplusNum() > 0) {
            acDrawGiftRuleConfigExt = acDrawRewardRecordService.obtainAwardRecordByUser(acDrawRewardNum);
            if (acDrawGiftRuleConfigExt == null) {
                return AjaxResult.error(ActivityMsgConstants.DRAW_OVER);
            }
            acDrawGiftRuleConfigExt.setIsLotteryDraw(EYesNo.YES.getIntValue());
        } else {
            acDrawGiftRuleConfigExt = new AcDrawGiftRuleConfigExt();
            acDrawGiftRuleConfigExt.setAvailableNum(acDrawRewardNum.getAvailableNum());
            // 查询需要支付的价格
            acDrawGiftRuleConfigExt.setIsLotteryDraw(EYesNo.YES.getIntValue());
            // 查询支付金额
            AcBaseConfig acBaseConfig = acBaseConfigService.queryBaseConfigById(acDrawRewardNum.getPkBaseId());
            acDrawGiftRuleConfigExt.setPayMoney(acBaseConfig.getPayMoney());
        }
        return AjaxResult.success(acDrawGiftRuleConfigExt);
    }

    /*
     * @description: 查询抽奖次数
     * @author: sui q
     * @date: 2023/4/21 17:33
     * @param: null null
     **/
    @PostMapping("/lottery-num")
    public AjaxResult lotteryDrawNumber(@RequestBody AcDrawRewardNumParam drawRewardNumParam) {
        drawRewardNumParam.setPkMember(SecurityUtils.getUserId());
        drawRewardNumParam.setPkCountry(SecurityUtils.getPkCountry());
        // 验证会员是否有抽奖次数， 可用次数
        AcDrawRewardNum acDrawRewardNum = acDrawRewardNumService.queryAcDrawRewardNum(drawRewardNumParam);
        if (acDrawRewardNum == null || acDrawRewardNum.getTotalSurplusNum() + acDrawRewardNum.getAvailableSurplusNum() <= 0) {
            return AjaxResult.error(ActivityMsgConstants.DRAW_AVAILABLE_NUMBER);
        }
        return AjaxResult.success(BeanUtil.copyProperties(acDrawRewardNum, DrawRewardNumVO.class));
    }

    /*
     * @description: 根据活动查询奖品活动列表
     * @author: sui q
     * @date: 2023/4/27 11:27
     * @param: null null
     **/
    @PostMapping("/prize-list")
    public TableDataInfo drawGiftList(@RequestBody DrawGiftConfigParam drawGiftConfigParam) {
        drawGiftConfigParam.setPkCountry(SecurityUtils.getPkCountry());
        List<AcDrawGiftRuleConfigExt> drawGiftRuleConfigExtList = acDrawGiftRuleConfigService.queryAcDrawGiftConfig(drawGiftConfigParam);
        List<DrawGiftConfigVo> drawGiftConfigVoList = new ArrayList<>(drawGiftRuleConfigExtList.size());
        for (AcDrawGiftRuleConfigExt acDrawGiftRuleConfigExt : drawGiftRuleConfigExtList) {
            DrawGiftConfigVo drawGiftConfigVo = DrawGiftConfigVo.builder()
                    .pkId(acDrawGiftRuleConfigExt.getPkId())
                    .giftName(acDrawGiftRuleConfigExt.getGiftName())
                    .giftCover(acDrawGiftRuleConfigExt.getGiftCover())
                    .build();
            drawGiftConfigVoList.add(drawGiftConfigVo);
        }
        return getDataTable(drawGiftConfigVoList);
    }

    /**
     * @param acDrawRewardNumParam 购买
     * @Description: 查询抽奖购买消费明细
     * @return: AjaxResult
     * @Author: sui q
     * @Date: 2022/8/27 16:56
     */
    @PostMapping("/query-spend-details")
    public AjaxResult querySpendDetails(@RequestBody AcDrawRewardNumParam acDrawRewardNumParam) {
        if (acDrawRewardNumParam.getPkBaseId() == null || acDrawRewardNumParam.getPayNum() == null) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.REQUIRED_NOT_EMPTY));
        }
        // 获取账户，验证账户
        List<CuMemberAccountExt> cuMemberAccountExtList = acDrawRewardNumService.queryMemberAccountByCondition(getCuMemberAccount());
        if (cuMemberAccountExtList == null || cuMemberAccountExtList.size() == 0) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.CENTER_NOT_EXISTS));
        }
        AcDrawRewardNumExt acDrawRewardNum = getAcDrawRewardNumExt(acDrawRewardNumParam);
        if (acDrawRewardNum == null || acDrawRewardNum.getTotalSurplusNum() < acDrawRewardNumParam.getPayNum()) {
            return AjaxResult.error(TransactionUtils.getContent(ActivityMsgConstants.DRAW_AVAILABLE_NUMBER));
        }
        CuMemberAccountExt cuMemberAccountExt = cuMemberAccountExtList.get(0);
        // 验证会员账户余额是否足够支付
        BigDecimal toBePaidMoney = ComputeUtil.computeMultiply(acDrawRewardNum.getPayMoney(), acDrawRewardNumParam.getPayNum());
        queryPaySpendDetails(cuMemberAccountExt, toBePaidMoney);
        CuMemberPayAccountVO cuMemberPayAccountVO = BeanUtil.copyProperties(cuMemberAccountExt, CuMemberPayAccountVO.class);
        cuMemberPayAccountVO.setToBePaidMoney(toBePaidMoney);
        return AjaxResult.success(cuMemberPayAccountVO);
    }

    /*
     * @description: 支付抽奖次数
     * @author: sui q
     * @date: 2023/4/27 14:46
     * @param: null null
     **/
    @PostMapping("/pay-draw-num")
    public AjaxResult payDrawLotteryNum(@RequestBody AcDrawRewardNumParam acDrawRewardNumParam) {
        if (acDrawRewardNumParam.getPkBaseId() == null || acDrawRewardNumParam.getPayNum() == null || StringUtils.isEmpty(acDrawRewardNumParam.getPayPwd())) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.REQUIRED_NOT_EMPTY));
        }
        // 获取账户，验证账户
        List<CuMemberAccountExt> cuMemberAccountExtList = acDrawRewardNumService.queryMemberAccountByCondition(getCuMemberAccount());
        if (cuMemberAccountExtList == null || cuMemberAccountExtList.size() == 0) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.CENTER_NOT_EXISTS));
        }
        CuMemberAccountExt cuMemberAccountExt = cuMemberAccountExtList.get(0);
        // 验证密码
        if (!SecurityUtils.matchesPassword(acDrawRewardNumParam.getPayPwd(), cuMemberAccountExt.getPayPwd())) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.MEMBER_PASSWORD_NOT_MATCH));
        }
        AcDrawRewardNumExt acDrawRewardNum = getAcDrawRewardNumExt(acDrawRewardNumParam);
        if (acDrawRewardNum == null || acDrawRewardNum.getTotalSurplusNum() < acDrawRewardNumParam.getPayNum()) {
            return AjaxResult.error(TransactionUtils.getContent(ActivityMsgConstants.DRAW_AVAILABLE_NUMBER));
        }
        // 验证会员账户余额是否足够支付
        queryPaySpendDetails(cuMemberAccountExt, ComputeUtil.computeMultiply(acDrawRewardNum.getPayMoney(), acDrawRewardNumParam.getPayNum()));

        if (cuMemberAccountExt.getIsPayment()) {
            // 支付
            acDrawRewardNumService.payDrawRewardNum(cuMemberAccountExt, acDrawRewardNumParam.getPayNum(), acDrawRewardNum);
            return AjaxResult.success();
        }
        // 余额不足
        return AjaxResult.error(TransactionUtils.getContent(FinanceMsgConstants.BALANCE_NOT_ENOUGH));
    }

    /*
     * @description: 支付抽奖次数
     * @author: sui q
     * @date: 2023/4/27 14:46
     * @param: null null
     **/
    @PostMapping("/online-pay-draw")
    public AjaxResult onLinePayDrawNum(@RequestBody AcDrawRewardNumParam acDrawRewardNumParam) {
        if (acDrawRewardNumParam.getPkBaseId() == null || acDrawRewardNumParam.getPayNum() == null) {
            return AjaxResult.error(TransactionUtils.getContent(MemberMsgConstants.REQUIRED_NOT_EMPTY));
        }
        AcDrawRewardNumExt acDrawRewardNum = getAcDrawRewardNumExt(acDrawRewardNumParam);
        if (acDrawRewardNum == null || acDrawRewardNum.getTotalSurplusNum() < acDrawRewardNumParam.getPayNum()) {
            return AjaxResult.error(TransactionUtils.getContent(ActivityMsgConstants.DRAW_AVAILABLE_NUMBER));
        }
        String orderCode = acDrawRewardNumService.confirmDrawRewardPayNum(acDrawRewardNumParam, acDrawRewardNum);
        return AjaxResult.success(CuMemberPayAccountVO.builder().actCode(orderCode).build());
    }

    private AcDrawRewardNumExt getAcDrawRewardNumExt(AcDrawRewardNumParam acDrawRewardNumParam) {
        acDrawRewardNumParam.setPkCountry(SecurityUtils.getPkCountry());
        acDrawRewardNumParam.setPkMember(SecurityUtils.getUserId());
        // 验证购买次数
        return acDrawRewardNumService.queryDrawRewardNumByCondition(acDrawRewardNumParam);
    }

    private CuMemberAccount getCuMemberAccount() {
        CuMemberAccount cuMemberAccount = CuMemberAccount.builder().pkMember(SecurityUtils.getUserId()).build();
        cuMemberAccount.setPkCountry(SecurityUtils.getPkCountry());
        return cuMemberAccount;
    }

    public void queryPaySpendDetails(CuMemberAccountExt cuMemberAccountExt, BigDecimal payMoney) {
        if (ComputeUtil.compareValue(cuMemberAccountExt.getAccount1(), payMoney)) {
            cuMemberAccountExt.setIsPayment(Boolean.TRUE);
        } else {
            cuMemberAccountExt.setIsPayment(Boolean.FALSE);
        }
        cuMemberAccountExt.setPayAccount1(payMoney);
    }
}
