package com.qs.mp.web.controller.api.admin;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.qs.mp.admin.domain.*;
import com.qs.mp.admin.domain.excel.CdKeyOrderExcel;
import com.qs.mp.admin.domain.param.CdKeyActivateParam;
import com.qs.mp.admin.domain.param.CdKeyCreateParam;
import com.qs.mp.admin.domain.param.CdKeyExportParam;
import com.qs.mp.admin.domain.param.CdKeyQueryParam;
import com.qs.mp.admin.domain.vo.CdKeyExchangeVO;
import com.qs.mp.admin.domain.vo.CdKeyGroupListVO;
import com.qs.mp.admin.domain.vo.CdKeyGroupVO;
import com.qs.mp.admin.domain.vo.CdKeyVO;
import com.qs.mp.admin.service.*;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.page.TableDataInfo;
import com.qs.mp.common.enums.CdKeyGroupGoodsTypeEnum;
import com.qs.mp.common.enums.CdKeyGroupStatusEnum;
import com.qs.mp.common.enums.CdKeyStatusEnum;
import com.qs.mp.common.enums.ValidityPeriodEnum;
import com.qs.mp.common.utils.DateUtils;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.utils.ExcelUtil;
import com.qs.mp.web.controller.BaseController;
import io.swagger.annotations.*;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author zhangkaikai
 * @create 2023-05-16 10:16 AM
 **/
@Api(tags = "兑换码管理API")
@RestController
@RequestMapping("/api/v1/mp/admin/CdKey/*")
public class CdKeyMgrController extends BaseController {


    @Autowired
    private ICdKeyGroupService cdKeyGroupService;

    @Autowired
    private ICdKeyGroupGoodsService cdKeyGroupGoodsService;

    @Autowired
    private ICdKeyService cdKeyService;

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private IChannelService channelService;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private ICouponService couponService;

    @Autowired
    private ICouponPkgService couponPkgService;

    @Value("${cloud.public-bucket-name}")
    private String publicBucketName;

    @Value("${cloud.region}")
    private String region;


    @ApiOperation("兑换码生成")
    @PreAuthorize("@ss.hasPermi('business:cdKey:add')")
    @PostMapping("/create")
    public AjaxResult create(@Validated @RequestBody CdKeyCreateParam param) {
        String groupId = cdKeyGroupService.createCdKeyGroup(param);
        if (StringUtils.isNotBlank(groupId)) {
            return AjaxResult.success();
        }
        return AjaxResult.error("生成兑换码失败");
    }

