package com.cf.imes.module.manage.service.pack;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.cf.imes.framework.common.enums.OrderPackageStatusEnum;
import com.cf.imes.framework.common.enums.OrderPackageTypeEnum;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.manage.controller.admin.pack.vo.*;
import com.cf.imes.module.manage.controller.admin.process.vo.ProcessRespVO;
import com.cf.imes.module.manage.controller.admin.query.vo.productionStatus.OrderModuleReqVO;
import com.cf.imes.module.manage.dal.dataobject.pack.OrderBodyDO;
import com.cf.imes.module.manage.dal.dataobject.process.OrderDO;
import com.cf.imes.module.manage.dal.dataobject.query.OrderItemDO;
import com.cf.imes.module.manage.dal.dataobject.query.OrderPackageDO;
import com.cf.imes.module.manage.dal.dataobject.query.OrderPartsNDO;
import com.cf.imes.module.manage.dal.mysql.pack.OrderBodyMapper;
import com.cf.imes.module.manage.dal.mysql.pack.OrderPackageMapper;
import com.cf.imes.module.manage.dal.mysql.query.OrderItemMapper;
import com.cf.imes.module.manage.dal.mysql.query.OrderPartsMapper;
import com.cf.imes.module.manage.dal.mysql.query.ProductionStatusMapper;
import com.cf.imes.module.manage.util.packageNo.PackageNoUtil;
import com.cf.imes.module.manage.util.page.PageHelperUtil;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
import static com.cf.imes.module.manage.util.search.SearchUtil.insertSeparator;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;

@Service
@Validated
@Transactional
public class PackServiceImpl implements PackService {

    @Resource
    private OrderPackageMapper orderPackageMapper;

    @Resource
    private ProductionStatusMapper productionStatusMapper;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private OrderPartsMapper orderPartsMapper;

    @Resource
    private OrderBodyMapper orderBodyMapper;


    // 打包分页查询
    @Override
    public PageResult<PackRespVO> getPackPage(PackPageReqVO pageReqVO) {

        pageReqVO.setCustomer(insertSeparator(pageReqVO.getCustomer()));
        pageReqVO.setCustomOrderNo(insertSeparator(pageReqVO.getCustomOrderNo()));
        pageReqVO.setAddress(insertSeparator(pageReqVO.getAddress()));

        PageDTO<PackRespVO> page = new PageDTO<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());

        // 根据生产状态查询生产单号
        List<Long> collect = productionStatusMapper.selectPackPage(pageReqVO,getUserOrganId()).stream().map(OrderDO::getId).collect(Collectors.toList());

        if(collect.isEmpty()){
            return null;
        }

        // 查询打包首页分页数据信息，包裹数，板件数量信息
        IPage<PackRespVO> packRespVOS = productionStatusMapper.selectOrderPlate(page,collect,getUserOrganId());

        for (PackRespVO record : packRespVOS.getRecords()) {

            // 待处理量
            record.setPendingNum(record.getTotalPieceCount() - record.getPackPieceCount());
        }

        if (CollectionUtil.isEmpty(packRespVOS.getRecords())) {
            return new PageResult<>();
        }


