package com.fuint.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuint.common.dto.AccountInfo;
import com.fuint.common.dto.MtPurchaseOrderDto;
import com.fuint.common.dto.MtPurchaseOrderItemDto;
import com.fuint.common.service.PurchaseOrderItemService;
import com.fuint.common.util.AuthUserUtil;
import com.fuint.common.vo.MtPurchaseOrderItemVo;
import com.fuint.common.vo.MtPurchaseOrderVo;
import com.fuint.framework.web.PageResult;
import com.fuint.repository.mapper.MtPurchaseOrderItemMapper;
import com.fuint.repository.mapper.MtStoreMapper;
import com.fuint.repository.model.MtPurchaseOrder;
import com.fuint.common.service.PurchaseOrderService;
import com.fuint.common.enums.StatusEnum;
import com.fuint.repository.mapper.MtPurchaseOrderMapper;
import com.fuint.repository.model.MtPurchaseOrderItem;
import com.fuint.repository.model.MtStore;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 采购订单表服务接口
 *
 * Created by huangwen
 * CopyRight https://www.fuint.cn
 */
@Service
@AllArgsConstructor
public class PurchaseOrderServiceImpl extends ServiceImpl<MtPurchaseOrderMapper, MtPurchaseOrder> implements PurchaseOrderService {

    private static final Logger logger = LoggerFactory.getLogger(PurchaseOrderServiceImpl.class);

    private MtPurchaseOrderMapper mtPurchaseOrderMapper;

    private MtPurchaseOrderItemMapper mtPurchaseOrderItemMapper;

    private MtStoreMapper mtStoreMapper;

    private PurchaseOrderItemService purchaseOrderItemService;

    @Override
    public MtPurchaseOrderVo queryPurchaseOrderById(Long id) {

        Assert.isTrue(ObjectUtils.isNotEmpty(AuthUserUtil.get()), "请先登录");
        Assert.isTrue(ObjectUtils.isNotEmpty(id), "请选择查询的订单");

        MtPurchaseOrder mtPurchaseOrder = mtPurchaseOrderMapper.selectOne(new LambdaQueryWrapper<MtPurchaseOrder>().eq(MtPurchaseOrder::getId, id));
        List<MtPurchaseOrderItem> itemList = mtPurchaseOrderItemMapper.selectList(new LambdaQueryWrapper<MtPurchaseOrderItem>().eq(MtPurchaseOrderItem::getPurchaseNo, id));

        MtPurchaseOrderVo mtPurchaseOrderVo = BeanUtil.copyProperties(mtPurchaseOrder, MtPurchaseOrderVo.class);
        if (ObjectUtils.isNotEmpty(itemList)) {
            List<MtPurchaseOrderItemVo> mtPurchaseOrderItemVos = BeanUtil.copyToList(itemList, MtPurchaseOrderItemVo.class);
            mtPurchaseOrderVo.setOrderItemList(mtPurchaseOrderItemVos);
        }

        return mtPurchaseOrderVo ;
    }



