package com.sw.common.accessory.server.interfaces.in.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.AccessoryMaterialInfo;
import com.sw.common.accessory.server.dto.ApplyAccessoryData;
import com.sw.common.accessory.server.dto.DeviceDto;
import com.sw.common.accessory.server.entity.*;
import com.sw.common.accessory.server.interfaces.in.AccyInService;
import com.sw.common.accessory.server.interfaces.out.AccyOutService;
import com.sw.common.accessory.server.service.*;
import com.sw.common.core.exception.BusinessException;
import com.sw.common.core.response.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import java.util.Date;

/**
 * @author zhaowenjie
 */
@Validated
@Service
@Transactional(rollbackFor = Exception.class)
public class AccyInServiceImpl implements AccyInService {
    @Autowired
    private ReturnRecordService returnRecordService;

    @Autowired
    private AccessoryService accessoryService;

    @Autowired
    private EquipmentAccessoryService equipmentAccessoryService;

    @Autowired
    private ApplyRecordService applyRecordService;

    @Autowired
    private AccyOutService accyOutService;
    @Autowired
    private AccessoryPartService accessoryPartService;
    @Autowired
    private AccessoryPartDetailsService accessoryPartDetailsService;
    @Autowired
    private YbFeignClients ybFeignClients;
    @Override
    public void stockReturnApplyFeedback(String code, int status, String userConfirm) throws BusinessException {
        Assert.notNull(code, "退库单号，不能为空");
        LambdaQueryWrapper<ReturnRecord> returnRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        returnRecordLambdaQueryWrapper.eq(ReturnRecord::getCode, code);
        ReturnRecord returnRecord = returnRecordService.getOne(returnRecordLambdaQueryWrapper);
        Assert.notNull(returnRecord, "退库单号，记录不存在");
        Accessory accessory = accessoryService.get(returnRecord.getAccessoryId());
        Assert.isTrue(accessory.getStatus() == EnumValuesAccy.AccyUseStatus.退库中.getKey(), "辅材状态不是退库中");
        if (status == 1) {
            returnRecord.setStatus(EnumValuesAccy.ReturnStatus.HAS_REJECT.getKey());
            returnRecord.setUserConfirm(userConfirm);
            returnRecord.setGmtConfirm(new Date());
            accessoryService.cancelReturnRecordSave(accessory, returnRecord);
        } else if(status == 2){
            returnRecord.setStatus(EnumValuesAccy.ReturnStatus.HAS_CANCEL.getKey());
            returnRecord.setUserConfirm(userConfirm);
            returnRecord.setGmtConfirm(new Date());
            accessoryService.cancelReturnRecordSave(accessory, returnRecord);
        } else if (status == 0) {
            EquipmentAccessory equipmentAccessory = equipmentAccessoryService.get(accessory.getEquipmentAccessoryId());
            equipmentAccessoryService.updateStockReturnCount(equipmentAccessory.getId(), equipmentAccessory.getStockReturnCount(), -1);
            returnRecord.setStatus(EnumValuesAccy.ReturnStatus.HAS_RECEIVE.getKey());
            returnRecord.setUserConfirm(userConfirm);
            returnRecord.setGmtConfirm(new Date());
            boolean updateReturnRecordStatus = returnRecordService.update(returnRecord, new LambdaUpdateWrapper<ReturnRecord>().eq(ReturnRecord::getId, returnRecord.getId()).eq(ReturnRecord::getStatus, EnumValuesAccy.ReturnStatus.WAIT_RECEIVE.getKey()));
            Assert.isTrue(updateReturnRecordStatus, "失败，请重试，退库申请单状态修改失败");
            accessory.setStatus(EnumValuesAccy.AccyUseStatus.已退库.getKey());
            accessory.setEquipmentCode(null);
            accessory.setEquipmentAccessoryId(null);
            accessoryService.saveOrUpdate(accessory);
        } else {
            throw new BusinessException("status参数错误");
        }
    }

