package com.maintain.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.maintain.business.domain.*;
import com.maintain.business.domain.vo.ErpMaterialInventoryRecordVo;
import com.maintain.business.domain.vo.ErpUserVo;
import com.maintain.business.domain.vo.ErpWarehouseVo;
import com.maintain.business.mapper.*;
import com.maintain.business.service.IErpMaterialService;
import com.maintain.common.enums.InventoryType;
import com.maintain.common.enums.IsEnableStatus;
import com.maintain.common.enums.PickingState;
import com.maintain.common.enums.RepairFormState;
import com.maintain.common.exception.ServiceException;
import com.maintain.common.utils.StringUtils;
import com.maintain.common.core.page.TableDataInfo;
import com.maintain.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.maintain.business.domain.bo.ErpRepairFormDeliveryBo;
import com.maintain.business.domain.vo.ErpRepairFormDeliveryVo;
import com.maintain.business.service.IErpRepairFormDeliveryService;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 报修单-交车信息Service业务层处理
 *
 * @author liushuai
 * @date 2025-04-01
 */
@RequiredArgsConstructor
@Service
public class ErpRepairFormDeliveryServiceImpl implements IErpRepairFormDeliveryService {

    private final ErpRepairFormDeliveryMapper baseMapper;
    private final ErpUserMapper userMapper;
    private final ErpRepairFormMapper repairFormMapper;
    private final ErpMaterialPickingMapper pickingMapper;
    private final ErpMaterialPickingInfoMapper pickingInfoMapper;
    private final IErpMaterialService materialService;
    private final ErpMaterialInventoryRecordMapper materialInventoryRecordMapper;
    private final ErpMaterialPutawayInfoMapper putawayInfoMapper;
    private final ErpWarehouseMapper warehouseMapper;

    /**
     * 查询报修单-交车信息
     */
    @Override
    public ErpRepairFormDeliveryVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询报修单-交车信息列表
     */
    @Override
    public TableDataInfo<ErpRepairFormDeliveryVo> queryPageList(ErpRepairFormDeliveryBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ErpRepairFormDelivery> lqw = buildQueryWrapper(bo);
        Page<ErpRepairFormDeliveryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询报修单-交车信息列表
     */
    @Override
    public List<ErpRepairFormDeliveryVo> queryList(ErpRepairFormDeliveryBo bo) {
        LambdaQueryWrapper<ErpRepairFormDelivery> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ErpRepairFormDelivery> buildQueryWrapper(ErpRepairFormDeliveryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ErpRepairFormDelivery> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getRepairFormId() != null, ErpRepairFormDelivery::getRepairFormId, bo.getRepairFormId());
        lqw.eq(bo.getDeliveryUserId() != null, ErpRepairFormDelivery::getDeliveryUserId, bo.getDeliveryUserId());
        lqw.like(StringUtils.isNotBlank(bo.getDeliveryUserName()), ErpRepairFormDelivery::getDeliveryUserName, bo.getDeliveryUserName());
        lqw.eq(bo.getDeliveryTime() != null, ErpRepairFormDelivery::getDeliveryTime, bo.getDeliveryTime());
        lqw.eq(StringUtils.isNotBlank(bo.getDeliveryRemark()), ErpRepairFormDelivery::getDeliveryRemark, bo.getDeliveryRemark());
        lqw.eq(StringUtils.isNotBlank(bo.getDeliveryUrl()), ErpRepairFormDelivery::getDeliveryUrl, bo.getDeliveryUrl());
        lqw.like(StringUtils.isNotBlank(bo.getCarPickupUserName()), ErpRepairFormDelivery::getCarPickupUserName, bo.getCarPickupUserName());
        lqw.eq(StringUtils.isNotBlank(bo.getCarPickupUserPhone()), ErpRepairFormDelivery::getCarPickupUserPhone, bo.getCarPickupUserPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getCarPickupUrl()), ErpRepairFormDelivery::getCarPickupUrl, bo.getCarPickupUrl());
        return lqw;
    }

