package com.sw.common.accessory.server.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sw.common.accessory.api.feignCilent.YbFeignClients;
import com.sw.common.accessory.api.model.EquipmentDto;
import com.sw.common.accessory.server.EnumValuesAccy;
import com.sw.common.accessory.server.dto.*;
import com.sw.common.accessory.server.entity.AccessoryPartDetails;
import com.sw.common.accessory.server.entity.ApplyRecord;
import com.sw.common.accessory.server.entity.EquipmentAccessory;
import com.sw.common.accessory.server.interfaces.out.AccyOutService;
import com.sw.common.accessory.server.mapper.EquipmentAccessoryMapper;
import com.sw.common.accessory.server.service.AccessoryPartDetailsService;
import com.sw.common.accessory.server.service.AccessoryPartService;
import com.sw.common.accessory.server.service.ApplyRecordService;
import com.sw.common.accessory.server.service.EquipmentAccessoryService;
import com.sw.common.core.context.BaseContextHandler;
import com.sw.common.core.exception.BusinessException;
import com.sw.common.core.request.RequestPage;
import com.sw.common.core.response.Result;
import com.sw.common.mybatisplus.base.BaseServiceImpl;
import com.sw.common.mybatisplus.entity.Pageable;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;

;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class EquipmentAccessoryServiceImpl extends BaseServiceImpl<EquipmentAccessoryMapper, EquipmentAccessory> implements EquipmentAccessoryService {
    @Autowired
    private EquipmentAccessoryMapper equipmentAccessoryMapper;

    @Autowired
    private AccyOutService accyService;

    @Autowired
    private ApplyRecordService applyRecordService;

    @Autowired
    private AccessoryPartService accessoryPartService;

    @Autowired
    private AccessoryPartDetailsService accessoryPartDetailsService;
    @Autowired
    private YbFeignClients ybFeignClients;


    @Override
    public List<EquipmentAccessory> pages(EquipmentAccessBo bo, Pageable pageable) {
        int pages = (pageable.getPage() - 1) * pageable.getRows();
        pageable.setPage(pages);
        List<EquipmentAccessory> page = equipmentAccessoryMapper.pages(bo,pageable);
        return page;
    }
    @Override
    public int pageCount(EquipmentAccessBo bo) {
        return  equipmentAccessoryMapper.pageCount(bo);
    }
    @Override
    public void applyAccessory(ApplyAccessoryParamDto applyAccessoryParamDto) throws BusinessException {
        //判断设备是否存在
        EquipmentInfo equipmentInfo = accyService.getEquipmentInfo(applyAccessoryParamDto.getEquipmentCode());
        Assert.notNull(equipmentInfo, applyAccessoryParamDto.getEquipmentCode() + "该设备号不存在，没有获取到设备信息");
        AccessoryMaterialInfo accessoryMaterialInfo = accyService.getById(applyAccessoryParamDto.getMaterialId());
        Assert.notNull(accessoryMaterialInfo, "辅料模型数据不存在");

        EquipmentAccessory equipmentAccessory = equipmentAccessoryMapper.findByEquipmentCode(applyAccessoryParamDto.getEquipmentCode());
        if (equipmentAccessory == null) {
            createNewEquipmentAccessory(equipmentInfo, 0);
        } else {
            //修改 待出库数量
            updateWaitingOutboundCount(equipmentAccessory.getId(), equipmentAccessory.getWaitingOutboundCount(), 1);
        }
        ApplyAccessoryParam applyAccessoryParam = new ApplyAccessoryParam();
        applyAccessoryParam.setEquipmentCode(applyAccessoryParamDto.getEquipmentCode());
        applyAccessoryParam.setMaterialCode(accessoryMaterialInfo.getMaterialCode());
        applyAccessoryParam.setNumber(applyAccessoryParamDto.getNumber());
        applyAccessoryParam.setReason(applyAccessoryParamDto.getReason());
        String code = accyService.applyAccessory(applyAccessoryParam);

        //创建申请记录
        ApplyRecord applyRecord = new ApplyRecord();
        applyRecord.setCode(code);
        applyRecord.setEquipmentCode(applyAccessoryParamDto.getEquipmentCode());
        applyRecord.setMaterialId(applyAccessoryParamDto.getMaterialId());
        if (StringUtil.isNotBlank(accessoryMaterialInfo.getMaterialType())) {
            applyRecord.setMaterialType(accessoryMaterialInfo.getMaterialType());
        } else {
            applyRecord.setMaterialType(new String());
        }
        applyRecord.setMaterialName(accessoryMaterialInfo.getMaterialName());
        applyRecord.setMaterialCode(accessoryMaterialInfo.getMaterialCode());
        applyRecord.setNumber(applyAccessoryParamDto.getNumber());
        applyRecord.setUnit(accessoryMaterialInfo.getUnit());
        applyRecord.setReason(applyAccessoryParamDto.getReason());
        applyRecord.setStatus(0);
        applyRecord.setUserCreate(BaseContextHandler.getUsername());
        applyRecord.setGmtCreate(new Date());
        applyRecord.setUserConfirm(null);
        applyRecord.setGmtConfirm(null);
        applyRecordService.saveOrUpdate(applyRecord);
    }

    @Override
    public void applyMaterial(ApplyMaterialParamDto applyMaterialParamDto) {
        //判断设备是否存在
        EquipmentInfo equipmentInfo = accyService.getEquipmentInfo(applyMaterialParamDto.getEquipmentCode());
        Assert.notNull(equipmentInfo, applyMaterialParamDto.getEquipmentCode() + "该设备号不存在，没有获取到设备信息");
        EquipmentAccessory equipmentAccessory = equipmentAccessoryMapper.findByEquipmentCode(applyMaterialParamDto.getEquipmentCode());
        if (equipmentAccessory == null) {
            int number = applyMaterialParamDto.getPartDtos().size();
            createNewEquipmentAccessory(equipmentInfo, number);
        } else {
            //修改 待出库数量
            int number = applyMaterialParamDto.getPartDtos().size();
            updateWaitingOutboundCount(equipmentAccessory.getId(), equipmentAccessory.getWaitingOutboundCount(), number);
        }
        applyMaterialParamDto.getPartDtos().stream().forEach(entity -> {
            AccessoryMaterialInfo accessoryMaterialInfo = accyService.getByMaterialCode(entity.getMaterialCode());
            Assert.notNull(accessoryMaterialInfo, "辅料模型数据不存在");
            ApplyAccessoryParam applyAccessoryParam = new ApplyAccessoryParam();
            applyAccessoryParam.setEquipmentCode(applyMaterialParamDto.getEquipmentCode());
            applyAccessoryParam.setMaterialCode(entity.getMaterialCode());
            applyAccessoryParam.setNumber(entity.getNumber());
            applyAccessoryParam.setReason(applyMaterialParamDto.getReason());
            String code = accyService.applyAccessory(applyAccessoryParam);
            //创建申请记录
            ApplyRecord applyRecord = new ApplyRecord();
            applyRecord.setCode(code);
            applyRecord.setEquipmentCode(applyMaterialParamDto.getEquipmentCode());
            applyRecord.setMaterialId(entity.getMaterialId());
            if (StringUtil.isNotBlank(accessoryMaterialInfo.getMaterialType())) {
                applyRecord.setMaterialType(accessoryMaterialInfo.getMaterialType());
            } else {
                applyRecord.setMaterialType(new String());
            }
            applyRecord.setMaterialName(accessoryMaterialInfo.getMaterialName());
            applyRecord.setMaterialCode(accessoryMaterialInfo.getMaterialCode());
            applyRecord.setNumber(entity.getNumber());
            applyRecord.setUnit(accessoryMaterialInfo.getUnit());
            applyRecord.setReason(applyMaterialParamDto.getReason());
            applyRecord.setStatus(0);
            applyRecord.setUserCreate(BaseContextHandler.getUsername());
            applyRecord.setGmtCreate(new Date());
            applyRecord.setUserConfirm(null);
            applyRecord.setGmtConfirm(null);
            applyRecord.setPartCode(entity.getPartCode());
            applyRecord.setPartId(entity.getPartId());
            applyRecord.setPartName(entity.getPartName());
            applyRecord.setAccessoryStatus(0);
            applyRecordService.saveOrUpdate(applyRecord);
            Result<EquipmentDto> equipmentInfoDto = ybFeignClients.getByCodeDto(applyMaterialParamDto.getEquipmentCode());
            String deviceCodes = new String();
            if (equipmentInfoDto.getCode().equals(200)) {
                Result<DeviceDto> result = ybFeignClients.getDeviceId(equipmentInfoDto.getData().getDeviceId());
                if (result.getCode().equals(200)) {
                    deviceCodes = result.getData().getCode();
                } else {
                    throw new BusinessException("未查询到当前设备的设备类型数据!");
                }
            } else {
                throw new BusinessException("未查询到当前设备数据!");
            }
            //更新部位使用数量
            AccessoryPartDetails accessoryPart = accessoryPartDetailsService.getByCode(deviceCodes, applyMaterialParamDto.getEquipmentCode(), entity.getMaterialCode(), entity.getPartCode());
            if (!ObjectUtils.isEmpty(accessoryPart)) {
                accessoryPart.setUsableNumber(accessoryPart.getTotalNumber(), accessoryPart.getUsedNumber() + entity.getNumber());
                if (accessoryPart.getTotalNumber() - accessoryPart.getUsedNumber() - entity.getNumber() <= 0) {
                    accessoryPart.setUsedNumber(accessoryPart.getTotalNumber());
                } else {
                    accessoryPart.setUsedNumber(accessoryPart.getUsedNumber() + entity.getNumber());
                }
                accessoryPartDetailsService.updateById(accessoryPart);
            }
        });

    }

    @Override
    public EquipmentAccessory createNewEquipmentAccessory(EquipmentInfo equipmentInfo, int type) {
        EquipmentAccessory equipmentAccessory = new EquipmentAccessory();
        equipmentAccessory.setEarlyWarningCount(0);
        equipmentAccessory.setWaitingOutboundCount(type == 0 ? 0 : type);
        equipmentAccessory.setWaitingBoardingCount(0);
        equipmentAccessory.setBoardingCount(type == -1 ? 1 : 0);
        equipmentAccessory.setStockReturnCount(0);
        equipmentAccessory.setGmtCreate(new Date());
        equipmentAccessory.setUserCreate(BaseContextHandler.getUsername());
        equipmentAccessory.setArea(equipmentInfo.getArea());
        equipmentAccessory.setSeries(equipmentInfo.getSeries());
        equipmentAccessory.setEquipmentCode(equipmentInfo.getEquipmentCode());
        save(equipmentAccessory);
        return equipmentAccessory;
    }

    /**
     * 取消申请辅材
     *
     * @param applyAccessoryId 申请记录id
     */
    @Override
    public void cancelApplyAccessory(Long applyAccessoryId) throws BusinessException {
        ApplyRecord applyRecord = applyRecordService.getById(applyAccessoryId);
        Assert.isTrue(EnumValuesAccy.ApplyStatus.WAITING.getKey() == applyRecord.getStatus(), "取消申请辅材失败，当前状态不允许取消");
        boolean isUpdateTrue = applyRecordService.update(new LambdaUpdateWrapper<ApplyRecord>().set(ApplyRecord::getStatus, EnumValuesAccy.ApplyStatus.CANCEL.getKey()).eq(ApplyRecord::getId, applyRecord.getId()).eq(ApplyRecord::getStatus, EnumValuesAccy.ApplyStatus.WAITING.getKey()));
        Assert.isTrue(isUpdateTrue, "取消申请辅材失败，请重试");
        EquipmentAccessory equipmentAccessory = getOne(new LambdaQueryWrapper<EquipmentAccessory>().eq(EquipmentAccessory::getEquipmentCode, applyRecord.getEquipmentCode()));
        updateWaitingOutboundCount(equipmentAccessory.getId(), equipmentAccessory.getWaitingOutboundCount(), -1);
        accyService.cancelApplyAccessory(applyRecord.getCode());
        Result<EquipmentDto> equipmentInfo = ybFeignClients.getByCodeDto(applyRecord.getEquipmentCode());
        String deviceCodes = new String();
        if (equipmentInfo.getCode().equals(200)) {
            Result<DeviceDto> result = ybFeignClients.getDeviceId(equipmentInfo.getData().getDeviceId());
            if (result.getCode().equals(200)) {
                deviceCodes = result.getData().getCode();
            }
        }
        AccessoryPartDetails accessoryPart = accessoryPartDetailsService.getByCode(deviceCodes
                , applyRecord.getEquipmentCode(), applyRecord.getMaterialCode(), applyRecord.getPartCode());
        if (!ObjectUtils.isEmpty(accessoryPart)) {
            accessoryPart.setUsableNumber(accessoryPart.getTotalNumber(), accessoryPart.getUsedNumber() - 1);
            if (accessoryPart.getTotalNumber() - accessoryPart.getUsedNumber() - 1 <= 0) {
                accessoryPart.setUsedNumber(accessoryPart.getTotalNumber());
            } else {
                accessoryPart.setUsedNumber(accessoryPart.getUsedNumber() + 1);
            }
            accessoryPartDetailsService.updateById(accessoryPart);
        }
    }

    @Override
    public void updateStockReturnCount(Long equipmentAccessoryId, int stockReturnCount, int number) {
        Assert.isTrue(stockReturnCount + number >= 0, "退库中数量，不能小于0");
        int count = equipmentAccessoryMapper.updateStockReturnCount(equipmentAccessoryId, stockReturnCount, number);
        Assert.isTrue(count > 0, "失败，请重试，退库中数量修改失败");
    }

    @Override
    public void updateBoardingCount(Long equipmentAccessoryId, int boardingCount, int number) {
        Assert.isTrue(boardingCount + number >= 0, "上机数量，不能小于0");
        int count = equipmentAccessoryMapper.updateBoardingCount(equipmentAccessoryId, boardingCount, number);
        Assert.isTrue(count > 0, "退库失败，请重试，上机数量修改失败");
    }

    @Override
    public void updateWaitingOutboundCount(Long equipmentAccessoryId, int waitingOutboundCount, int number) {
        Assert.isTrue(waitingOutboundCount + number >= 0, "待出库数量，不能小于0");
        int count = equipmentAccessoryMapper.updateWaitingOutboundCount(equipmentAccessoryId, waitingOutboundCount, number);
        Assert.isTrue(count > 0, "失败，请重试，待出库数量修改失败");
    }

    @Override
    public void updateWaitingBoardingCount(Long equipmentAccessoryId, int waitingBoardingCount, int number) {
        Assert.isTrue(waitingBoardingCount + number >= 0, "待上机数量，不能小于0");
        int count = equipmentAccessoryMapper.updateWaitingBoardingCount(equipmentAccessoryId, waitingBoardingCount, number);
        Assert.isTrue(count > 0, "添加失败，辅材待上机数量修改失败");
    }

    @Override
    public void updateEarlyWarningCount(Long equipmentAccessoryId, int earlyWarningCount, int number) {
        Assert.isTrue(earlyWarningCount + number >= 0, "预警数量，不能小于0");
        Assert.isTrue(update(new LambdaUpdateWrapper<EquipmentAccessory>().set(EquipmentAccessory::getEarlyWarningCount, earlyWarningCount + number).eq(EquipmentAccessory::getEarlyWarningCount, earlyWarningCount).eq(EquipmentAccessory::getId, equipmentAccessoryId)),
                "预警数量修改失败，请重试");
    }

    @Override
    public EquipmentAccessory findByEquipmentCode(String equipmentCode) {
        return equipmentAccessoryMapper.findByEquipmentCode(equipmentCode);
    }
}