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

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.*;
import com.sw.common.accessory.server.interfaces.out.AccyOutService;
import com.sw.common.accessory.server.mapper.DeterminationQualityMapper;
import com.sw.common.accessory.server.service.*;
import com.sw.common.core.context.BaseContextHandler;
import com.sw.common.core.response.Result;
import com.sw.common.core.response.ResultGenerator;
import com.sw.common.mybatisplus.base.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
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.ObjectUtils;

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

@Service
@Transactional
public class DeterminationQualityServiceImpl extends BaseServiceImpl<DeterminationQualityMapper, DeterminationQuality> implements DeterminationQualityService {
    @Autowired
    private DeterminationQualityMapper mapper;
    @Autowired
    @Lazy
    private AccessoryService accessoryService;
    @Autowired
    @Lazy
    private DeterminationEchnologyService echnologyService;
    @Autowired
    @Lazy
    private AccyOutService accyService;

    @Autowired
    private ReturnRecordService returnRecordService;

    @Autowired
    private YbFeignClients ybFeignClients;

    @Autowired
    private AccessoryPartDetailsService accessoryPartDetailsService;
    @Override
    public Result confirmAudit(DeterminationQualityDto dto, DeterminationQuality entity) {
        entity.setConfirmationReview(dto.getConfirmationReview());
        entity.setStatus(1);
        entity.setAuditPass(true);
        entity.setDel(true);
        entity.setUpdateBy(BaseContextHandler.getUsername());
        entity.setUpdateTime(new Date());
        int update = mapper.updateById(entity);
        if(update>=1){
            StockReturn stockReturn = new StockReturn();
            Accessory accessory = accessoryService.get(entity.getAccessoryId());
            String code = "";
            if(entity.isMaterialAnomaly()){
                DeterminationEchnology determinationEchnology = echnologyService.get(entity.getEchnologyId());
                stockReturn.setReason(determinationEchnology.getReasonAnalysis());
                //创建仓储系统的退库申请单
                code = accyService.stockEchnologyReturnOutApply(accessory, stockReturn.getReason(),determinationEchnology);
                determinationEchnology.setInputBillNo(code);
                echnologyService.updateById(determinationEchnology);
            }else {
                //创建仓储系统的退库申请单
                code = accyService.stockQualityReturnOutApply(accessory, stockReturn.getReason(),entity);
            }
            //更新入库单号到评审表
            entity.setInputBillNo(code);
            mapper.updateById(entity);
            accessory.setStatus(EnumValuesAccy.AccyUseStatus.退库中.getKey());
            accessoryService.saveOrUpdate(accessory);
            if(!entity.isMaterialAnomaly()){
                switch (entity.getResultDetermination()){
                    case "报废":
                        accessory.setAccessoryStatus(EnumValuesAccy.AccessoryStatus.报废.getKey());
                        break;
                    case "返修":
                        accessory.setAccessoryStatus(EnumValuesAccy.AccessoryStatus.返修.getKey());
                        break;
                    default:
                        accessory.setAccessoryStatus(EnumValuesAccy.AccessoryStatus.煅烧可用.getKey());
                }
                accessoryService.saveOrUpdate(accessory);
            }
            // 增加退库记录表
            ReturnRecord returnRecord = new ReturnRecord();
            returnRecord.setAccessoryId(accessory.getId());
            returnRecord.setCode(code);
            returnRecord.setAccessoryStatus(accessory.getAccessoryStatus());
            returnRecord.setEquipmentCode(accessory.getEquipmentCode());
            returnRecord.setMaterialType(accessory.getMaterialType());
            returnRecord.setMaterialName(accessory.getMaterialName());
            returnRecord.setMaterialCode(accessory.getMaterialCode());
            returnRecord.setBatchCode(accessory.getBatchCode());
            returnRecord.setUniqueCode(accessory.getUniqueCode());
            returnRecord.setNumber(stockReturn.getNumber() == null ?1:stockReturn.getNumber());
            returnRecord.setSpecification(accessory.getSpecification());
            returnRecord.setUnit(accessory.getUnit());
            returnRecord.setSupplier(accessory.getSupplier());
            returnRecord.setRatedLife(accessory.getRatedLife());
            returnRecord.setUsefulLife(accessory.getUsefulLife());
            returnRecord.setRemainingLife(accessory.getRemainingLife());
            returnRecord.setReason(stockReturn.getReason());
            returnRecord.setUseStatus(accessory.getStatus());
            returnRecord.setStatus(EnumValuesAccy.ReturnStatus.WAIT_RECEIVE.getKey());
            returnRecord.setUserCreate(BaseContextHandler.getUsername());
            returnRecord.setGmtCreate(new Date());
            returnRecordService.saveOrUpdate(returnRecord);
            List<AccessoryDetails> accessoryDetails = accessoryService.findAccessoryDetailsByEquipmentAccessoryId(accessory.getEquipmentAccessoryId(), null, null);
            Optional<AccessoryDetails> accessoryDetail = accessoryDetails.stream().filter(details -> details.getId().equals(entity.getAccessoryId())).findFirst();
            //更新部位使用数量
            if (accessoryDetail.isPresent()) {
                Result<EquipmentDto> equipmentInfo = ybFeignClients.getByCodeDto(accessory.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
                        , accessory.getEquipmentCode(), accessory.getMaterialCode(), accessoryDetail.get().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);
                }
            }
        }
        return ResultGenerator.success();
    }


    @Override
    public Result unConfirmAudit(DeterminationEchnologyDto dto, DeterminationQuality entity) {
        entity.setResultDetermination(dto.getResultDetermination());
        entity.setStatus(2);
        entity.setAuditPass(false);
        entity.setUpdateBy(BaseContextHandler.getUsername());
        entity.setUpdateTime(new Date());
        entity.setDel(true);
        int update = mapper.updateById(entity);
        if(update>=1 && entity.isMaterialAnomaly()){
            DeterminationEchnology determinationEchnology = echnologyService.get(entity.getEchnologyId());
            determinationEchnology.setDel(false);
            determinationEchnology.setAuditPass(false);
            determinationEchnology.setMaterialAnomaly(true);
            determinationEchnology.setStatus(3);
            echnologyService.updateById(determinationEchnology);
        }
        if(!entity.isMaterialAnomaly()){
            Accessory accessory = accessoryService.get(entity.getAccessoryId());
            accessory.setStatus(EnumValuesAccy.AccyUseStatus.待上机.getKey());
            accessory.setAccessoryStatus(0);
            accessoryService.saveOrUpdate(accessory);
        }
        return ResultGenerator.success();
    }

    @Override
    public DeterminationQualityDto findById(Long id) {
        DeterminationQuality determinationQuality = mapper.selectById(id);
        DeterminationQualityDto eagerDto = toEagerDto(determinationQuality);
        if(determinationQuality.isMaterialAnomaly()){
            DeterminationEchnologyDto determinationEchnologyDto = echnologyService.findById(determinationQuality.getEchnologyId());
            eagerDto.setDeterminationEchnologyDto(determinationEchnologyDto);
        }else {
            DeterminationEchnologyDto eagerEchnologyDto = new DeterminationEchnologyDto();
            BeanUtils.copyProperties(eagerDto,eagerEchnologyDto);
            String equipmentCode = "";
            String materialCode = "";
            if (StringUtils.isNotBlank(determinationQuality.getEquipmentCode())) {
                equipmentCode = determinationQuality.getEquipmentCode();
            }
            if (StringUtils.isNotBlank(determinationQuality.getMaterialCode())) {
                materialCode = determinationQuality.getMaterialCode();
            }
            AccessoryPartDetails accessoryPartDetails = accessoryPartDetailsService.getByDeviceCodeAndMaterialCode(equipmentCode,materialCode);
            if(org.apache.commons.lang3.ObjectUtils.isNotEmpty(accessoryPartDetails)){
                eagerEchnologyDto.setPartName(accessoryPartDetails.getPartName());
            }
            eagerDto.setDeterminationEchnologyDto(eagerEchnologyDto);
        }
        return eagerDto;
    }

    @Override
    public DeterminationQuality getDeterminationQualityById(Long id) {
        return mapper.getDeterminationQualityById(id);
    }

    @Override
    public DeterminationQualityDto findByAccessoryId(Long id) {
        DeterminationQuality qualityByAccessoryId = mapper.findQualityByAccessoryId(id);
        if(null==qualityByAccessoryId){
            return null;
        }
        DeterminationQualityDto eagerDto = toEagerDto(qualityByAccessoryId);
        if(qualityByAccessoryId.isMaterialAnomaly()){
            DeterminationEchnology echnologyByAccessoryId = echnologyService.findEchnologyByAccessoryId(id);
            DeterminationEchnologyDto determinationEchnologyDto = new DeterminationEchnologyDto();
            BeanUtils.copyProperties(echnologyByAccessoryId,determinationEchnologyDto);
            eagerDto.setDeterminationEchnologyDto(determinationEchnologyDto);
        }
        return eagerDto;
    }

    @Override
    public DeterminationQualityDto findByInputBillNo(String billNo) {
        DeterminationQuality qualityByAccessoryId = mapper.findByInputBillNo(billNo);
        if(null==qualityByAccessoryId){
            return null;
        }
        DeterminationQualityDto eagerDto = toEagerDto(qualityByAccessoryId);
        if(qualityByAccessoryId.isMaterialAnomaly()){
            DeterminationEchnology echnologyByAccessoryId = echnologyService.findByInputBillNo(billNo);
            DeterminationEchnologyDto determinationEchnologyDto = new DeterminationEchnologyDto();
            BeanUtils.copyProperties(echnologyByAccessoryId,determinationEchnologyDto);
            eagerDto.setDeterminationEchnologyDto(determinationEchnologyDto);
        }
        return eagerDto;
    }

    public DeterminationQualityDto toLazyDto(DeterminationQuality entity) {
        DeterminationQualityDto determinationQualityDto = new DeterminationQualityDto();
        BeanUtils.copyProperties(entity, determinationQualityDto);
        return determinationQualityDto;
    }

    public DeterminationQualityDto toEagerDto(DeterminationQuality entity) {
        DeterminationQualityDto determinationQualityDto = new DeterminationQualityDto();
        BeanUtils.copyProperties(entity, determinationQualityDto);
        return determinationQualityDto;
    }

    public DeterminationQuality fromDto(DeterminationQualityDto dto) {
        DeterminationQuality determinationQuality = new DeterminationQuality();
        BeanUtils.copyProperties(dto, determinationQuality);
        return determinationQuality;
    }

    @Override
    public DeterminationQuality findEchnologyByUniqueCode(String uniqueCode) {
        return mapper.findQualityByUniqueCode(uniqueCode);
    }

    @Override
    public DeterminationQuality findEchnologyByAccessoryId(Long accessoryId) {
        return mapper.findQualityByAccessoryId(accessoryId);
    }
}
