
package com.tmerclub.cloud.distribution.controller.app;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.tmerclub.cloud.api.auth.bo.LoginInfoBO;
import com.tmerclub.cloud.api.auth.bo.UidInfoBO;
import com.tmerclub.cloud.api.auth.constant.SocialType;
import com.tmerclub.cloud.api.auth.feign.AuthSocialFeignClient;
import com.tmerclub.cloud.api.auth.feign.TokenFeignClient;
import com.tmerclub.cloud.api.auth.vo.AuthSocialVO;
import com.tmerclub.cloud.api.platform.vo.DistributionConfigApiVO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.distribution.constant.DistributionUserStateEnum;
import com.tmerclub.cloud.distribution.dto.AppDistributionWithdrawCashDTO;
import com.tmerclub.cloud.distribution.dto.RangeTimeDTO;
import com.tmerclub.cloud.distribution.model.DistributionUserWallet;
import com.tmerclub.cloud.distribution.service.DistributionConfigService;
import com.tmerclub.cloud.distribution.service.DistributionUserService;
import com.tmerclub.cloud.distribution.service.DistributionUserWalletService;
import com.tmerclub.cloud.distribution.service.DistributionWithdrawCashService;
import com.tmerclub.cloud.distribution.vo.AppDistributionWithdrawCashLogVO;
import com.tmerclub.cloud.distribution.vo.AppDistributionWithdrawCashVO;
import com.tmerclub.cloud.distribution.vo.DistributionUserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 分销员提现记录
 *
 * @author cl
 * @date 2021-08-09 14:14:10
 */
@RestController("appDistributionWithdrawCashController")
@RequestMapping("/distribution_withdraw_cash")
@Tag(name = "分销员提现记录")
public class DistributionWithdrawCashController {

    @Autowired
    private DistributionWithdrawCashService distributionWithdrawCashService;
    @Autowired
    private DistributionUserService distributionUserService;
    @Autowired
    private DistributionConfigService distributionConfigService;
    @Autowired
    private DistributionUserWalletService distributionUserWalletService;
    @DubboReference
    private AuthSocialFeignClient authSocialFeignClient;
    @DubboReference
    private TokenFeignClient tokenFeignClient;

    @GetMapping("/page")
    @Operation(summary = "获取分销员提现记录列表", description = "分页获取分销员提现记录列表")
    public ServerResponseEntity<PageVO<AppDistributionWithdrawCashLogVO>> pageByUserId(@Valid PageDTO pageDTO) {
        Long userId = AuthUserContext.get().getUserId();
        DistributionUserVO distributionUserVO = distributionUserService.getByUserId(userId);
        if (Objects.isNull(distributionUserVO)) {
            // 您还不是分销员
            throw new LuckException("您还不是分销员");
        }
        PageVO<AppDistributionWithdrawCashVO> distributionWithdrawCashPage = distributionWithdrawCashService.pageByDistributionUserId(pageDTO, distributionUserVO.getDistributionUserId());
        // 将结果封装一下，以年月为分界线处理,
        PageVO<AppDistributionWithdrawCashLogVO> resPageVO = handleGroupByYearAndMonth(distributionWithdrawCashPage);
        return ServerResponseEntity.success(resPageVO);
    }

    private PageVO<AppDistributionWithdrawCashLogVO> handleGroupByYearAndMonth(PageVO<AppDistributionWithdrawCashVO> distributionWithdrawCashPage) {
        PageVO<AppDistributionWithdrawCashLogVO> resPage = new PageVO<>();
        resPage.setTotal(distributionWithdrawCashPage.getTotal());
        resPage.setPages(distributionWithdrawCashPage.getPages());
        List<AppDistributionWithdrawCashVO> list = distributionWithdrawCashPage.getList();
        if (CollUtil.isEmpty(list)) {
            return resPage;
        }
        //  list的必须是已经倒序updateTime排序后的顺序
        // 将日期设置为月开始的第一天，然后直接根据时间进行分组就可以了
        for (AppDistributionWithdrawCashVO withdrawCashVO : list) {
            Date createTime = withdrawCashVO.getCreateTime();
            DateTime beginOfMonth = DateUtil.beginOfMonth(createTime);
            withdrawCashVO.setMonthTimeStr(DateUtil.formatDateTime(beginOfMonth));
        }
        // 分组， 由数据库update_time字段设计，不可能为空，无需做为空处理
        Map<String, List<AppDistributionWithdrawCashVO>> listMap = list.stream().collect(Collectors.groupingBy(AppDistributionWithdrawCashVO::getMonthTimeStr));
        // 为改变前的数据
        List<AppDistributionWithdrawCashLogVO> resList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (String dateStr : listMap.keySet()) {
            AppDistributionWithdrawCashLogVO logVO = new AppDistributionWithdrawCashLogVO();
            logVO.setDate(DateUtil.parseDate(dateStr));
            logVO.setDistributionWithdrawCashList(listMap.get(dateStr));
            resList.add(logVO);
        }
        resPage.setList(resList.stream().sorted(Comparator.comparing(AppDistributionWithdrawCashLogVO::getDate).reversed()).collect(Collectors.toList()));
        return resPage;
    }


