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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.zhongzheng.common.exception.CustomException;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.modules.course.domain.CourseChapterSection;
import com.zhongzheng.modules.order.bo.*;
import com.zhongzheng.modules.order.domain.OrderBillGoods;
import com.zhongzheng.modules.order.domain.OrderBillSheet;
import com.zhongzheng.modules.order.domain.OrderGoods;
import com.zhongzheng.modules.order.mapper.OrderBillSheetMapper;
import com.zhongzheng.modules.order.service.IOrderBillGoodsService;
import com.zhongzheng.modules.order.service.IOrderBillSheetService;
import com.zhongzheng.modules.order.service.IOrderGoodsService;
import com.zhongzheng.modules.order.vo.OrderBillSheetVo;
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.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单计费单Service业务层处理
 *
 * @author hjl
 * @date 2021-11-09
 */
@Service
public class OrderBillSheetServiceImpl extends ServiceImpl<OrderBillSheetMapper, OrderBillSheet> implements IOrderBillSheetService {

    @Autowired
    private IOrderBillGoodsService iOrderBillGoodsService;

    @Autowired
    private IOrderGoodsService iOrderGoodsService;

    @Override
    public OrderBillSheetVo queryById(Long sheetId){
        OrderBillSheet db = this.baseMapper.selectById(sheetId);
        return BeanUtil.toBean(db, OrderBillSheetVo.class);
    }

    @Override
    public List<OrderBillSheetVo> queryList(OrderBillSheetQueryBo bo) {
        LambdaQueryWrapper<OrderBillSheet> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getPayer()), OrderBillSheet::getPayer, bo.getPayer());
        lqw.eq(StrUtil.isNotBlank(bo.getPayerTel()), OrderBillSheet::getPayerTel, bo.getPayerTel());
        lqw.eq(StrUtil.isNotBlank(bo.getPayType()), OrderBillSheet::getPayType, bo.getPayType());
        lqw.eq(StrUtil.isNotBlank(bo.getPayAccount()), OrderBillSheet::getPayAccount, bo.getPayAccount());
        lqw.eq(StrUtil.isNotBlank(bo.getPayee()), OrderBillSheet::getPayee, bo.getPayee());
        lqw.eq(StrUtil.isNotBlank(bo.getCollectionAccount()), OrderBillSheet::getCollectionAccount, bo.getCollectionAccount());
        lqw.eq(StrUtil.isNotBlank(bo.getPayChannel()), OrderBillSheet::getPayChannel, bo.getPayChannel());
        lqw.eq(StrUtil.isNotBlank(bo.getPosNumber()), OrderBillSheet::getPosNumber, bo.getPosNumber());
        lqw.eq(StrUtil.isNotBlank(bo.getVoucherNo()), OrderBillSheet::getVoucherNo, bo.getVoucherNo());
        lqw.eq(StrUtil.isNotBlank(bo.getRefNo()), OrderBillSheet::getRefNo, bo.getRefNo());
        lqw.eq(StrUtil.isNotBlank(bo.getSheetSn()), OrderBillSheet::getSheetSn, bo.getSheetSn());
        return entity2Vo(this.list(lqw));
    }

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

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

    @Override
    public Boolean updateByEditBo(OrderBillSheetEditBo bo) {
        OrderBillSheet update = BeanUtil.toBean(bo, OrderBillSheet.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        return this.updateById(update);
    }

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

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> placeBillOrder(OrderBillSheetAddBo bo) {
        List<OrderBillGoodsAddBo> goodsList = bo.getGoodsList();
        if(goodsList==null||goodsList.size()<1){
            throw new CustomException("商品列表为空");
        }
        OrderBillSheet add = BeanUtil.toBean(bo, OrderBillSheet.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        //计费订单号
        String sheet_no = DateUtils.getDateOrderSn();
        add.setSheetSn(sheet_no);
        //生成订单
        Collection<OrderBillGoods> coll = new HashSet<>();
        for (OrderBillGoodsAddBo g : goodsList) {
            //计费单商品
            OrderBillGoods orderGoods = BeanUtil.toBean(g, OrderBillGoods.class);
            orderGoods.setOrderSn(g.getOrderSn());
            orderGoods.setSheetSn(sheet_no);
            orderGoods.setCreateTime(DateUtils.getNowTime());
            orderGoods.setUpdateTime(DateUtils.getNowTime());
            coll.add(orderGoods);
            if(orderGoods.getAmount().compareTo(BigDecimal.ZERO)!=1){
                throw new CustomException("已收费用必须大于0");
            }
            //订单商品
            OrderGoods goods = iOrderGoodsService.getOne(new LambdaQueryWrapper<OrderGoods>().eq(OrderGoods::getOrderSn, g.getOrderSn()).eq(OrderGoods::getGoodsId,g.getGoodsId()));
            if(goods==null){
                throw new CustomException("订单商品错误");
            }
            //计费单已收费用累加
            goods.setGoodsReceived(goods.getGoodsReceived().add(orderGoods.getAmount()));
            if(goods.getGoodsRealPrice().compareTo(goods.getGoodsReceived()) == -1){
                throw new CustomException("已收费用超出成交价");
            }
            else if(goods.getGoodsRealPrice().compareTo(goods.getGoodsReceived()) == 0){
                //完全收费
                goods.setPayStatus(OrderGoods.PAY_FULL);
            }
            else{
                //部分收费
                goods.setPayStatus(OrderGoods.PAY_PART);
            }
            goods.setUpdateTime(DateUtils.getNowTime());
            iOrderGoodsService.updateById(goods);
        }
        iOrderBillGoodsService.saveBatch(coll);
        this.save(add);
        Map<String, Object> result = new HashMap<>();
        result.put("sheetId",add.getSheetId());
        result.put("sheetSn",sheet_no);
        return result;
    }
}