    /**
     * 新增报修单-交车信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertByBo(ErpRepairFormDeliveryBo bo) {
        ErpRepairFormDelivery add = BeanUtil.toBean(bo, ErpRepairFormDelivery.class);
        ErpUserVo userVo = userMapper.selectVoById(bo.getDeliveryUserId());
        add.setDeliveryUserName(userVo.getName());
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            // 报修单更新为已交工
            ErpRepairForm erpRepairForm = repairFormMapper.selectById(add.getRepairFormId());
            erpRepairForm.setIsDelivery(IsEnableStatus.YES.getCode());
            erpRepairForm.setState(RepairFormState.TWO.getCode());
            erpRepairForm.setMaintainEndTime(new Date());
            erpRepairForm.setDeliveryTime(new Date());
            repairFormMapper.updateById(erpRepairForm);
            // 根据报修单ID更新未完成的出库单状态
            LambdaUpdateWrapper<ErpMaterialPicking> pickingLambdaUpdateWrapper = Wrappers.lambdaUpdate();
            pickingLambdaUpdateWrapper.eq(ErpMaterialPicking::getRepairFormId, add.getRepairFormId()).eq(ErpMaterialPicking::getState, PickingState.ONE.getCode());
            pickingLambdaUpdateWrapper.set(ErpMaterialPicking::getState, PickingState.TWO.getCode()).set(ErpMaterialPicking::getOutTime, new Date());
            pickingMapper.update(pickingLambdaUpdateWrapper);
            // 根据报修单ID查询未完成的出库单明细数据，并更新库存
            LambdaQueryWrapper<ErpMaterialPickingInfo> pickingInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
            pickingInfoLambdaQueryWrapper.eq(ErpMaterialPickingInfo::getRepairFormId, add.getRepairFormId()).eq(ErpMaterialPickingInfo::getState, PickingState.ONE.getCode());
            List<ErpMaterialPickingInfo> pickingInfoList = pickingInfoMapper.selectList(pickingInfoLambdaQueryWrapper);
            if (!pickingInfoList.isEmpty()) {
                List<ErpMaterialInventoryRecord> inventoryRecordList = pickingInfoList.stream().map(item -> {
                    ErpMaterialInventoryRecordVo recordVo = materialInventoryRecordMapper.customQueryInventoryById(item.getRecordId());
                    if (null == recordVo) {
                        throw new ServiceException("仓库["+item.getWarehouseName()+"]中物料["+item.getMaterialName()+"]库存异常，请联系管理员！");
                    }
                    if (item.getCollectNumber().compareTo(recordVo.getInventory()) > 0) {
                        throw new ServiceException("仓库["+item.getWarehouseName()+"]中物料["+item.getMaterialName()+"]库存不足，请调整后重试!");
                    }
                    /* 记录已出数量 */
                    ErpMaterialInventoryRecord inventoryRecord = materialInventoryRecordMapper.selectById(item.getRecordId());
                    if (null == inventoryRecord) {
                        throw new ServiceException("库存存在异常，请联系管理员！！！");
                    }
                    ErpMaterialPutawayInfo putawayInfo = putawayInfoMapper.selectById(inventoryRecord.getInfoId());
                    putawayInfo.setIssuedNumber(putawayInfo.getIssuedNumber().add(item.getCollectNumber()));
                    putawayInfoMapper.updateById(putawayInfo);
                    /* 创建库存记录 */
                    ErpMaterialInventoryRecord record = new ErpMaterialInventoryRecord();
                    record.setInfoId(item.getId());
                    record.setMaterialId(item.getMaterialId());
                    ErpWarehouseVo warehouseVo = warehouseMapper.selectVoById(item.getWarehouseId());
                    record.setWarehouseId(warehouseVo.getId());
                    record.setDeptId(warehouseVo.getDeptId());
                    record.setVendorId(item.getVendorId());
                    record.setNumber(item.getCollectNumber());
                    record.setPrice(item.getPrice());
                    record.setMoney(item.getMoney());
                    record.setType(InventoryType.picking.getCode());
                    return record;
                }).collect(Collectors.toList());
                materialInventoryRecordMapper.insertBatch(inventoryRecordList);
            }
        }
        return flag;
    }

    /**
     * 修改报修单-交车信息
     */
    @Override
    public Boolean updateByBo(ErpRepairFormDeliveryBo bo) {
        ErpRepairFormDelivery update = BeanUtil.toBean(bo, ErpRepairFormDelivery.class);
        ErpUserVo userVo = userMapper.selectVoById(bo.getDeliveryUserId());
        update.setDeliveryUserName(userVo.getName());
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ErpRepairFormDelivery entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除报修单-交车信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