    @Override
    public void applyAccessoryFeedback(@Valid ApplyAccessoryData applyAccessoryData) throws BusinessException {
        LambdaQueryWrapper<ApplyRecord> applyRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        applyRecordLambdaQueryWrapper.eq(ApplyRecord::getCode, applyAccessoryData.getCode());
        ApplyRecord applyRecord = applyRecordService.getOne(applyRecordLambdaQueryWrapper);
        Assert.notNull(applyRecord, "【" + applyAccessoryData.getCode() + "】申请单号，记录不存在");
        Assert.isTrue(applyRecord.getStatus() == EnumValuesAccy.ApplyStatus.WAITING.getKey(), "【" + applyAccessoryData.getCode() + "】申请单不是待出库状态");
        EquipmentAccessory equipmentAccessory = equipmentAccessoryService.getOne(new LambdaQueryWrapper<EquipmentAccessory>().eq(EquipmentAccessory::getEquipmentCode, applyRecord.getEquipmentCode()));
        Assert.notNull(equipmentAccessory, "设备辅材信息不存在");

        // 填充确认人，确认时间
        applyRecord.setUserConfirm(applyAccessoryData.getUserConfirm());
        applyRecord.setGmtConfirm(new Date());
        equipmentAccessoryService.updateWaitingOutboundCount(equipmentAccessory.getId(), equipmentAccessory.getWaitingOutboundCount(), -1);

        if (applyAccessoryData.getStatus() == 1) {
            applyRecord.setStatus(EnumValuesAccy.ApplyStatus.REFUSE.getKey());
            boolean updateApplyRecordStatus = applyRecordService.update(applyRecord, new LambdaUpdateWrapper<ApplyRecord>().eq(ApplyRecord::getId, applyRecord.getId()).eq(ApplyRecord::getStatus, EnumValuesAccy.ApplyStatus.WAITING.getKey()));
            Assert.isTrue(updateApplyRecordStatus, "失败，请重试，辅材申请单状态修改失败");
//            Result<EquipmentDto> equipmentInfoDto = ybFeignClients.getByCodeDto(applyRecord.getEquipmentCode());
//            String deviceTypeCode = new String();
//            if(equipmentInfoDto.getCode().equals(200)){
//                Result<DeviceDto> result = ybFeignClients.getDeviceId(equipmentInfoDto.getData().getDeviceId());
//                if(result.getCode().equals(200)){
//                    deviceTypeCode = result.getData().getCode();
//                }else {
//                    throw new BusinessException("未查询到当前设备的设备类型数据!");
//                }
//            }else {
//                throw new BusinessException("未查询到当前设备数据!");
//            }
//            AccessoryPartDetails accessoryPart = accessoryPartDetailsService.getByCode(deviceTypeCode,applyRecord.getEquipmentCode(),applyRecord.getMaterialCode(), applyRecord.getPartCode());
//            if(!ObjectUtils.isEmpty(accessoryPart)){
//                accessoryPart.setUsableNumber(accessoryPart.getTotalNumber(),accessoryPart.getUsedNumber()-applyRecord.getNumber());
//                accessoryPart.setUsedNumber(accessoryPart.getUsedNumber()-applyRecord.getNumber());
//                accessoryPartDetailsService.updateById(accessoryPart);
//            }
        } else if (applyAccessoryData.getStatus() == 0) {
            // 修改出库单状态以及确认人
            applyRecord.setStatus(EnumValuesAccy.ApplyStatus.OUT.getKey());
            boolean updateApplyRecordStatus = applyRecordService.update(applyRecord, new LambdaUpdateWrapper<ApplyRecord>().eq(ApplyRecord::getId, applyRecord.getId()).eq(ApplyRecord::getStatus, EnumValuesAccy.ApplyStatus.WAITING.getKey()));
            Assert.isTrue(updateApplyRecordStatus, "失败，请重试，辅材申请单状态修改失败");

            for (ApplyAccessoryData.AccessoryData accessoryData : applyAccessoryData.getAccessoryDatas()) {
                Assert.notNull(accessoryData.getUniqueCode(), "辅材的唯一码，不能为空");
                equipmentAccessoryService.updateWaitingBoardingCount(equipmentAccessory.getId(), equipmentAccessory.getWaitingBoardingCount(), 1);
                equipmentAccessory.setWaitingBoardingCount(equipmentAccessory.getWaitingBoardingCount() + 1);
                Accessory accessory = accessoryService.getOne(new LambdaQueryWrapper<Accessory>().eq(Accessory::getUniqueCode, accessoryData.getUniqueCode()));
                if (accessory == null) {
                    // 出库
                    accessory = newAccessory(accessoryData, applyRecord, equipmentAccessory);
                    accessory.setUserCreate(applyAccessoryData.getUserConfirm());
                    accessoryService.saveOrUpdate(accessory);
                } else {
                    Assert.isTrue(EnumValuesAccy.AccyUseStatus.已退库.getKey() == accessory.getStatus(), accessoryData.getUniqueCode() + "该唯一码，已上机使用，无法出库");
                    accessory.setEquipmentAccessoryId(equipmentAccessory.getId());
                    accessory.setEquipmentCode(equipmentAccessory.getEquipmentCode());
                    accessory.setUserCreate(applyAccessoryData.getUserConfirm());
                    accessory.setGmtCreate(new Date());
                    accessory.setStatus(EnumValuesAccy.AccyUseStatus.待上机.getKey());
                    boolean updateAccessoryStatus = accessoryService.update(accessory, new LambdaUpdateWrapper<Accessory>().eq(Accessory::getId, accessory.getId()).eq(Accessory::getStatus, EnumValuesAccy.AccyUseStatus.已退库.getKey()));
                    Assert.isTrue(updateAccessoryStatus, "失败，请重试，辅料状态修改失败");
                }
            }
//            Result<EquipmentDto> equipmentInfoDto = ybFeignClients.getByCodeDto(applyRecord.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,applyRecord.getEquipmentCode(),applyRecord.getMaterialCode(), applyRecord.getPartCode());
//            if(!ObjectUtils.isEmpty(accessoryPart)){
//                accessoryPart.setUsableNumber(accessoryPart.getTotalNumber(),accessoryPart.getUsedNumber()-applyRecord.getNumber());
//                accessoryPart.setUsedNumber(accessoryPart.getUsedNumber()-applyRecord.getNumber());
//                accessoryPartDetailsService.updateById(accessoryPart);
//            }
        } else {
            throw new BusinessException("status参数错误");
        }
    }

