package com.gree.mall.manager.logic.activity;

import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.activity.fullpiece.PromotionFullPieceBean;
import com.gree.mall.manager.bean.activity.fullpiece.PromotionFullPieceListVO;
import com.gree.mall.manager.bean.activity.fullpiece.PromotionFullPieceOrderVO;
import com.gree.mall.manager.bean.activity.fullpiece.PromotionFullPieceVO;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.commonmapper.OrderMapper;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.Goods;
import com.gree.mall.manager.plus.entity.PromotionFullPiece;
import com.gree.mall.manager.plus.entity.PromotionFullPieceGoods;
import com.gree.mall.manager.plus.entity.PromotionFullPieceItem;
import com.gree.mall.manager.plus.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class PromotionFullPieceLogic {

    @Autowired
    CommonLogic commonLogic;
    @Autowired
    GoodsService goodsService;
    @Autowired
    PromotionFullPieceService promotionFullPieceService;
    @Autowired
    PromotionFullPieceItemService promotionFullPieceItemService;
    @Autowired
    PromotionFullPieceGoodsService promotionFullPieceGoodsService;
    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    OrderMapper orderMapper;


    /**
     * 活动列表
     * @param status 1=进行中 2=未开始 3=已过期
     * @param pageNum
     * @param pageSize
     * @return
     */
    public IPage<PromotionFullPieceListVO> list(Integer status, Integer pageNum, Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage page = promotionFullPieceService.lambdaQuery()
                .ge(status != null && status == 1, PromotionFullPiece::getEndTime,new Date())
                .le(status != null && status == 1,PromotionFullPiece::getStartTime,new Date())
                .gt(status != null && status == 2,PromotionFullPiece::getStartTime,new Date())
                .lt(status != null && status == 3,PromotionFullPiece::getEndTime,new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds())
                .orderByDesc(PromotionFullPiece::getCreateTime).page(new Page<>(pageNum, pageSize));

        List<PromotionFullPieceListVO> list = new ArrayList<>();
        for(Object o : page.getRecords()){
            PromotionFullPiece promotionFullPiece = (PromotionFullPiece)o;

            //订单数量，商品数量
            PromotionFullPieceListVO pvo = orderMapper.queryTotalAmountCount(promotionFullPiece.getId());
            BeanUtils.copyProperties(promotionFullPiece,pvo);

            //商品数量
            pvo.setGoodsNum(promotionFullPieceGoodsService.lambdaQuery()
                    .eq(PromotionFullPieceGoods::getPromotionFullPieceId,promotionFullPiece.getId()).count());
            //状态
            pvo.setStatus(this.getStatusByTime(pvo.getStartTime(),pvo.getEndTime()));

            list.add(pvo);
        }
        page.setRecords(list);
        return page;
    }

    /**
     * 根据状态统计活动数量
     */
    public Map<String,Integer> totalByStatus(){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        //未开始
        Integer count1 = promotionFullPieceService.lambdaQuery().gt(PromotionFullPiece::getStartTime, new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds()).count();
        //已过期
        Integer count2 = promotionFullPieceService.lambdaQuery().lt(PromotionFullPiece::getEndTime, new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds()).count();
        //进行中
        Integer count3 = promotionFullPieceService.lambdaQuery().le(PromotionFullPiece::getStartTime, new Date()).ge(PromotionFullPiece::getEndTime, new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds()).count();
        Map<String,Integer> map = new HashMap<>();
        map.put("all",count1+count2+count3);
        map.put("wks",count1);
        map.put("ygq",count2);
        map.put("jxz",count3);
        return map;
    }

    /**
     * 保存活动
     * @param bean
     */
    @Transactional
    public void save(PromotionFullPieceBean bean){

        if(CollectionUtils.isEmpty(bean.getItems())){
            throw new RemoteServiceException("请配置活动规则");
        }
        if(CollectionUtils.isEmpty(bean.getGoodsIds())){
            throw new RemoteServiceException("请选择商品id");
        }
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> notGoodsIds = new ArrayList<>();
        //编辑状态不需要判断自己已有的商品是否存在本活动中
        if(StringUtils.isNotEmpty(bean.getId())){
            List<PromotionFullPieceGoods> list = promotionFullPieceGoodsService.lambdaQuery().eq(PromotionFullPieceGoods::getPromotionFullPieceId, bean.getId()).list();
            notGoodsIds = list.stream().map(PromotionFullPieceGoods::getGoodsId).collect(Collectors.toList());
        }

        Integer count = goodsService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),Goods::getCompanyWechatId,adminUser.getCompanyWechatIds())
                .in(Goods::getGoodsId, bean.getGoodsIds())
                .eq(Goods::getPromotionFullPiece,true)
                .notIn(!CollectionUtils.isEmpty(notGoodsIds), Goods::getGoodsId,notGoodsIds)
                .count();
        if(count > 0)
            throw new RemoteServiceException("同一件商品不可重复参与多个满件打折活动");

        //检查是否已存在时段冲突的活动
        Integer count1 = promotionFullPieceService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds())
                .between(PromotionFullPiece::getStartTime, bean.getStartTime(), bean.getEndTime())
                .ne(StringUtils.isNotEmpty(bean.getId()),PromotionFullPiece::getId,bean.getId()).count();
        Integer count2 = promotionFullPieceService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds())
                .between(PromotionFullPiece::getEndTime, bean.getStartTime(), bean.getEndTime())
                .ne(StringUtils.isNotEmpty(bean.getId()),PromotionFullPiece::getId,bean.getId()).count();
        Integer count3 = promotionFullPieceService.lambdaQuery()
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds())
                .lt(PromotionFullPiece::getStartTime, bean.getStartTime())
                .gt(PromotionFullPiece::getEndTime, bean.getEndTime())
                .ne(StringUtils.isNotEmpty(bean.getId()),PromotionFullPiece::getId,bean.getId()).count();
        if(count1 > 0 || count2 > 0 || count3 > 0){
            throw new RemoteServiceException("同时间段不可重复存在多个满件打折活动");
        }
        //1.保存或更新主表
        bean.setCompanyWechatId(adminUser.getCompanyWechatId());
        bean.setCompanyWechatName(adminUser.getCompanyName());
        bean.setCreateBy(adminUser.getNickName());
        bean.setUpdateBy(adminUser.getNickName());
        bean.setCreateTime(new Date());
        bean.setUpdateTime(new Date());
        promotionFullPieceService.saveOrUpdate(bean);
        //2.保存活动规则(先删后增)
        promotionFullPieceItemService.lambdaUpdate().eq(PromotionFullPieceItem::getPromotionFullPieceId,bean.getId()).remove();
        bean.getItems().forEach(v -> v.setCreateTime(new Date()).setPromotionFullPieceId(bean.getId()));
        promotionFullPieceItemService.saveBatch(bean.getItems());
        //3.保存活动商品(先删后增)
        promotionFullPieceGoodsService.lambdaUpdate().eq(PromotionFullPieceGoods::getPromotionFullPieceId,bean.getId()).remove();
        List<PromotionFullPieceGoods> goodsList = new ArrayList<>();
        for(String goodsId : bean.getGoodsIds()){
            PromotionFullPieceGoods promotionFullPieceGoods = new PromotionFullPieceGoods();
            promotionFullPieceGoods.setPromotionFullPieceId(bean.getId());
            promotionFullPieceGoods.setGoodsId(goodsId);
            promotionFullPieceGoods.setCreateTime(new Date());
            goodsList.add(promotionFullPieceGoods);
        }
        promotionFullPieceGoodsService.saveBatch(goodsList);
        //4.标记满件打折商品
        this.reloadGoodsPromotionFullPiece();
    }


    /**
     * 标识哪些商品为满件活动商品
     */
    @Transactional
    public void reloadGoodsPromotionFullPiece(){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        //1.将所有商品都设为非满件活动的商品
        goodsService.lambdaUpdate().set(Goods::getPromotionFullPiece,false)
                .eq(Goods::getPromotionFullPiece,true)
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),Goods::getCompanyWechatId,adminUser.getCompanyWechatIds()).update();

        List<PromotionFullPiece> fullPieces = promotionFullPieceService.lambdaQuery()
                .ge(PromotionFullPiece::getEndTime, new Date())
                .le(PromotionFullPiece::getStartTime, new Date())
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),PromotionFullPiece::getCompanyWechatId,adminUser.getCompanyWechatIds())
                .list();
        List<String> promotionFullPieceIds = fullPieces.stream().map(PromotionFullPiece::getId).collect(Collectors.toList());
        if(promotionFullPieceIds.size() == 0){
            return ;
        }
        List<PromotionFullPieceGoods> list = promotionFullPieceGoodsService.lambdaQuery()
                .in(PromotionFullPieceGoods::getPromotionFullPieceId,promotionFullPieceIds)
                .list();
        if(list.size() == 0){
            return;
        }
        List<String> goodsIds = list.stream().map(PromotionFullPieceGoods::getGoodsId).collect(Collectors.toList());
        //2.将所有满件活动的商品标识为满件活动的商品
        goodsService.lambdaUpdate().set(Goods::getPromotionFullPiece,true)
                .in(Goods::getGoodsId,goodsIds)
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),Goods::getCompanyWechatId,adminUser.getCompanyWechatIds()).update();
    }


    /**
     * 详情
     * @param id
     * @return
     */
    public PromotionFullPieceVO detail(String id){
        PromotionFullPieceVO vo = new PromotionFullPieceVO();
        //主表
        PromotionFullPiece promotionFullPrice = promotionFullPieceService.getById(id);
        BeanUtils.copyProperties(promotionFullPrice,vo);
        //规则
        List<PromotionFullPieceItem> items = promotionFullPieceItemService.lambdaQuery().eq(PromotionFullPieceItem::getPromotionFullPieceId, id).list();
        vo.setItemList(items);
        //商品
        List<PromotionFullPieceGoods> goodsList = promotionFullPieceGoodsService.lambdaQuery().eq(PromotionFullPieceGoods::getPromotionFullPieceId, id).list();
        List<String> goodsIds = goodsList.stream().map(PromotionFullPieceGoods::getGoodsId).collect(Collectors.toList());
        List<Goods> goods = goodsService.lambdaQuery().in(Goods::getGoodsId, goodsIds).list();
        vo.setGoodsList(goods);
        return vo;
    }


    /**
     * 订单详情
     */
    public IPage<PromotionFullPieceOrderVO> orderDetail(String id, Integer pageNum, Integer pageSize){
        IPage<PromotionFullPieceOrderVO> promotionFullPieceOrderVOIPage = orderMapper.queryPromotionFullPieceOrder(new Page(pageNum, pageSize), id);
        return promotionFullPieceOrderVOIPage;
    }


    /**
     * 根据时间筛选状态
     * @param startTime
     * @param endTime
     * @return
     */
    private String getStatusByTime(Date startTime,Date endTime){
        Date curDate = new Date();
        if(startTime.getTime() > curDate.getTime()){
            return "未开始";
        }else if(endTime.getTime() < curDate.getTime()) {
            return "已过期";
        }else {
            return "进行中";
        }
    }

    /**
     * 查询秒杀商品数量
     */
    public Integer countGoods(List<String> goodsIds){
        Integer count = promotionFullPieceGoodsService.lambdaQuery()
                .in(PromotionFullPieceGoods::getGoodsId, goodsIds)
                .count();
        return count;
    }


}
