package com.slodon.b2b2c.controller.promotion.admin;

import com.slodon.b2b2c.aop.OperationLogger;
import com.slodon.b2b2c.core.constant.DrawConst;
import com.slodon.b2b2c.core.constant.RedisConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.UserUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.model.promotion.DrawModel;
import com.slodon.b2b2c.model.promotion.DrawPrizeModel;
import com.slodon.b2b2c.model.promotion.DrawRecordModel;
import com.slodon.b2b2c.promotion.dto.DrawDTO;
import com.slodon.b2b2c.promotion.example.DrawExample;
import com.slodon.b2b2c.promotion.example.DrawPrizeExample;
import com.slodon.b2b2c.promotion.example.DrawRecordExample;
import com.slodon.b2b2c.promotion.pojo.Draw;
import com.slodon.b2b2c.promotion.pojo.DrawPrize;
import com.slodon.b2b2c.promotion.pojo.DrawRecord;
import com.slodon.b2b2c.system.pojo.Admin;
import com.slodon.b2b2c.vo.promotion.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Api(tags = "admin-抽奖")
@RestController
@Slf4j
@RequestMapping("v3/promotion/admin/draw")
public class AdminDrawController extends BaseController {

    @Resource
    private DrawModel drawModel;
    @Resource
    private DrawPrizeModel drawPrizeModel;
    @Resource
    private DrawRecordModel drawRecordModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @ApiOperation("抽奖列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "drawType", value = "抽奖活动类型，1-幸运抽奖，2-大转盘，3-刮刮卡，4-摇一摇，5-翻翻看", paramType = "query"),
            @ApiImplicitParam(name = "drawName", value = "抽奖活动名称", paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "活动开始时间", paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "活动结束时间", paramType = "query"),
            @ApiImplicitParam(name = "state", value = "活动状态(1-未开始;2-进行中;3-已结束)", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("list")
    public JsonResult<PageVO<DrawVO>> list(HttpServletRequest request, Integer drawType, String drawName, Date startTime,
                                           Date endTime, Integer state) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        DrawExample example = new DrawExample();
        example.setDrawType(drawType);
        example.setDrawNameLike(drawName);
        example.setStartTimeBefore(endTime);
        example.setEndTimeAfter(startTime);
        if (!StringUtil.isNullOrZero(state)) {
            if (state == DrawConst.STATE_1) {
                //未开始
                example.setStartTimeAfter(new Date());
            } else if (state == DrawConst.STATE_2) {
                //进行中
                example.setStartTimeBefore(new Date());
                example.setEndTimeAfter(new Date());
            } else if (state == DrawConst.STATE_3) {
                //已结束
                example.setEndTimeBefore(new Date());
            }
        }
        List<Draw> list = drawModel.getDrawList(example, pager);
        List<DrawVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(draw -> {
                DrawVO vo = new DrawVO(draw);
                //抽奖人数
                DrawRecordExample recordExample = new DrawRecordExample();
                recordExample.setDrawId(draw.getDrawId());
                vo.setDrawNum(drawRecordModel.getDrawRecordCount(recordExample));
                //中奖人数
                recordExample.setIsPrize(DrawConst.IS_PRIZE_1);
                vo.setPrizeNum(drawRecordModel.getDrawRecordCount(recordExample));
                vos.add(vo);
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("抽奖列表(装修使用)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "drawType", value = "抽奖活动类型，1-幸运抽奖，2-大转盘，3-刮刮卡，4-摇一摇，5-翻翻看", paramType = "query"),
            @ApiImplicitParam(name = "drawName", value = "抽奖活动名称", paramType = "query"),
            @ApiImplicitParam(name = "state", value = "活动状态(1-未开始;2-进行中)", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("drawList")
    public JsonResult<PageVO<DrawListVO>> drawList(HttpServletRequest request, Integer drawType, String drawName, Integer state) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        DrawExample example = new DrawExample();
        example.setDrawType(drawType);
        example.setDrawNameLike(drawName);
        if (!StringUtil.isNullOrZero(state)) {
            if (state == DrawConst.STATE_1) {
                //未开始
                example.setStartTimeAfter(new Date());
            } else if (state == DrawConst.STATE_2) {
                //进行中
                example.setStartTimeBefore(new Date());
            }
        }
        example.setEndTimeAfter(new Date());
        List<Draw> list = drawModel.getDrawList(example, pager);
        List<DrawListVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(draw -> {
                vos.add(new DrawListVO(draw));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("中奖列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "drawId", value = "抽奖活动id", paramType = "query", required = true),
            @ApiImplicitParam(name = "memberName", value = "会员名称", paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "抽奖开始时间", paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "抽奖结束时间", paramType = "query"),
            @ApiImplicitParam(name = "isPrize", value = "中奖状态(0-未中奖，1-中奖)", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("drawRecordList")
    public JsonResult<PageVO<DrawRecordVO>> drawRecordList(HttpServletRequest request, Integer drawId, String memberName, Date startTime,
                                                           Date endTime, Integer isPrize) {
        AssertUtil.notNullOrZero(drawId, "抽奖活动id不能为空");
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        DrawRecordExample example = new DrawRecordExample();
        example.setDrawId(drawId);
        example.setMemberNameLike(memberName);
        example.setRecordTimeAfter(startTime);
        example.setRecordTimeBefore(endTime);
        example.setIsPrize(isPrize);
        List<DrawRecord> list = drawRecordModel.getDrawRecordList(example, pager);
        List<DrawRecordVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(drawRecord -> {
                DrawRecordVO vo = new DrawRecordVO(drawRecord);
                vos.add(vo);
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("抽奖详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "drawId", value = "抽奖活动id", paramType = "query", required = true)
    })
    @GetMapping("detail")
    public JsonResult<DrawDetailVO> detail(HttpServletRequest request, Integer drawId) {
        AssertUtil.notNullOrZero(drawId, "抽奖活动id不能为空");
        Draw draw = drawModel.getDrawByDrawId(drawId);
        AssertUtil.notNull(draw, "查询的抽奖信息为空");
        DrawDetailVO vo = new DrawDetailVO(draw);

        DrawPrizeExample example = new DrawPrizeExample();
        example.setDrawId(drawId);
        example.setOrderBy("prize_id ASC");
        List<DrawPrize> list = drawPrizeModel.getDrawPrizeList(example, null);
        ArrayList<DrawPrizeVO> drawPrizeVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(drawPrize -> {
                DrawPrizeVO prizeVO = new DrawPrizeVO(drawPrize);
                drawPrizeVOList.add(prizeVO);
            });
            vo.setDrawPrizeVOList(drawPrizeVOList);
        }
        return SldResponse.success(vo);
    }

    @ApiOperation("新建抽奖活动")
    @OperationLogger(option = "新建抽奖活动")
    @PostMapping("add")
    public JsonResult addDraw(HttpServletRequest request, @RequestBody DrawDTO drawDTO) {

        Admin admin = UserUtil.getUser(request, Admin.class);
        check(drawDTO);
        drawModel.saveDraw(drawDTO, admin.getAdminId());
        return SldResponse.success("添加成功");
    }

    @ApiOperation("编辑抽奖活动")
    @OperationLogger(option = "编辑抽奖活动")
    @PostMapping("update")
    public JsonResult updateDraw(HttpServletRequest request, @RequestBody DrawDTO drawDTO) {
        Admin admin = UserUtil.getUser(request, Admin.class);
        //参数校验
        check(drawDTO);
        AssertUtil.notNullOrZero(drawDTO.getDrawId(), "抽奖活动id不能为空");
        drawModel.updateDraw(drawDTO);
        return SldResponse.success("编辑成功");
    }

    @ApiOperation("删除抽奖活动")
    @OperationLogger(option = "删除抽奖活动")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "drawId", value = "抽奖活动id", paramType = "query", required = true)
    })
    @PostMapping("del")
    public JsonResult delDraw(HttpServletRequest request, Integer drawId) {
        AssertUtil.notNullOrZero(drawId, "抽奖活动id不能为空");
        drawModel.deleteDrawWithDrawPrize(drawId);

        //删除redis数据
        stringRedisTemplate.delete(RedisConst.DRAW_PREFIX + drawId);
        return SldResponse.success("删除成功");
    }

    public void check(DrawDTO drawDTO) {
        //参数校验
        AssertUtil.notNull(drawDTO, "抽奖活动信息不能为空");
        List<DrawDTO.DrawPrizeInfo> drawPrizeInfoList = drawDTO.getDrawPrizeInfoList();
        AssertUtil.isTrue(CollectionUtils.isEmpty(drawPrizeInfoList), "奖项设置信息不能为空");
        AssertUtil.isTrue(drawDTO.getIntegralUse() > 1000000, "单次消耗积分最大输入1000000");
        AssertUtil.isTrue(drawDTO.getRuleNum() > 1000000, "活动规则次数最大输入1000000");

        AssertUtil.isTrue(drawPrizeInfoList.size() > 6, "同一个活动下最多设置6个奖项,请重试");
        BigDecimal totalRate = BigDecimal.ZERO;
        drawPrizeInfoList.forEach(drawPrizeInfo -> {
            AssertUtil.isTrue(drawPrizeInfo.getRate() < 0, "奖项的中奖率输入大于等于1");
            AssertUtil.isTrue(drawPrizeInfo.getRate() > 100, "同一个活动下奖项的中奖率相加需小于等于100%");
            AssertUtil.isTrue(drawPrizeInfo.getPrizeNum() > 1000000, "活动规则次数最大输入1000000");
        });
        AssertUtil.isTrue(!drawDTO.getEndTime().after(drawDTO.getStartTime()), "活动结束时间必须大于开始时间");
    }
}