    @ApiOperation("查询所有兑换码组列表")
    @PreAuthorize("@ss.hasPermi('business:cdKey:list')")
    @PostMapping("/list")
    @ApiResponses(
            @ApiResponse(code = 200, message = "查询成功", response = CdKeyGroupListVO.class)
    )
    public TableDataInfo list(@RequestBody CdKeyQueryParam param) {

        QueryWrapper<CdKeyGroup> queryWrapper = new QueryWrapper<>();

        if (Objects.nonNull(param.getCreateTimeStart()) && Objects.nonNull(param.getCreateTimeEnd())) {
            queryWrapper.between("created_time", param.getCreateTimeStart(), param.getCreateTimeEnd());
        }

        if (Objects.nonNull(param.getActiveTimeStart()) && Objects.nonNull(param.getActiveTimeEnd())) {
            queryWrapper.between("activation_time", param.getActiveTimeStart(), param.getActiveTimeEnd());
        }

        if (Objects.nonNull(param.getMinCdKeyNum()) && Objects.nonNull(param.getMaxCdKeyNum())) {
            queryWrapper.between("quantity", param.getMinCdKeyNum(), param.getMaxCdKeyNum());
        }

        if (Objects.nonNull(param.getChannelId())) {
            queryWrapper.eq("channel_id", param.getChannelId());
        }

        if (Objects.nonNull(param.getStatus())) {
            queryWrapper.eq("status", param.getStatus());
        }

        if (StringUtils.isNotEmpty(param.getTitle())) {
            queryWrapper.like("title", param.getTitle());
        }
        queryWrapper.orderByAsc("FIELD(`status`,'waiting','noactive','activated','invalid')");
        queryWrapper.orderByDesc("created_time");

        startPage();
        List<CdKeyGroupVO> cdKeyGroupList = cdKeyGroupService.listCdKeyGroupListVO(queryWrapper);
        List<CdKeyGroup> inValid = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(cdKeyGroupList)) {
            cdKeyGroupList.forEach(cdKeyGroupVO -> {
                        Channel channel = channelService.getById(cdKeyGroupVO.getChannelId());
                        String siteName = channel.getName() == null ? "--   " : channel.getName();
                        cdKeyGroupVO.setSiteName(siteName + "(" + channel.getMobile() + ")");
                        if (CdKeyGroupStatusEnum.ACTIVATED == cdKeyGroupVO.getStatus()) {
                            int validityPeriod = ValidityPeriodEnum.getByValue(cdKeyGroupVO.getValidityPeriod().getValue());
                            if (validityPeriod == 3 && DateUtils.diffMonth(cdKeyGroupVO.getActivationTime(), new Date()) >= 3) {
                                CdKeyGroup cdKeyGroup = new CdKeyGroup();
                                cdKeyGroup.setGroupId(cdKeyGroupVO.getGroupId());
                                cdKeyGroup.setStatus(CdKeyGroupStatusEnum.INVALID);
                                inValid.add(cdKeyGroup);
                                cdKeyGroupVO.setStatus(CdKeyGroupStatusEnum.INVALID);
                            }
                            if (validityPeriod == 6 && DateUtils.diffMonth(cdKeyGroupVO.getActivationTime(), new Date()) >= 6) {
                                CdKeyGroup cdKeyGroup = new CdKeyGroup();
                                cdKeyGroup.setGroupId(cdKeyGroupVO.getGroupId());
                                cdKeyGroup.setStatus(CdKeyGroupStatusEnum.INVALID);
                                inValid.add(cdKeyGroup);
                                cdKeyGroupVO.setStatus(CdKeyGroupStatusEnum.INVALID);
                            }
                }
            });
        }
        if (CollectionUtils.isNotEmpty(inValid)) {
            cdKeyGroupService.updateBatchById(inValid);
        }
        return getDataTable(cdKeyGroupList);
    }

    @ApiOperation("兑换码详情")
    @PreAuthorize("@ss.hasPermi('business:cdKey:query')")
    @PostMapping("/detail/{groupId}")
    @ApiResponses(
            @ApiResponse(code = 200, message = "查询成功", response = CdKeyGroupVO.class)
    )
    public AjaxResult detail(@PathVariable String groupId) {
        CdKeyGroup cdKeyGroup = cdKeyGroupService.getById(groupId);
        CdKeyGroupVO cdKeyGroupVO = mapperFacade.map(cdKeyGroup, CdKeyGroupVO.class);
        List<CdKeyGroupGoods> goodsList = cdKeyGroupGoodsService.list(new QueryWrapper<CdKeyGroupGoods>().eq("group_id", groupId));
        goodsList.forEach(g ->{
            if (StringUtils.isNotEmpty(g.getRefId())) {
                if (CdKeyGroupGoodsTypeEnum.GOODS.equals(g.getType())) {
                    Goods goods = goodsService.getById(g.getRefId());
                    g.setTitle(goods.getTitle());
                    g.setPicUrl(goods.getPicUrl());
                } else if (CdKeyGroupGoodsTypeEnum.COUPON.equals(g.getType())) {
                    Coupon coupon = couponService.getById(g.getRefId());
                    g.setTitle(coupon.getTitle());
                    g.setPicUrl(coupon.getPicUrl());
                } else if (CdKeyGroupGoodsTypeEnum.COUPON_PKG.equals(g.getType())) {
                    CouponPkg couponPkg = couponPkgService.getById(g.getRefId());
                    g.setTitle(couponPkg.getTitle());
                    g.setPicUrl(couponPkg.getPicUrl());
                }

            }
        });
        cdKeyGroupVO.setGoodsList(goodsList);
        return AjaxResult.success(cdKeyGroupVO);
    }

    @ApiOperation("激活兑换码")
    @PreAuthorize("@ss.hasPermi('business:cdKey:activate')")
    @PostMapping("/activate")
    public AjaxResult activate(@RequestBody CdKeyActivateParam param) {
        CdKeyGroup cdKeyGroup = cdKeyGroupService.getById(param.getGroupId());
        if (!CdKeyGroupStatusEnum.NO_ACTIVE.getValue().equals(cdKeyGroup.getStatus().getValue())) {
            return AjaxResult.error("只有未激活的兑换码组才能激活");
        }
        cdKeyGroup.setStatus(param.getIsActive() == 1 ? CdKeyGroupStatusEnum.ACTIVATED : CdKeyGroupStatusEnum.NO_ACTIVE);
        cdKeyGroup.setActivationTime(new Date());
        return AjaxResult.success(cdKeyGroupService.updateById(cdKeyGroup));
    }

    @ApiOperation("查看兑换码兑换详情")
    @PreAuthorize("@ss.hasPermi('business:cdKey:query')")
    @PostMapping("/exchangeDetail/{groupId}")
    @ApiResponses(
            @ApiResponse(code = 200, message = "查询成功", response = CdKeyExchangeVO.class)
    )
    public TableDataInfo exchangeDetail(@PathVariable String groupId) {
        List<CdKey> cdKeyList = cdKeyService.list(new QueryWrapper<CdKey>().eq("group_id", groupId));
        long unCashedCount = cdKeyList.stream().filter(cdKey -> CdKeyStatusEnum.UNCASHED.getValue().equals(cdKey.getStatus())).count();
        long cashedCount = cdKeyList.stream().filter(cdKey -> CdKeyStatusEnum.CASHED.getValue().equals(cdKey.getStatus())).count();
        startPage();
        List<CdKeyExchangeVO> cdKeyExchangeVOList = cdKeyService.listCdKeyExchangeVO(new QueryWrapper<CdKey>().eq("t1.group_id", groupId).orderByDesc("t2.exchange_time"));
        cdKeyExchangeVOList.forEach(cdKeyExchangeVO -> {
            cdKeyExchangeVO.setRemainQty((int) unCashedCount);
            cdKeyExchangeVO.setCashedQty((int) cashedCount);
            if (StringUtils.isNotEmpty(cdKeyExchangeVO.getRefId())) {
                if (CdKeyGroupGoodsTypeEnum.GOODS.equals(cdKeyExchangeVO.getType())) {
                    Goods goods = goodsService.getById(cdKeyExchangeVO.getRefId());
                    cdKeyExchangeVO.setGoodsName(goods.getTitle());
                    cdKeyExchangeVO.setPicUrl(goods.getPicUrl());
                } else if (CdKeyGroupGoodsTypeEnum.COUPON.equals(cdKeyExchangeVO.getType())) {
                    Coupon coupon = couponService.getById(cdKeyExchangeVO.getRefId());
                    cdKeyExchangeVO.setGoodsName(coupon.getTitle());
                    cdKeyExchangeVO.setPicUrl(coupon.getPicUrl());
                } else if (CdKeyGroupGoodsTypeEnum.COUPON_PKG.equals(cdKeyExchangeVO.getType())) {
                    CouponPkg couponPkg = couponPkgService.getById(cdKeyExchangeVO.getRefId());
                    cdKeyExchangeVO.setGoodsName(couponPkg.getTitle());
                    cdKeyExchangeVO.setPicUrl(couponPkg.getPicUrl());
                }
            }
        });
        return getDataTable(cdKeyExchangeVOList);

    }

    @ApiOperation("导出兑换码订单")
    @PreAuthorize("@ss.hasPermi('business:cdKey:export')")
    @PostMapping("/export")
    public AjaxResult export(@RequestBody CdKeyExportParam param) {
        List<CdKeyVO> cdKeyExportList = cdKeyService.listExportVO(new QueryWrapper<CdKey>().in("t1.group_id", param.getGroupIdList()));
        List<CdKeyOrderExcel> excelList = new ArrayList<>();
        cdKeyExportList.forEach(CdKeyVO -> {
            CdKeyOrderExcel cdKeyOrderExcel = new CdKeyOrderExcel();
            cdKeyOrderExcel.setCdKey(CdKeyVO.getCdKey());
            if (CdKeyGroupGoodsTypeEnum.COIN.equals(CdKeyVO.getType())) {
                cdKeyOrderExcel.setGoodsName(CdKeyVO.getGoodsName() + " x" + CdKeyVO.getValue());
            } else {
                cdKeyOrderExcel.setGoodsName(CdKeyVO.getGoodsName());
            }
            String picUrl = "https://" + publicBucketName + ".cos." + region + ".myqcloud.com/" + CdKeyVO.getPicUrl();
            cdKeyOrderExcel.setPicUrl(picUrl);
            cdKeyOrderExcel.setStatus(CdKeyVO.getStatus() == 1 ? "已兑换" : "未兑换");
            excelList.add(cdKeyOrderExcel);
        });

        ExcelUtil<CdKeyOrderExcel> excelUtil = new ExcelUtil<>(CdKeyOrderExcel.class);
        return excelUtil.exportExcel(excelList, cdKeyExportList.get(0).getTitle() + "兑换码订单导出", false);
    }
}