    @Override
    public PageResult<MtPurchaseOrderVo> queryOrderPageList(MtPurchaseOrderDto mtPurchaseOrderDto)  {

        AccountInfo accountInfo = AuthUserUtil.get();
        Assert.isTrue(ObjectUtils.isNotEmpty(accountInfo), "请先登录");
        Assert.isTrue(ObjectUtils.isNotEmpty(mtPurchaseOrderDto.getStoreId()), "请选择餐厅");
        Assert.isFalse(accountInfo.getStoreId()!=0 && !accountInfo.getStoreId().equals(mtPurchaseOrderDto.getStoreId()), "暂无该餐厅权限");

        //分页
        IPage<MtPurchaseOrder> page = new Page<>(mtPurchaseOrderDto.getPageNo()==null?1:mtPurchaseOrderDto.getPageNo(), mtPurchaseOrderDto.getPageSize()==null?10:mtPurchaseOrderDto.getPageSize());
        IPage<MtPurchaseOrder> orderIPage = mtPurchaseOrderMapper.selectPage(page, new LambdaQueryWrapper<MtPurchaseOrder>().eq(MtPurchaseOrder::getStoreId, mtPurchaseOrderDto.getStoreId()));
        if (ObjectUtils.isEmpty(orderIPage.getRecords())){
            return PageResult.<MtPurchaseOrderVo>builder().data(new ArrayList<>()).currentPage((int)orderIPage.getCurrent()).total((int)orderIPage.getTotal()).build();
        }
        List<MtPurchaseOrderVo> mtPurchaseOrderVos = BeanUtil.copyToList(orderIPage.getRecords(), MtPurchaseOrderVo.class);

        //订单项列表
        List<MtPurchaseOrderItem> itemList = mtPurchaseOrderItemMapper.selectList(new LambdaQueryWrapper<MtPurchaseOrderItem>()
                .in(MtPurchaseOrderItem::getPurchaseNo));
        Map<String, List<MtPurchaseOrderItem>> orderNoItemMap = itemList.stream().collect(Collectors.groupingBy(MtPurchaseOrderItem::getPurchaseNo));

        mtPurchaseOrderVos.forEach(vo -> {
            List<MtPurchaseOrderItem> orderItemList = orderNoItemMap.get(vo.getOrderNo());
            if (ObjectUtils.isNotEmpty(orderItemList)) {
                List<MtPurchaseOrderItemVo> orderItemVos = BeanUtil.copyToList(orderItemList, MtPurchaseOrderItemVo.class);
                vo.setOrderItemList(orderItemVos);
            }
        });
        return PageResult.<MtPurchaseOrderVo>builder().data(mtPurchaseOrderVos).total((int)orderIPage.getTotal()).currentPage(mtPurchaseOrderDto.getPageNo()).build();
    }

    @Override
    @Transactional
    public void savePurcahseOrder(MtPurchaseOrderDto mtPurchaseOrderDto) {
        //参数验证
        AccountInfo accountInfo = AuthUserUtil.get();
        Assert.isTrue(ObjectUtils.isNotEmpty(accountInfo), "请先登录");
        Assert.isTrue(ObjectUtils.isNotEmpty(mtPurchaseOrderDto.getStoreId()), "请选择餐厅");
        List<MtPurchaseOrderItemDto> orderItemList = mtPurchaseOrderDto.getOrderItemList();
        Assert.isFalse(orderItemList.isEmpty(), "请添加采购项");
        Assert.isFalse(accountInfo.getStoreId()!=0 && !accountInfo.getStoreId().equals(mtPurchaseOrderDto.getStoreId()), "暂无该餐厅权限");
        MtStore mtStore = mtStoreMapper.selectOne(new LambdaQueryWrapper<MtStore>().eq(MtStore::getId, mtPurchaseOrderDto.getStoreId()).eq(MtStore::getStatus, StatusEnum.ENABLED.getKey()));
        Assert.isTrue(ObjectUtils.isNotEmpty(mtStore), "该餐厅不存在");
        //参数准备
        MtPurchaseOrder purchaseOrder = BeanUtil.copyProperties(mtPurchaseOrderDto, MtPurchaseOrder.class);
        purchaseOrder.setCreateTime(new Date());
        purchaseOrder.setCreateUserId(String.valueOf(accountInfo.getId()));
        purchaseOrder.setOrderNo(new Snowflake(1,1).nextIdStr());

        ArrayList<MtPurchaseOrderItem> orderItems = new ArrayList<>();
        for (MtPurchaseOrderItemDto itemDto : orderItemList) {
            MtPurchaseOrderItem purchaseOrderItem = BeanUtil.copyProperties(itemDto, MtPurchaseOrderItem.class);
            purchaseOrderItem.setPurchaseNo(String.valueOf(purchaseOrder.getOrderNo()));
            purchaseOrderItem.setCreateTime(new Date());
            purchaseOrderItem.setCreateUserId(String.valueOf(accountInfo.getId()));
            purchaseOrderItem.setTotalPrice(purchaseOrderItem.getUnitPrice()*purchaseOrderItem.getTotalQuantity());
            orderItems.add(purchaseOrderItem);
        }
        purchaseOrder.setTotalPrice(orderItems.stream().mapToDouble(MtPurchaseOrderItem::getTotalPrice).sum());
        //保存订单
        int insert = mtPurchaseOrderMapper.insert(purchaseOrder);
        Assert.isFalse(insert!=1, "保存失败");
        //保存订单项
        boolean b = purchaseOrderItemService.saveBatch(orderItems);
        Assert.isFalse(b, "保存失败");
    }

