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.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.ExcelData;
import com.gree.mall.manager.bean.activity.luckdraw.PromotionLuckDrawBean;
import com.gree.mall.manager.bean.activity.luckdraw.PromotionLuckDrawCodeBean;
import com.gree.mall.manager.bean.activity.luckdraw.PromotionLuckDrawCouponBean;
import com.gree.mall.manager.bean.activity.luckdraw.PromotionLuckDrawList;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.commonmapper.luckdraw.LuckDrawMapper;
import com.gree.mall.manager.enums.CouponTypeEnum;
import com.gree.mall.manager.enums.OrderStatusEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.goods.GoodsLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PromotionLuckDrawLogic {

    @Autowired
    LuckDrawMapper luckDrawMapper;
    @Autowired
    PromotionLuckDrawService promotionLuckDrawService;
    @Autowired
    PromotionLuckDrawCouponService promotionLuckDrawCouponService;
    @Autowired
    PromotionLuckDrawCouponCodeService promotionLuckDrawCouponCodeService;
    @Autowired
    UserCouponService userCouponService;
    @Autowired
    CouponGoodsService couponGoodsService;

    @Autowired
    CommonLogic commonLogic;
    @Autowired
    GoodsLogic goodsLogic;


    /**
     * 列表
     */
    public IPage<PromotionLuckDrawList> list(String name, Boolean status, Integer pageNum, Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage<PromotionLuckDrawList> page = luckDrawMapper.queryList(new Page(pageNum, pageSize), name, status,adminUser.getAdminCompanyIds());
        return page;
    }


    /**
     * 新增活动
     */
    @Transactional
    public void add(PromotionLuckDrawBean promotionLuckDrawBean){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        promotionLuckDrawBean.setCreateTime(new Date());
        promotionLuckDrawBean.setCreateBy(adminUser.getNickName());
        promotionLuckDrawService.save(promotionLuckDrawBean);
        //新增优惠券
        @NotNull List<PromotionLuckDrawCouponBean> promotionLuckDrawCoupons = promotionLuckDrawBean.getPromotionLuckDrawCoupons();
        for(PromotionLuckDrawCouponBean couponBean:promotionLuckDrawCoupons){
            //自定义优惠券id
            String couponId = IdWorker.getIdStr();

            couponBean.setId(couponId);
            if(couponBean.getCouponType().equals(CouponTypeEnum.GOODS.toString()) && CollectionUtils.isEmpty(couponBean.getGoodsIds())){
                throw new RemoteServiceException("商品券请指定商品");
            }
            couponBean.setCreateTime(new Date());
            couponBean.setCreateBy(adminUser.getNickName());
            //新增优惠券
            couponBean.setPromotionLuckDrawId(promotionLuckDrawBean.getId());
            couponBean.insert();

            //发放数量
            Integer totalNum = couponBean.getTotalNum();
            List<PromotionLuckDrawCouponCode> list = promotionLuckDrawCouponCodeService.lambdaQuery()
                    .eq(PromotionLuckDrawCouponCode::getPromotionLuckDrawId, "")
                    .eq(PromotionLuckDrawCouponCode::getPromotionLuckDrawCouponId, "")
                    .last("limit " + totalNum).list();
            if(list.size() != totalNum){
                throw new RemoteServiceException("兑换码不足，请联系相关人员充值");
            }
            list.forEach(v -> v
                    .setPromotionLuckDrawId(promotionLuckDrawBean.getId())
                    .setPromotionLuckDrawCouponId(couponId)
                    .setStartTime(promotionLuckDrawBean.getStartTime())
                    .setEndTime(promotionLuckDrawBean.getEndTime())
                    .setCreateTime(new Date())
                    .setCreateBy(adminUser.getNickName())
            );
            promotionLuckDrawCouponCodeService.updateBatchById(list);

            List<CouponGoods> couponGoodList = new ArrayList<>();
            if(couponBean.getCouponType().equals(CouponTypeEnum.GOODS.toString())) {
                //保存商品券的商品
                List<GoodsSpec> goodsSpecs = goodsLogic.getSpec(couponBean.getGoodsIds());
                for(GoodsSpec goodsSpec : goodsSpecs){
                    CouponGoods couponGoods = new CouponGoods();
                    couponGoods.setGoodsId(goodsSpec.getGoodsId());
                    couponGoods.setCouponId(couponBean.getId());
                    couponGoods.setGoodsSpecId(goodsSpec.getGoodsSpecId());
                    couponGoods.setCreateTime(new Date());
                    couponGoodList.add(couponGoods);
                }
                couponGoodsService.saveBatch(couponGoodList);
            }
        }
    }


    /**
     * 开启/取消活动
     */
    public void updateStatus(String id,Boolean status){
        PromotionLuckDraw promotionLuckDraw = new PromotionLuckDraw();
        promotionLuckDraw.setId(id);
        promotionLuckDraw.setStatus(status);
        promotionLuckDraw.updateById();
    }


    /**
     * 活动详情
     */
    public PromotionLuckDrawBean detail(String id){
        PromotionLuckDrawBean promotionLuckDrawBean = new PromotionLuckDrawBean();
        //1.主
        PromotionLuckDraw promotionLuckDraw = promotionLuckDrawService.getById(id);
        BeanUtils.copyProperties(promotionLuckDraw,promotionLuckDrawBean);
        //2.券
        List<PromotionLuckDrawCoupon> list = promotionLuckDrawCouponService.lambdaQuery().eq(PromotionLuckDrawCoupon::getPromotionLuckDrawId, id).list();
        List<PromotionLuckDrawCouponBean> couponBeans = new ArrayList<>();
        for(PromotionLuckDrawCoupon coupon : list){
            PromotionLuckDrawCouponBean couponBean = new PromotionLuckDrawCouponBean();
            BeanUtils.copyProperties(coupon,couponBean);

            //商品券的处理
            if(couponBean.getCouponType().equals(CouponTypeEnum.GOODS.toString())) {
                List<CouponGoods> couponGoods = couponGoodsService.lambdaQuery().eq(CouponGoods::getCouponId, coupon.getId()).list();
                List<String> goodsIds = couponGoods.stream().map(CouponGoods::getGoodsId).collect(Collectors.toList());
                List<Goods> goodsList = goodsLogic.getById(goodsIds);
                couponBean.setGoodsList(goodsList);
                couponBean.setGoodsIds(goodsIds);
            }

            //兑换情况 todo 兑换数量，剩余兑换数量，使用数量，未使用数量
            Integer dhsl = promotionLuckDrawCouponCodeService.lambdaQuery()
                    .eq(PromotionLuckDrawCouponCode::getStatus, 1)
                    .eq(PromotionLuckDrawCouponCode::getPromotionLuckDrawCouponId, coupon.getId()).count();
            Integer sydhsl = promotionLuckDrawCouponCodeService.lambdaQuery()
                    .eq(PromotionLuckDrawCouponCode::getStatus, 0)
                    .eq(PromotionLuckDrawCouponCode::getPromotionLuckDrawCouponId, coupon.getId()).count();
            //使用数量
            Integer sysl = userCouponService.lambdaQuery().eq(UserCoupon::getStatus, 1).eq(UserCoupon::getCouponId, coupon.getId()).count();
            //未使用数量
            Integer wsysl = userCouponService.lambdaQuery().eq(UserCoupon::getStatus, 0).eq(UserCoupon::getCouponId, coupon.getId()).count();
            couponBean.setDhsl(dhsl);
            couponBean.setSydhsl(sydhsl);
            couponBean.setSysl(sysl);
            couponBean.setWsysl(wsysl);

            couponBeans.add(couponBean);
        }
        promotionLuckDrawBean.setPromotionLuckDrawCoupons(couponBeans);
        return promotionLuckDrawBean;
    }

    /**
     *  兑换记录
     **/
    public IPage<PromotionLuckDrawCodeBean> exchangeList(String promotionLuckDrawId,String promotinLuckDrawCouponId, String code, String name,
                                                         String mobile, String exchangeStartTime, String exchangeEndTime,
                                                         String useStartTime, String useEndTime, String orderId,
                                                         String couponName, Integer status2,Integer pageNum,Integer pageSize){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage<PromotionLuckDrawCodeBean> page = luckDrawMapper.queryLuckDrawCodeList(new Page(pageNum, pageSize), promotionLuckDrawId,promotinLuckDrawCouponId,
                code, name, mobile, exchangeStartTime, exchangeEndTime, useStartTime, useEndTime, orderId, couponName, status2,adminUser.getAdminCompanyIds());
        return page;
    }


    /**
     * 导出兑换码
     */
    public ExcelData exportCode(String promotionLuckDrawId,String promotinLuckDrawCouponId){
        List<PromotionLuckDrawCouponCode> list = promotionLuckDrawCouponCodeService.lambdaQuery()
                .eq(StringUtils.isNotEmpty(promotionLuckDrawId),PromotionLuckDrawCouponCode::getPromotionLuckDrawId,promotionLuckDrawId)
                .eq(StringUtils.isNotEmpty(promotinLuckDrawCouponId),PromotionLuckDrawCouponCode::getPromotionLuckDrawCouponId, promotinLuckDrawCouponId).list();

        List<PromotionLuckDraw> promotionLuckDraws = promotionLuckDrawService.list();
        Map<String, PromotionLuckDraw> promotionLuckDrawMap = promotionLuckDraws.stream().collect(Collectors.toMap(PromotionLuckDraw::getId, v -> v));

        List<PromotionLuckDrawCoupon> promotionLuckDrawCoupons = promotionLuckDrawCouponService.list();
        Map<String, PromotionLuckDrawCoupon> promotionLuckDrawCouponMap = promotionLuckDrawCoupons.stream().collect(Collectors.toMap(PromotionLuckDrawCoupon::getId, v -> v));

        List<List<Object>> rows = new ArrayList<>();
        for(PromotionLuckDrawCouponCode bean : list){
            List<Object> row = new ArrayList<>();
            row.add(bean.getCode());
            row.add(promotionLuckDrawMap.get(bean.getPromotionLuckDrawId()).getName());
            row.add(promotionLuckDrawCouponMap.get(bean.getPromotionLuckDrawCouponId()).getCouponName());
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList("兑换码","优惠券名称","活动名称"));
        return excelData;
    }


    /**
     * 导出兑换记录
     */
    public ExcelData exportData(List<PromotionLuckDrawCodeBean> list){
        String[] titles = new String[]{"活动名称","活动有效期","兑换有效期","使用有效期","优惠券名称","优惠券类型","优惠券面值","兑换码","状态","昵称",
        "电话","兑换时间","使用时间","订单号","订单状态"};
        List<List<Object>> rows = new ArrayList<>();
        for(PromotionLuckDrawCodeBean bean : list){
            List<Object> row = new ArrayList<>();
            row.add(bean.getName());
            row.add(DateUtils.formatDate(bean.getStartTime()));
            row.add(DateUtils.formatDate(bean.getEndTime()));
            row.add(DateUtils.formatDate(bean.getExchangeStartTime()));
            row.add(DateUtils.formatDate(bean.getExchangeEndTime()));
            row.add(bean.getCouponName());
            row.add(CouponTypeEnum.valueOf(bean.getCouponType()).getRemark());
            row.add(bean.getDiscountAmount());
            row.add(bean.getCode());
            //0=未兑换 1=已兑换未使用 2=已使用
            row.add(bean.getStatus2() == 0 ? "未兑换": bean.getStatus2() == 1?"已兑换未使用":"已使用");
            row.add(bean.getUserNickName());
            row.add(bean.getUserMobile());
            row.add(DateUtils.formatDate(bean.getUserExchangeTime()));
            row.add(DateUtils.formatDate(bean.getUserUseTime()));
            row.add(bean.getOrderId());
            if(StringUtils.isNotEmpty(bean.getOrderStatus())) {
                row.add(OrderStatusEnum.valueOf(bean.getOrderStatus()).getName());
            }else{
                row.add("");
            }
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setTitles(Arrays.asList(titles));
        excelData.setRows(rows);
        return excelData;
    }



}
