package com.zhongzheng.modules.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.zhongzheng.common.exception.CustomException;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.common.utils.SecurityUtils;
import com.zhongzheng.modules.bank.mapper.QuestionMapper;
import com.zhongzheng.modules.goods.domain.Goods;
import com.zhongzheng.modules.goods.service.IGoodsService;
import com.zhongzheng.modules.grade.domain.ClassGradeGoods;
import com.zhongzheng.modules.grade.domain.ClassGradeUser;
import com.zhongzheng.modules.grade.service.IClassGradeGoodsService;
import com.zhongzheng.modules.grade.service.IClassGradeService;
import com.zhongzheng.modules.grade.service.IClassGradeUserService;
import com.zhongzheng.modules.grade.vo.ClassGradeVo;
import com.zhongzheng.modules.order.bo.OrderAddBo;
import com.zhongzheng.modules.order.bo.OrderGoodsAddBo;
import com.zhongzheng.modules.order.bo.OrderGoodsEditBo;
import com.zhongzheng.modules.order.bo.OrderGoodsQueryBo;
import com.zhongzheng.modules.order.domain.Order;
import com.zhongzheng.modules.order.domain.OrderGoods;
import com.zhongzheng.modules.order.mapper.OrderGoodsMapper;
import com.zhongzheng.modules.order.service.IOrderGoodsService;
import com.zhongzheng.modules.order.service.IOrderService;
import com.zhongzheng.modules.order.vo.OrderGoodsVo;
import com.zhongzheng.modules.order.vo.OrderVo;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单商品Service业务层处理
 *
 * @author hjl
 * @date 2021-11-08
 */
@Service
public class OrderGoodsServiceImpl extends ServiceImpl<OrderGoodsMapper, OrderGoods> implements IOrderGoodsService {

    @Autowired
    private OrderGoodsMapper orderGoodsMapper;

    @Autowired
    private IGoodsService iGoodsService;

    @Autowired
    private IClassGradeUserService iClassGradeUserService;

    @Autowired
    private IClassGradeService iClassGradeService;

    @Autowired
    private IOrderService iOrderService;

    @Autowired
    private IClassGradeGoodsService iClassGradeGoodsService;

    @Override
    public OrderGoodsVo queryById(String orderSn){
        OrderGoods db = this.baseMapper.selectById(orderSn);
        return BeanUtil.toBean(db, OrderGoodsVo.class);
    }

    @Override
    public OrderGoodsVo selectDetail(OrderGoodsQueryBo bo) {
        return orderGoodsMapper.selectDetail(bo);
    }

    @Override
    public List<OrderGoodsVo> selectList(OrderGoodsQueryBo bo) {
        return orderGoodsMapper.selectList(bo);
    }


