package com.sw.common.accessory.api;

import com.sw.common.accessory.api.feignCilent.StoreFeignClients;
import com.sw.common.accessory.api.feignCilent.YbFeignClients;
import com.sw.common.accessory.api.model.*;
import com.sw.common.accessory.server.dto.*;
import com.sw.common.accessory.server.entity.Accessory;
import com.sw.common.accessory.server.entity.DeterminationEchnology;
import com.sw.common.accessory.server.entity.DeterminationQuality;
import com.sw.common.accessory.server.interfaces.out.AccyOutService;
import com.sw.common.core.exception.BusinessException;
import com.sw.common.core.response.Result;
import com.sw.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author wupeng
 * @Description 获取外部系统数据的接口
 * @Date 17:11 2023/12/31
 * @Param
 * @return
 **/
@Service
public class AccyOutServiceImpl implements AccyOutService {

    @Autowired
    private StoreFeignClients storeFeignClients;

    @Autowired
    private YbFeignClients ybFeignClients;

    @Override
    public EquipmentInfo getEquipmentInfo(String equipmentCode) {
        try {
            Result<EquipmentDto> result = ybFeignClients.getEquipmentInfo(equipmentCode);
            Integer code = result.getCode();
            EquipmentDto equipmentDto = result.getData();
            if (code != 200 || equipmentDto == null) {
                throw new BusinessException("根据设备编号【" + equipmentCode + "】查询设备信息失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            EquipmentInfo equipmentInfo = new EquipmentInfo();
            equipmentInfo.setEquipmentCode(equipmentDto.getCode());
            equipmentInfo.setArea(equipmentDto.getArea());
            equipmentInfo.setSeries(equipmentDto.getSeries());
            equipmentInfo.setEquipmentType(equipmentDto.getDeviceName());
            return equipmentInfo;
        } catch (Exception e) {
            throw new BusinessException("根据设备编号查询设备信息异常，" + e.getMessage());
        }
    }

    @Override
    public String stockReturnApply(Accessory accessory, String reason) {
        //辅料退库
        try {
            Result<String> result = storeFeignClients.inputApply(newInputBill(accessory, reason));
            Integer code = result.getCode();
            String data = result.getData();
            if (code != 200 || StringUtils.isBlank(data)) {
                throw new BusinessException("辅材退库失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return data;
        } catch (Exception e) {
            throw new BusinessException("辅材退库异常，" + e.getMessage());
        }
    }

    @Override
    public String stockEchnologyReturnOutApply(Accessory accessory, String reason, DeterminationEchnology determinationEchnology) {
        //辅料退库
        try {
            Result<String> result = storeFeignClients.inputApply(newEchnologyInputBillBo(accessory, reason,determinationEchnology));
            Integer code = result.getCode();
            String data = result.getData();
            if (code != 200 || StringUtils.isBlank(data)) {
                throw new BusinessException("辅材退库失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return data;
        } catch (Exception e) {
            throw new BusinessException("辅材退库异常，" + e.getMessage());
        }
    }
    @Override
    public String stockQualityReturnOutApply(Accessory accessory, String reason, DeterminationQuality determinationQuality) {
        //辅料退库
        try {
            Result<String> result = storeFeignClients.inputApply(newQualityInputBillBo(accessory, reason,determinationQuality));
            Integer code = result.getCode();
            String data = result.getData();
            if (code != 200 || StringUtils.isBlank(data)) {
                throw new BusinessException("辅材退库失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return data;
        } catch (Exception e) {
            throw new BusinessException("辅材退库异常，" + e.getMessage());
        }
    }
    @Override
    public void cancelStockReturnApply(String billNo) {
        try {
            Result result = storeFeignClients.cancelInputApply(billNo);
            Integer code = result.getCode();
            if (code != 200) {
                throw new BusinessException("取消辅材退库失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
        } catch (Exception e) {
            throw new BusinessException("取消辅材退库失败，" + e.getMessage());
        }
    }

    @Override
    public String applyAccessory(ApplyAccessoryParam applyAccessoryParam) {
        try {
            Result<String> result = storeFeignClients.outputApply(newOutputBill(applyAccessoryParam));
            Integer code = result.getCode();
            String data = result.getData();
            if (code != 200 || StringUtils.isBlank(data)) {
                throw new BusinessException("辅材申请出库失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return data;
        } catch (Exception e) {
            throw new BusinessException("辅材申请出库异常，" + e.getMessage());
        }
    }

    @Override
    public void cancelApplyAccessory(String billNo) {
        try {
            Result result = storeFeignClients.cancelOutputApply(billNo);
            Integer code = result.getCode();
            if (code != 200) {
                throw new BusinessException("辅材申请出库失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
        } catch (Exception e) {
            throw new BusinessException("辅材申请出库异常，" + e.getMessage());
        }
    }

    @Override
    public AccessoryMaterialInfo getById(Long materialId) {
        try {
            Result<AccessoryMaterialDto> result = ybFeignClients.getByMaterialId(materialId);
            Integer code = result.getCode();
            AccessoryMaterialDto materialModelDto = result.getData();
            if (code != 200 || materialModelDto == null) {
                throw new BusinessException("根据物料ID【" + materialId + "】获取辅材信息失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return this.setAccessoryMaterialInfo(materialModelDto);
        } catch (Exception e) {
            throw new BusinessException("根据物料ID【" + materialId + "】获取辅材信息失败，" + e.getMessage());
        }
    }

    @Override
    public AccessoryMaterialInfo getByMaterialCode(String materialCode) {
        try {
            Result<AccessoryMaterialDto> result = ybFeignClients.getByMaterialCodes(materialCode);
            Integer code = result.getCode();
            AccessoryMaterialDto materialModelDto = result.getData();
            if (code != 200 || materialModelDto == null) {
                throw new BusinessException("根据物料编码【" + materialCode + "】获取辅材信息失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return this.setAccessoryMaterialInfo(materialModelDto);
        } catch (Exception e) {
            throw new BusinessException("根据物料编码【" + materialCode + "】获取辅材信息异常，" + e.getMessage());
        }
    }

    @Override
    public AccessoryMaterialInfo getByMaterialCodes(String materialCode) {
        try {
            Result<AccessoryMaterialDto> result = ybFeignClients.getByMaterialCodes(materialCode);
            Integer code = result.getCode();
            AccessoryMaterialDto materialModelDto = result.getData();
            if (code != 200 || materialModelDto == null) {
                throw new BusinessException("根据物料编码【" + materialCode + "】获取辅材信息失败，状态码：" + code + "，反馈信息：" + result.getMessage());
            }
            return this.setAccessoryMaterialInfos(materialModelDto);
        } catch (Exception e) {
            throw new BusinessException("根据物料编码【" + materialCode + "】获取辅材信息异常，" + e.getMessage());
        }
    }

    private AccessoryMaterialInfo setAccessoryMaterialInfo(AccessoryMaterialDto materialModelDto) {
        AccessoryMaterialInfo accessoryMaterialInfo = new AccessoryMaterialInfo();
        accessoryMaterialInfo.setMaterialId(Long.valueOf(materialModelDto.getId()));
        accessoryMaterialInfo.setMaterialType(materialModelDto.getModelType());
        accessoryMaterialInfo.setMaterialName(materialModelDto.getName());
        accessoryMaterialInfo.setMaterialCode(materialModelDto.getCodes());
        accessoryMaterialInfo.setWarning(materialModelDto.getWarning());
        accessoryMaterialInfo.setWarnTime(materialModelDto.getWarnTime());
        accessoryMaterialInfo.setUseLife(materialModelDto.getUseLife());
        //TODO 寿命类型字段，先默认为0，标识按照炉次
        accessoryMaterialInfo.setLifeType(0);
        accessoryMaterialInfo.setSupplier(materialModelDto.getSupplier());
        accessoryMaterialInfo.setSpecification(materialModelDto.getSpecification());
        accessoryMaterialInfo.setXh("");
        accessoryMaterialInfo.setTh("");
        accessoryMaterialInfo.setUnit(materialModelDto.getUnitName());
        return accessoryMaterialInfo;
    }
    private AccessoryMaterialInfo setAccessoryMaterialInfos(AccessoryMaterialDto materialModelDto) {
        AccessoryMaterialInfo accessoryMaterialInfo = new AccessoryMaterialInfo();
        accessoryMaterialInfo.setMaterialId(Long.valueOf(materialModelDto.getMaterialModelId()));
        accessoryMaterialInfo.setMaterialType(materialModelDto.getModelType());
        accessoryMaterialInfo.setMaterialName(materialModelDto.getName());
        accessoryMaterialInfo.setMaterialCode(materialModelDto.getCodes());
        accessoryMaterialInfo.setWarning(materialModelDto.getWarning());
        accessoryMaterialInfo.setWarnTime(materialModelDto.getWarnTime());
        accessoryMaterialInfo.setUseLife(materialModelDto.getUseLife());
        //TODO 寿命类型字段，先默认为0，标识按照炉次
        accessoryMaterialInfo.setLifeType(0);
        accessoryMaterialInfo.setSupplier(materialModelDto.getSupplier());
        accessoryMaterialInfo.setSpecification(materialModelDto.getSpecification());
        accessoryMaterialInfo.setXh("");
        accessoryMaterialInfo.setTh("");
        accessoryMaterialInfo.setUnit(materialModelDto.getUnitName());
        return accessoryMaterialInfo;
    }
    private WarehouseInputBillBo newInputBill(Accessory accessory, String reason) {
        WarehouseInputBillBo inputBill = new WarehouseInputBillBo();
        inputBill.setType("辅料退库");
        inputBill.setRemark(reason);
        //入库物料明细
        List<WarehouseInputBillDetailBo> inputBillDetails = new ArrayList<>();
        WarehouseInputBillDetailBo dto = new WarehouseInputBillDetailBo();
//        Result<WarehouseMaterialDto> byStoreMaterialCode = storeFeignClients.getByStoreMaterialCode(accessory.getMaterialCode());
//        if(byStoreMaterialCode.getCode().equals(200)){
//            if(!ObjectUtils.isEmpty(byStoreMaterialCode.getData().getDefaultLocationId())){
//                dto.setWarehouseId(byStoreMaterialCode.getData().getDefaultLocationId());
//            }
//            if(!ObjectUtils.isEmpty(byStoreMaterialCode.getData().getDefaultLocation())){
//                dto.setWarehouseName(byStoreMaterialCode.getData().getDefaultLocation());
//            }
//        }
        //下机之后 申请入库单入库库位设置为虚拟库位 防止操作失误
        Result<DictionaryItemDto> byThemeCodeAndItemName = ybFeignClients.findByThemeCodeAndItemName("accessory_down_defaultLocation", "热场下机默认库位");
        if(byThemeCodeAndItemName.getCode().equals(200)){
            if(!ObjectUtils.isEmpty(byThemeCodeAndItemName.getData())){
                dto.setWarehouseId(Long.valueOf(byThemeCodeAndItemName.getData().getValue()));
                dto.setWarehouseName(byThemeCodeAndItemName.getData().getExtendValue());
            }
        }
        //组装物料明细数据
        dto.setUniqueCode(accessory.getUniqueCode());
        dto.setBatchNo(accessory.getBatchCode());
        dto.setCount(new BigDecimal(accessory.getNumber()));
        //TODO 字段需要与物料主数据对齐
        AccessoryMaterialInfo materialModel = this.getByMaterialCodes(accessory.getMaterialCode());
        Assert.notNull(materialModel, "【" + accessory.getMaterialCode() + "】物料主数据不存在，请检查数据！");
        dto.setMaterialModelId(materialModel.getMaterialId());
        dto.setMaterialModelCode(materialModel.getMaterialCode());
        dto.setMaterialModelName(materialModel.getMaterialName());
        dto.setMaterialTypeName(materialModel.getMaterialType());
//        dto.setMaterialCategoryName(materialModel.getMaterialCategoryName());
        dto.setMaterialTh(materialModel.getTh());
        dto.setSupplier(materialModel.getSupplier());
        dto.setUnitName(materialModel.getUnit());
        dto.setSpecification(materialModel.getSpecification());
        inputBillDetails.add(dto);
        inputBill.setInputBillDetails(inputBillDetails);
        return inputBill;
    }

    /**
     * 退料判定单独处理逻辑
     * @param accessory
     * @param reason
     * @return
     */
    private WarehouseInputBillBo newEchnologyInputBillBo(Accessory accessory, String reason,DeterminationEchnology determinationEchnology) {
        WarehouseInputBillBo inputBill = new WarehouseInputBillBo();
        inputBill.setType("辅料退库");
        inputBill.setRemark(reason);
        //入库物料明细
        List<WarehouseInputBillDetailBo> inputBillDetails = new ArrayList<>();
        WarehouseInputBillDetailBo dto = new WarehouseInputBillDetailBo();
        //下机之后 申请入库单入库库位
        if(determinationEchnology.getResultDetermination().equals("返修")){
            Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode("FX22B");
            if(warehouseModelDtoResult.getCode().equals(200)){
                WarehouseModelDto data = warehouseModelDtoResult.getData();
                dto.setWarehouseName(data.getName());
                dto.setWarehouseId(data.getId());
            }

        }
        if(determinationEchnology.getResultDetermination().equals("报废")){
            Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode("BF22B");
            if(warehouseModelDtoResult.getCode().equals(200)){
                WarehouseModelDto data = warehouseModelDtoResult.getData();
                dto.setWarehouseName(data.getName());
                dto.setWarehouseId(data.getId());
            }

        }
        if(determinationEchnology.getResultDetermination().equals("煅烧可用")){
            Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode("P22B");
            if(warehouseModelDtoResult.getCode().equals(200)){
                WarehouseModelDto data = warehouseModelDtoResult.getData();
                dto.setWarehouseName(data.getName());
                dto.setWarehouseId(data.getId());
            }
        }
        //组装物料明细数据
        dto.setUniqueCode(accessory.getUniqueCode());
        dto.setBatchNo(accessory.getBatchCode());
        dto.setCount(new BigDecimal(accessory.getNumber()));
        //TODO 字段需要与物料主数据对齐
        AccessoryMaterialInfo materialModel = this.getByMaterialCodes(accessory.getMaterialCode());
        Assert.notNull(materialModel, "【" + accessory.getMaterialCode() + "】物料主数据不存在，请检查数据！");
        dto.setMaterialModelId(materialModel.getMaterialId());
        dto.setMaterialModelCode(materialModel.getMaterialCode());
        dto.setMaterialModelName(materialModel.getMaterialName());
        dto.setMaterialTypeName(materialModel.getMaterialType());
//        dto.setMaterialCategoryName(materialModel.getMaterialCategoryName());
        dto.setMaterialTh(materialModel.getTh());
        dto.setSupplier(materialModel.getSupplier());
        dto.setUnitName(materialModel.getUnit());
        dto.setSpecification(materialModel.getSpecification());
        inputBillDetails.add(dto);
        inputBill.setInputBillDetails(inputBillDetails);
        return inputBill;
    }
    private WarehouseInputBillBo newQualityInputBillBo(Accessory accessory, String reason, DeterminationQuality determinationQuality) {
        WarehouseInputBillBo inputBill = new WarehouseInputBillBo();
        inputBill.setType("辅料退库");
        inputBill.setRemark(reason);
        //入库物料明细
        List<WarehouseInputBillDetailBo> inputBillDetails = new ArrayList<>();
        WarehouseInputBillDetailBo dto = new WarehouseInputBillDetailBo();
        //下机之后 申请入库单入库库位
        if(determinationQuality.getResultDetermination().equals("返修")){
            Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode("FX22B");
            if(warehouseModelDtoResult.getCode().equals(200)){
                WarehouseModelDto data = warehouseModelDtoResult.getData();
                dto.setWarehouseName(data.getName());
                dto.setWarehouseId(data.getId());
            }

        }
        if(determinationQuality.getResultDetermination().equals("报废")){
            Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode("BF22B");
            if(warehouseModelDtoResult.getCode().equals(200)){
                WarehouseModelDto data = warehouseModelDtoResult.getData();
                dto.setWarehouseName(data.getName());
                dto.setWarehouseId(data.getId());
            }

        }
        if(determinationQuality.getResultDetermination().equals("煅烧可用")){
            Result<WarehouseModelDto> warehouseModelDtoResult = storeFeignClients.getCode("P22B");
            if(warehouseModelDtoResult.getCode().equals(200)){
                WarehouseModelDto data = warehouseModelDtoResult.getData();
                dto.setWarehouseName(data.getName());
                dto.setWarehouseId(data.getId());
            }
        }
        //组装物料明细数据
        dto.setUniqueCode(accessory.getUniqueCode());
        dto.setBatchNo(accessory.getBatchCode());
        dto.setCount(new BigDecimal(accessory.getNumber()));
        //TODO 字段需要与物料主数据对齐
        AccessoryMaterialInfo materialModel = this.getByMaterialCodes(accessory.getMaterialCode());
        Assert.notNull(materialModel, "【" + accessory.getMaterialCode() + "】物料主数据不存在，请检查数据！");
        dto.setMaterialModelId(materialModel.getMaterialId());
        dto.setMaterialModelCode(materialModel.getMaterialCode());
        dto.setMaterialModelName(materialModel.getMaterialName());
        dto.setMaterialTypeName(materialModel.getMaterialType());
//        dto.setMaterialCategoryName(materialModel.getMaterialCategoryName());
        dto.setMaterialTh(materialModel.getTh());
        dto.setSupplier(materialModel.getSupplier());
        dto.setUnitName(materialModel.getUnit());
        dto.setSpecification(materialModel.getSpecification());
        inputBillDetails.add(dto);
        inputBill.setInputBillDetails(inputBillDetails);
        return inputBill;
    }
    private WarehouseOutputBillBo newOutputBill(ApplyAccessoryParam applyAccessoryParam) {
        WarehouseOutputBillBo outputBill = new WarehouseOutputBillBo();
        outputBill.setType("辅料出库");
        outputBill.setDestination(applyAccessoryParam.getEquipmentCode());
        outputBill.setRemark(applyAccessoryParam.getReason());
        List<WarehouseOutputBillDetailBo> outputBillDetails = new ArrayList<>();
        WarehouseOutputBillDetailBo dto = new WarehouseOutputBillDetailBo();
        //组装物料明细数据，出库时，出库请求方只需要传递物料号和出库数量即可，具体的出库逻辑由真正出库时处理
        String materialCode = applyAccessoryParam.getMaterialCode();
        //TODO 字段需要与物料主数据对齐
        AccessoryMaterialInfo materialModel = this.getByMaterialCodes(materialCode);
        Assert.notNull(materialModel, "【" + materialCode + "】物料主数据不存在，请检查数据！");
        dto.setMaterialModelId(materialModel.getMaterialId());
        dto.setMaterialModelCode(materialCode);
        dto.setMaterialModelName(materialModel.getMaterialName());
        dto.setMaterialTypeName(materialModel.getMaterialType());
//        dto.setMaterialCategoryName(materialModel.getMaterialCategoryName());
        dto.setMaterialTh(materialModel.getTh());
        dto.setSupplier(materialModel.getSupplier());
        dto.setUnitName(materialModel.getUnit());
        dto.setSpecification(materialModel.getSpecification());
        dto.setRequireCount(new BigDecimal(applyAccessoryParam.getNumber()));
        dto.setDestination(applyAccessoryParam.getEquipmentCode());
        outputBillDetails.add(dto);
        outputBill.setOutputBillDetails(outputBillDetails);
        return outputBill;
    }
}