    @PostMapping("/apply")
    @Operation(summary = "用户发起提现申请", description = "填入提现参数")
    public ServerResponseEntity<Void> apply(@Valid @RequestBody AppDistributionWithdrawCashDTO distributionWithdrawCashDTO) {
        LoginInfoBO loginInfoBO = tokenFeignClient.getLoginInfo();
        Long userId = AuthUserContext.getUserId();
        UidInfoBO uidInfoBO = AuthUserContext.get();
        String uid = AuthUserContext.getUid(uidInfoBO);
        DistributionUserVO distributionUserVO = distributionUserService.getByUserId(userId);
        if (Objects.isNull(distributionUserVO)) {
            // 您还不是分销员
            throw new LuckException("您还不是分销员");
        }
        if (!Objects.equals(distributionUserVO.getState(), DistributionUserStateEnum.NORMAL.value())) {
            // 您的分销身份异常，请联系管理员
            throw new LuckException("您的分销身份异常，请联系管理员");
        }
        AuthSocialVO authSocialVO = authSocialFeignClient.getByUserIdAndSocialType(loginInfoBO.getBizUserId(), SocialType.MA.value()).getData();

        if (Objects.isNull(authSocialVO)) {
            throw new LuckException("您未绑定微信，请先在微信小程序授权登录后再提现");
        }
        //发起提现
        distributionWithdrawCashService.apply(distributionWithdrawCashDTO, distributionUserVO, authSocialVO);
        return ServerResponseEntity.success();
    }

    @GetMapping("/isWithdrawCash")
    @Operation(summary = "当前是否可以提现")
    public ServerResponseEntity<Boolean> isWithdrawCash() {
        Long userId = AuthUserContext.get().getUserId();
        DistributionUserVO distributionUserVO = distributionUserService.getByUserId(userId);
        Long distributionUserId = distributionUserVO.getDistributionUserId();
        //获取店铺提现设置
        DistributionConfigApiVO distributionConfig = distributionConfigService.getDistributionConfig();
        //获取店铺设置的提现频率算出时间区间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - distributionConfig.getFrequency());
        //获取玩家最近的提现次数
        //判断是否能够提现
        Integer count = distributionWithdrawCashService.getCountByRangeTimeAndDistributionUserId(new RangeTimeDTO(calendar.getTime(), new Date()), distributionUserId);
        if (count >= distributionConfig.getNumber()) {
            // 提现次数为x天x次
            throw new LuckException("提现次数为" + distributionConfig.getFrequency() + "天" + distributionConfig.getNumber() + "次");
        }
        return ServerResponseEntity.success(true);
    }

    @GetMapping("/getUserTotalWithdrawCash")
    @Operation(summary = "查看用户总提现金额")
    public ServerResponseEntity<Long> getUserTotalWithdrawCash() {
        Long userId = AuthUserContext.get().getUserId();
        DistributionUserVO distributionUserVO = distributionUserService.getByUserId(userId);
        if (Objects.isNull(distributionUserVO)) {
            // 您还不是分销员
            throw new LuckException("您还不是分销员");
        }
        Long distributionUserId = distributionUserVO.getDistributionUserId();
        DistributionUserWallet distributionUserWallet = distributionUserWalletService.getByDistributionUserId(distributionUserId);
        Long totalWithdrawCash = distributionWithdrawCashService.getUserTotalWithdrawCash(distributionUserWallet.getWalletId());
        return ServerResponseEntity.success(totalWithdrawCash);
    }

}