    @Override
    public List<OrderGoodsVo> queryList(OrderGoodsQueryBo bo) {
        LambdaQueryWrapper<OrderGoods> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getGoodsId() != null, OrderGoods::getGoodsId, bo.getGoodsId());
        lqw.eq(StrUtil.isNotBlank(bo.getGoodsInputData()), OrderGoods::getGoodsInputData, bo.getGoodsInputData());
        lqw.eq(bo.getGoodsPrice() != null, OrderGoods::getGoodsPrice, bo.getGoodsPrice());
        lqw.eq(bo.getGoodsRealPrice() != null, OrderGoods::getGoodsRealPrice, bo.getGoodsRealPrice());
        lqw.eq(bo.getOrderSn() != null, OrderGoods::getOrderSn, bo.getOrderSn());
        return entity2Vo(this.list(lqw));
    }

    /**
    * 实体类转化成视图对象
    *
    * @param collection 实体类集合
    * @return
    */
    private List<OrderGoodsVo> entity2Vo(Collection<OrderGoods> collection) {
        List<OrderGoodsVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, OrderGoodsVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<OrderGoods> page = (Page<OrderGoods>)collection;
            Page<OrderGoodsVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page,pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Boolean insertByAddBo(OrderGoodsAddBo bo) {
        OrderGoods add = BeanUtil.toBean(bo, OrderGoods.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        return this.save(add);
    }

    @Override
    public Long getBuyGoodsHistory(OrderGoodsQueryBo bo) {
        return this.baseMapper.getBuyGoodsHistory(bo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(OrderGoodsEditBo bo) {
        OrderGoods update = BeanUtil.toBean(bo, OrderGoods.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        update.setGoodsInputData(JSON.toJSONString(bo.getGoodsInputData()));
        OrderGoods db = this.baseMapper.selectById(bo.getOrderGoodsId());
        //新的班级ID变化
        if(bo.getGradeId()!=null&&db.getGradeId()!=bo.getGradeId()){
            //修改班级
            Goods goods = iGoodsService.getOne(new LambdaQueryWrapper<Goods>().eq(Goods::getGoodsId,bo.getGoodsId()));
            //视频商品安排班级
            if(goods.getGoodsType()==1){
                Order order = iOrderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderSn,bo.getOrderSn()));
                //加入新班级
                joinGrade(bo.getOrderGoodsId(),bo.getGradeId(),order.getUserId(),bo.getGoodsId());
                //移除旧班级
                ClassGradeUser classGradeUser =iClassGradeUserService.getOne(new LambdaQueryWrapper<ClassGradeUser>()
                        .eq(ClassGradeUser::getUserId,order.getUserId()).eq(ClassGradeUser::getGradeId,db.getGradeId()
                        ).eq(ClassGradeUser::getStatus,1).last("limit 1"));
                if(classGradeUser==null){
                    throw new CustomException("原班级查无你的信息");
                }
                classGradeUser.setStatus(0);
                classGradeUser.setUpdateTime(DateUtils.getNowTime());
                iClassGradeUserService.updateById(classGradeUser);
            }else{
                throw new CustomException("非视频课程无法修改班级");
            }
        }
        return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(OrderGoods entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

    @Override
    public List<OrderGoodsVo> selectOrderGoods() {
        OrderGoodsQueryBo orderGoodsQueryBo = new OrderGoodsQueryBo();
        orderGoodsQueryBo.setGoodsId(1L);
        List<OrderGoodsVo> orderGoodsVos = baseMapper.selectOrderGoods(orderGoodsQueryBo);
        return orderGoodsVos;
    }

    @Override
    public List<OrderGoodsVo> selectOrderTwoGoods() {
        OrderGoodsQueryBo orderGoodsQueryBo = new OrderGoodsQueryBo();
        return baseMapper.selectOrderTwoGoods(orderGoodsQueryBo);
    }

    @Override
    public List<OrderGoodsVo> sendGoods() {
        return baseMapper.sendGoods();
    }

    public boolean joinGrade(Long orderGoodsId,Long gradeId,Long userId,Long goodsId){
        ClassGradeVo classGradeVo = iClassGradeService.queryById(gradeId);
        if(classGradeVo==null){
            throw new CustomException("班级不存在");
        }
        ClassGradeGoods gradeGoods = iClassGradeGoodsService.getOne(new LambdaQueryWrapper<ClassGradeGoods>().eq(ClassGradeGoods::getGradeId,gradeId)
                .eq(ClassGradeGoods::getGoodsId,goodsId));
        if(gradeGoods==null){
            throw new CustomException("该班级不支持该商品使用");
        }
        LambdaQueryWrapper<ClassGradeUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ClassGradeUser::getGradeId,gradeId);
        lqw.eq(ClassGradeUser::getStatus,1);
        int studentNum = iClassGradeUserService.count(lqw);
        //预留0空位避免超人数
        if(classGradeVo.getStudentUpper()-studentNum<1){
            //班级还有剩位,直接加入班级
            throw new CustomException("班级人数已满");
        }
        //进入班级
        ClassGradeUser classGradeUser = new ClassGradeUser();
        classGradeUser.setUserId(userId);
        classGradeUser.setGradeId(gradeId);
        classGradeUser.setStatus(1);
        classGradeUser.setCreateBy(SecurityUtils.getUsername());
        classGradeUser.setFromType(2);
        classGradeUser.setOrderGoodsId(orderGoodsId);
        classGradeUser.setCreateTime(DateUtils.getNowTime());
        classGradeUser.setUpdateTime(DateUtils.getNowTime());
        iClassGradeUserService.save(classGradeUser);

        return true;
    }
}