        return new PageResult<>(packRespVOS.getRecords(), packRespVOS.getTotal());

    }



    // 查看生产订单对应的板材信息
    @Override
    public List<PlateDetailsRespVO> getOrderPlateList(Long orderId) {

        // 查询需要返回的其他信息
//        OrderPlateDetailsRespVO orderPlateDetailsRespVO = orderItemMapper.selectOrderPlateDetails(orderId);
//        orderPlateDetailsRespVO.setPendingNum(orderPlateDetailsRespVO.getPlateNum() - orderPlateDetailsRespVO.getPlateProcessedNum());

        // 查询订单对应的板件信息
        List<PlateDetailsRespVO> plateDetailsRespVOS = orderItemMapper.selectOrderPlateList(orderId,getUserOrganId());

        return plateDetailsRespVOS;


    }


    // 查询多个生产单对应的板材信息
    @Override
    public List<PlateDetailsRespVO> getOrdersPlateList(List<Long> orderIds) {

        return orderItemMapper.selectOrdersPlateList(orderIds,getUserOrganId());

    }


    // 查看生产订单对应的包裹信息
    @Override
    public PageResult<OrderPackageDO> getOrderPack(PackageDetailsReqVO reqVO) {

        PageDTO<OrderPackageDO> page = new PageDTO<>(reqVO.getPageNo(), reqVO.getPageSize());

        IPage<OrderPackageDO> orderPackageDOIPage = orderPackageMapper.selectByOrderNo(page,reqVO, getUserOrganId());


        if (CollectionUtil.isEmpty(orderPackageDOIPage.getRecords())) {
            return new PageResult<>();
        }


        return new PageResult<>(orderPackageDOIPage.getRecords(), orderPackageDOIPage.getTotal());

    }





    // 查看板材列表分页
    @Override
    public PageResult<PlateDetailsRespVO> queryPlateDetails(OrderModuleReqVO pageReqVO) {


        PageHelper.startPage(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        List<PlateDetailsRespVO> plateDetailsRespVOS = orderItemMapper.selectOrderPlateList(pageReqVO.getOrderNo(),getUserOrganId());
        PageInfo<PlateDetailsRespVO> pageInfo = new PageInfo<>(plateDetailsRespVOS);
        PageResult<PlateDetailsRespVO> priceRateReqVOPageResult = PageHelperUtil.convertToPageResult(pageInfo);

        return priceRateReqVOPageResult;
    }



    // 查看配件列表分页
    @Override
    public PageResult<OrderPartsRespVO> getPartsList(OrderPartsReqVO reqVO) {

        PageDTO<OrderPartsRespVO> page = new PageDTO<>(reqVO.getPageNo(), reqVO.getPageSize());

        IPage<OrderPartsRespVO> orderPartsRespVOS = orderPartsMapper.selectPartsList(page,reqVO.getOrderNo(),getUserOrganId());

        if (CollectionUtil.isEmpty(orderPartsRespVOS.getRecords())) {
            return new PageResult<>();
        }


        return new PageResult<>(orderPartsRespVOS.getRecords(), orderPartsRespVOS.getTotal());


    }



    // 更新配件
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateParts(OrderPartsReqVO reqVO) {

        // 生产明细表新增的配件ID
        orderItemMapper.insertParts(reqVO.getAddPartsList(),reqVO.getPackId(),reqVO.getOrderNo());

        // 生产明细表删除的配件ID
        orderItemMapper.deletePartsList(reqVO.getDeletePartsList(),reqVO.getPackId(),reqVO.getOrderNo());
    }



    // 拆包
    @Override
    public void unpacking(Long packageID) {

        OrderPackageDO packageDO = orderPackageMapper.selectById(packageID);
        packageDO.setStatus((OrderPackageStatusEnum.UNPACKED.getStatus()));
        orderPackageMapper.updateById(packageDO);


    }


    // 显示分组房间名称
    @Override
    public List<OrderPlateGroupRespVO> GetOrderPlateGroup(Long orderId) {

        /*List<String> collect = orderBodyMapper.selectGroup(orderId).stream().map(OrderBodyDO::getRoomName).collect(Collectors.toList());*/

        List<OrderBodyDO> orderBodyDOS = orderBodyMapper.selectGroup(orderId);


        return BeanUtils.toBean(orderBodyDOS, OrderPlateGroupRespVO.class);


    }


    // 查看配件包裹详情
    @Override
    public List<OrderPartsRespVO> queryPackageDetails(PrintOrderPackReqVO reqVO) {

        return orderPartsMapper.selectOrderParts(reqVO.getOrderNo(), reqVO.getPackageNo());

    }


    // 新增包裹
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPackageDO insertPack(OrderPackReqVO packageVO) {

        List<OrderPackageDO> orderPackageDOS = orderPackageMapper.selectPackStatus(packageVO.getOrderId(),getUserOrganId());
        for (OrderPackageDO orderPackageDO : orderPackageDOS) {
            Integer status = orderPackageDO.getStatus();
            if (status.equals(OrderPackageStatusEnum.UNPACKED.getStatus())){
                throw ServiceExceptionUtil.exception(ErrorCodeConstants.THE_CURRENT_PACKAGE_HAS_AN_UNSEALED_PACKAGE);
            }
        }



        OrderPackageDO orderPackageDO = new OrderPackageDO();
        orderPackageDO.setOrderId(packageVO.getOrderId());
        orderPackageDO.setType(packageVO.getPackageType());
//        orderPackageDO.setPackageNo(PackageNoUtil.randomPageNo());
        orderPackageDO.setPackageNo(packageVO.getPackNo());
        orderPackageDO.setStatus((OrderPackageStatusEnum.PACKAGED.getStatus()));
        orderPackageDO.setRemark(packageVO.getRemark());
        orderPackageMapper.insert(orderPackageDO);
        // 生产单明细表新增包裹 ID
        orderItemMapper.insertPackId(packageVO.getAddPlateIdList(), orderPackageDO.getId());

        return orderPackageDO;


//        // 不为 -1 ，有包裹存在，走更新逻辑
//
//        // 生产明细表新增包裹ID
//        orderItemMapper.insertPackId(packageVO.getAddPlateIdList(), packageVO.getPackId());
//        // 移除包裹ID
//        orderItemMapper.deletePackId(packageVO.getDeletePlateIdList(), packageVO.getPackId());
//
//        return orderPackageMapper.selectByPackId(packageVO.getPackId()).setStatus(OrderPackageStatusEnum.PACKAGED.getStatus());


    }


    // 更新包裹
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPackageDO updatePack(OrderPackReqVO packageVO) {


        // 生产明细表新增包裹ID
        orderItemMapper.insertPackId(packageVO.getAddPlateIdList(), packageVO.getPackId());

        // 移除生产明细表中板件对应的包裹ID
        orderItemMapper.deletePackId(packageVO.getDeletePlateIdList(), packageVO.getPackId());

        return orderPackageMapper.selectByPackId(packageVO.getPackId(),getUserOrganId()).setStatus(OrderPackageStatusEnum.PACKAGED.getStatus());

    }




    // 查询包裹
    @Override
    public List<OrderPackRespVO> selectPack(Long orderId) {

        List<OrderPackageDO> orderPackageDOS = orderPackageMapper.selectPackStatus(orderId,getUserOrganId());
//        List<OrderPackageDO> collect = orderPackageDOS.stream().map(o -> o.setRemark(JsonUtils.unzipString(o.getRemark()))).collect(Collectors.toList());
        return BeanUtils.toBean(orderPackageDOS, OrderPackRespVO.class);

    }





    // 包裹订单打印
    @Override
    public PrintOrderPackRespVO printOrderPack(PrintOrderPackReqVO reqVO) {

        PrintOrderPackRespVO printOrderPackRespVO = productionStatusMapper.selectOrderPack(reqVO.getOrderNo(), reqVO.getPackageNo(),getUserOrganId());
        printOrderPackRespVO.setPlateList(orderItemMapper.selectPrintPlateList(reqVO.getOrderNo(), reqVO.getPackageNo(),getUserOrganId()));
        return printOrderPackRespVO;


    }



    // 删除包裹及其关联的包裹信息(删除全部)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrderPack(PackReqVO reqVO) {

        // 判断包裹的类型是否为其他类型，如果是，则删除其包裹信息
        if (reqVO.getIsOther() == true) {

            orderPartsMapper.deleteOrderParts(reqVO.getPackageId());
            orderPackageMapper.updateParts(reqVO.getPackageId(), reqVO.getPackageNo());
            orderItemMapper.deleteParts(reqVO);
            return;
        }

        orderItemMapper.deleteOrderPack(reqVO);

    }


    // 新增外部配件包裹表
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPackageDO addNewOtherPack(OtherPackReqVO reqVO) {

        // 判断配件名称是否重复
        OrderPartsNDO orderPartsNDO = orderPartsMapper.selectOneParts(reqVO.getName(),getUserOrganId());
        if (orderPartsNDO != null) {
            throw exception(THE_ACCESSORY_NAME_CANNOT_BE_DUPLICATED);
        }

        // 配件表新增数据
        OrderPartsNDO orderParts = BeanUtils.toBean(reqVO, OrderPartsNDO.class);
        orderPartsMapper.insert(orderParts);


        // 在包裹表中添加包裹编号和生产单号，修改包裹类型未其他配件类型
        OrderPackageDO orderPackageDO = new OrderPackageDO();
//        orderPackageDO.setPackageNo(PackageNoUtil.randomPageNo());
        orderPackageDO.setPackageNo(reqVO.getPackNo());
        orderPackageDO.setOrderId(reqVO.getOrderId());
        orderPackageDO.setType(OrderPackageTypeEnum.OTHER_ACCESSORIES.getType().longValue());

        // 新增包裹
        orderPackageMapper.insert(orderPackageDO);


        // 在生产单明细表中添加数据（生产单号，配件ID，包裹ID，部件数量（目前一直为1））
        OrderItemDO orderItemDO = new OrderItemDO();
        orderItemDO.setOrderId(reqVO.getOrderId());
        orderItemDO.setPartsId(orderParts.getId());
        orderItemDO.setPackageId(orderPackageDO.getId());
        orderItemDO.setNum(Float.valueOf(1));


        // 在生产单明细表中新增数据
        orderItemMapper.insert(orderItemDO);

        // 查看新增的包裹信息
        /*        return orderPackageMapper.selectByPackId(orderPackageDO.getId());*/
        return orderPackageDO;


    }




    // 新增外部配件
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPartsRespVO addNewOtherParts(OtherPackReqVO reqVO) {

        OrderPackageDO orderPackageDO = orderPackageMapper.selectByPackNo(reqVO.getPackNo(),getUserOrganId());
        if(orderPackageDO.getType()!= OrderPackageTypeEnum.OTHER_ACCESSORIES.getType().longValue()){
            throw exception(THE_CURRENT_PACKAGE_TYPE_IS_INCORRECT);
        }

        // 配件表新增数据
        OrderPartsNDO orderParts = BeanUtils.toBean(reqVO, OrderPartsNDO.class);
        orderPartsMapper.insert(orderParts);

        // 在生产单明细表中添加数据（生产单号，配件ID，包裹ID，部件数量（目前一直为1））
        OrderItemDO orderItemDO = new OrderItemDO();
        orderItemDO.setOrderId(reqVO.getOrderId());
        orderItemDO.setPartsId(orderParts.getId());
        orderItemDO.setPackageId(orderPackageDO.getId());
        orderItemDO.setNum(Float.valueOf(1));

        // 在生产单明细表中新增数据
        orderItemMapper.insert(orderItemDO);

        return BeanUtils.toBean(orderParts,OrderPartsRespVO.class);

    }







    // 删除配件包裹中的配件(删除某一个)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOtherParts(DeleteOtherPartsReqVO reqVO) {

        // 更新配件表中配件为逻辑删除
        orderPartsMapper.updateParts(reqVO.getPartsId());

        orderItemMapper.deleteOtherParts(reqVO.getPartsId());

    }



    // 新增配件-即新增一个包裹
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPackageDO addNewPartsPack(OrderPackReqVO reqVO) {

        OrderPackageDO orderPackageDO = new OrderPackageDO();
        orderPackageDO.setOrderId(reqVO.getOrderId());
        orderPackageDO.setType(reqVO.getPackageType());
        orderPackageDO.setStatus(OrderPackageStatusEnum.PACKAGED.getStatus());
        orderPackageDO.setPackageNo(PackageNoUtil.randomPageNo());
        orderPackageMapper.insert(orderPackageDO);

        orderItemMapper.insertPartsId(orderPackageDO.getId(), reqVO.getAddPartsIdList());

        return orderPackageDO;

    }

}