    private Accessory newAccessory(ApplyAccessoryData.AccessoryData accessoryData, ApplyRecord applyRecord, EquipmentAccessory equipmentAccessory) {
        AccessoryMaterialInfo accessoryMaterialInfo = accyOutService.getById(applyRecord.getMaterialId());
        Accessory accessory = new Accessory();
        accessory.setEquipmentAccessoryId(equipmentAccessory.getId());
        accessory.setEquipmentCode(equipmentAccessory.getEquipmentCode());
        accessory.setMaterialId(applyRecord.getMaterialId());
        accessory.setMaterialName(applyRecord.getMaterialName());
        accessory.setMaterialType(applyRecord.getMaterialType());
        accessory.setMaterialCode(applyRecord.getMaterialCode());
        accessory.setBatchCode(accessoryData.getBatchCode());
        accessory.setNumber(1);
        accessory.setUniqueCode(accessoryData.getUniqueCode());
        accessory.setAccessoryStatus(0);
        accessory.setWarnStatus(EnumValuesAccy.WarningStatus.NO_WARNING.getKey());
        accessory.setSupplier(accessoryData.getSupplier());
        accessory.setSpecification(accessoryMaterialInfo.getSpecification());
        accessory.setXh(accessoryMaterialInfo.getXh());
        accessory.setTh(accessoryMaterialInfo.getTh());
        accessory.setUnit(accessoryMaterialInfo.getUnit());
        accessory.setLifeType(accessoryMaterialInfo.getLifeType());
        accessory.setRatedLife(accessoryMaterialInfo.getUseLife().intValue());
        accessory.setUsefulLife(0);
        accessory.setRemainingLife(accessoryMaterialInfo.getUseLife().intValue());
        accessory.setWarnLife(accessoryMaterialInfo.getWarnTime().intValue());
        accessory.setGmtCreate(new Date());
        accessory.setStatus(EnumValuesAccy.AccyUseStatus.待上机.getKey());
        return accessory;
    }

    @Override
    public void upper(String uniqueCode, String equipmentCode, Integer accessoryStatus) {
        accessoryService.upper(uniqueCode, equipmentCode, accessoryStatus);
    }

    /**
     * 下机
     *
     * @param uniqueCode    辅材唯一码
     * @param equipmentCode 设备编号
     */
    @Override
    public void down(String uniqueCode, String equipmentCode, Integer accessoryStatus) {
        accessoryService.down(uniqueCode, equipmentCode, null, accessoryStatus);
    }


    @Override
    public void down(String uniqueCode, String equipmentCode, Integer life, Integer accessoryStatus) {
        accessoryService.down(uniqueCode, equipmentCode, life, accessoryStatus);
    }

    @Override
    public void canUpper(String uniqueCode) {
        accessoryService.canUpper(uniqueCode);
    }

    @Override
    public void consumptionLife(String equipmentCode, Integer lifeType, Integer life) throws BusinessException {
        accessoryService.consumptionLife(equipmentCode, lifeType, life);
    }
}
