package com.liquidnet.service.platform.controller.candy.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.candy.constant.CandyRedisConst;
import com.liquidnet.service.candy.dto.CandyCouponCodeDto;
import com.liquidnet.service.candy.dto.CandyCouponInfoDto;
import com.liquidnet.service.candy.dto.CandyCouponRuleDto;
import com.liquidnet.service.candy.dto.CandyUserCouponBasicDto;
import com.liquidnet.service.candy.entity.*;
import com.liquidnet.service.platform.service.impl.adam.dm.DMRdmService;
import com.liquidnet.service.platform.service.impl.candy.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("candy/task")
public class CandyMgtCouponTaskController {
    @Autowired
    private PlatformCandyMgtCouponService platformCandyMgtCouponService;
    @Autowired
    private PlatformCandyCouponService platformCandyCouponService;
    @Autowired
    private PlatformCandyCouponRuleService platformCandyCouponRuleService;
    @Autowired
    private PlatformCandyCouponCodeService platformCandyCouponCodeService;
    @Autowired
    private PlatformCandyUserCouponService platformCandyUserCouponService;
    @Autowired
    private DMRdmService dmRdmService;
    @Autowired
    private RedisUtil redisUtil;

    @PostMapping("issue/coupons")
    public void issueCoupons() {
        LambdaQueryWrapper<CandyMgtCoupon> queryWrapper = Wrappers.lambdaQuery(CandyMgtCoupon.class)
                .eq(CandyMgtCoupon::getState, 0)
                .orderByAsc(CandyMgtCoupon::getEventAt);
        List<CandyMgtCoupon> list = platformCandyMgtCouponService.list(queryWrapper);
        int taskSize = CollectionUtils.isEmpty(list) ? 0 : list.size();
        log.info("issue coupons taskSize:{}", taskSize);

        LambdaQueryWrapper<CandyCoupon> couponQueryWrapper = Wrappers.lambdaQuery(CandyCoupon.class).eq(CandyCoupon::getState, 1);
        LambdaQueryWrapper<CandyCouponRule> couponRuleQueryWrapper = Wrappers.lambdaQuery(CandyCouponRule.class).eq(CandyCouponRule::getState, 1);
        for (int i = 0; i < taskSize; i++) {
            LocalDateTime now = LocalDateTime.now();

            CandyMgtCoupon mgtCoupon = list.get(i);
            CandyCoupon coupon = platformCandyCouponService.getOne(couponQueryWrapper.eq(CandyCoupon::getCouponId, mgtCoupon.getCouponId()));

            List<CandyCouponRuleDto> couponRuleDtoList = platformCandyCouponRuleService.listForCouponRuleDto(coupon.getCouponId());


            List<CandyCouponCode> initCouponCodeList = new ArrayList<>();
            List<CandyUserCoupon> initUserCouponList = new ArrayList<>();
            Integer eventAmt = mgtCoupon.getEventAmt();
            for (int j = 0; j < eventAmt; j++) {
                switch (coupon.getCouType()) {
                    case 1:
                        String uid = dmRdmService.getUidByMobile("17701223310");
                        if (StringUtils.isNotEmpty(uid)) {
                            CandyUserCoupon userCoupon = new CandyUserCoupon();
                            userCoupon.setUcouponId(IDGenerator.get32UUID());
                            userCoupon.setMcouponId(mgtCoupon.getMcouponId());
                            userCoupon.setUid(uid);
                            userCoupon.setCouponId(coupon.getCouponId());
                            userCoupon.setState(1);
                            userCoupon.setBindAt(now);

                            initUserCouponList.add(userCoupon);
                        }
                        break;
                    case 2:
                        break;
                    case 3:// 兑换券
                        CandyCouponCode couponCode = new CandyCouponCode();
                        couponCode.setCcode(RandomStringUtils.randomAlphanumeric(16));
                        couponCode.setCouponId(coupon.getCouponId());
                        couponCode.setState(0);
                        couponCode.setCreatedAt(now);

                        initCouponCodeList.add(couponCode);
                        break;
                    case 4:
                        break;
                    default:
                        log.warn("Invalid operation[mcouponId:{},couType:{}]", mgtCoupon.getMcouponId(), coupon.getCouType());
                        break;
                }
            }


            if (!initUserCouponList.isEmpty() && platformCandyUserCouponService.saveBatch(initUserCouponList)) {
                CandyCouponInfoDto couponInfoDto = new CandyCouponInfoDto();
                BeanUtils.copyProperties(coupon, couponInfoDto);
                couponInfoDto.setUseRules(couponRuleDtoList);

                String key = CandyRedisConst.BASIC_COUPON_INFO.concat(couponInfoDto.getCouponId());
                redisUtil.set(key, couponInfoDto);

                initUserCouponList.forEach(r -> {
                    String uckey = CandyRedisConst.BASIC_USER_COUPON.concat(r.getUid());

                    List<CandyUserCouponBasicDto> vos = (List<CandyUserCouponBasicDto>) redisUtil.get(uckey);

                    if (CollectionUtils.isEmpty(vos)) {
                        vos = new ArrayList<>();
                    }
                    vos.add(CandyUserCouponBasicDto.getNew().copy(r, coupon, couponRuleDtoList));

                    redisUtil.set(uckey, vos);
                });
            }

            if (!initCouponCodeList.isEmpty() && platformCandyCouponCodeService.saveBatch(initCouponCodeList)) {
                CandyCouponInfoDto couponInfoDto = new CandyCouponInfoDto();
                BeanUtils.copyProperties(coupon, couponInfoDto);
                couponInfoDto.setUseRules(couponRuleDtoList);

                String key = CandyRedisConst.BASIC_COUPON_INFO.concat(couponInfoDto.getCouponId());
                redisUtil.set(key, couponInfoDto);

                initCouponCodeList.forEach(r -> {
                    redisUtil.set(CandyRedisConst.BASIC_COUPON_CODE.concat(r.getCcode()), CandyCouponCodeDto.getNew().copy(r));
                });
            }

            mgtCoupon.setState(1);
            LambdaUpdateWrapper<CandyMgtCoupon> mgtCouponUpdateWrapper = Wrappers.lambdaUpdate(CandyMgtCoupon.class).eq(CandyMgtCoupon::getMcouponId, mgtCoupon.getMcouponId());
            boolean update = platformCandyMgtCouponService.update(mgtCoupon, mgtCouponUpdateWrapper);
            log.info("issue coupons mcouponId:{} ~ {}", mgtCoupon.getMcouponId(), update);
        }
    }
}