    @Override
    @Transactional
    public void updatePurchaseOrderByOrderNo(MtPurchaseOrderDto mtPurchaseOrderDto) {
        //参数验证
        AccountInfo accountInfo = AuthUserUtil.get();
        Assert.isTrue(ObjectUtils.isNotEmpty(accountInfo), "请先登录");
        Assert.isTrue(ObjectUtils.isNotEmpty(mtPurchaseOrderDto.getStoreId()), "请选择餐厅");
        Assert.isTrue(ObjectUtils.isNotEmpty(mtPurchaseOrderDto.getOrderNo()), "请选择采购单");
        Assert.isFalse(mtPurchaseOrderDto.getOrderItemList().isEmpty(), "请添加采购项");
        Assert.isFalse(accountInfo.getStoreId()!=0 && !accountInfo.getStoreId().equals(mtPurchaseOrderDto.getStoreId()), "暂无该餐厅权限");

        MtStore mtStore = mtStoreMapper.selectOne(new LambdaQueryWrapper<MtStore>().eq(MtStore::getId, mtPurchaseOrderDto.getStoreId()).eq(MtStore::getStatus, StatusEnum.ENABLED.getKey()));
        Assert.isTrue(ObjectUtils.isNotEmpty(mtStore), "该餐厅不存在");

        MtPurchaseOrder mtPurchaseOrder = mtPurchaseOrderMapper.selectOne(new LambdaQueryWrapper<MtPurchaseOrder>().eq(MtPurchaseOrder::getOrderNo, mtPurchaseOrderDto.getOrderNo()));
        Assert.isTrue(ObjectUtils.isNotEmpty(mtPurchaseOrder), "该采购单不存在");

        //修改订单
        MtPurchaseOrder purchaseOrder = BeanUtil.copyProperties(mtPurchaseOrderDto, MtPurchaseOrder.class);
        purchaseOrder.setUpdateTime(new Date());
        purchaseOrder.setUpdateUserId(String.valueOf(accountInfo.getId()));
        purchaseOrder.setTotalPrice(mtPurchaseOrder.getTotalPrice() );
        purchaseOrder.setTotalQuantity(mtPurchaseOrder.getTotalQuantity());
        purchaseOrder.setTotalWeight(mtPurchaseOrder.getTotalWeight());
        purchaseOrder.setCreateUserId(mtPurchaseOrder.getCreateUserId());
        purchaseOrder.setCreateTime(mtPurchaseOrder.getCreateTime());
        purchaseOrder.setDeleteFlag(mtPurchaseOrderDto.getDeleteFlag());
        purchaseOrder.setOrderNo(mtPurchaseOrder.getOrderNo());
        purchaseOrder.setId(mtPurchaseOrder.getId());
        purchaseOrder.setProject(mtPurchaseOrder.getProject());
        int update = mtPurchaseOrderMapper.updateById(purchaseOrder);
        Assert.isFalse(update!=1, "修改失败");

    }

    @Override
    @Transactional
    public void deletePurchaseOrderByOrderNo(Long orderNo) {
        //参数验证
        AccountInfo accountInfo = AuthUserUtil.get();
        Assert.isTrue(ObjectUtils.isNotEmpty(accountInfo), "请先登录");
        Assert.isTrue(ObjectUtils.isNotEmpty(orderNo), "请选择采购单");

        MtPurchaseOrder mtPurchaseOrder = mtPurchaseOrderMapper.selectOne(new LambdaQueryWrapper<MtPurchaseOrder>().eq(MtPurchaseOrder::getOrderNo, orderNo));
        Assert.isTrue(ObjectUtils.isNotEmpty(mtPurchaseOrder), "该采购单不存在");
        Assert.isFalse(accountInfo.getStoreId()!=0 && mtPurchaseOrder.getStoreId() != accountInfo.getStoreId(), "暂无该餐厅权限");

        int delete = mtPurchaseOrderMapper.deleteById(orderNo);
        Assert.isFalse(delete!=1, "删除失败");
        int delete1 = mtPurchaseOrderItemMapper.delete(new LambdaQueryWrapper<MtPurchaseOrderItem>().eq(MtPurchaseOrderItem::getPurchaseNo, orderNo));
        Assert.isFalse(delete1!=1, "删除失败");
    }
}
