package com.sw.mes.outside.controller;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.enumvalue.EnumValuesEap;
import com.sw.mes.outside.dto.*;
import com.sw.mes.outside.service.EapService;
import com.sw.mes.redis.server.RedisUtils;
import com.sw.mes.yb.production.dto.LongCrystalVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("/eap")
@Api(description = "EAP->MES")
public class EapController {
    @Autowired
    private EapService eapService;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 开炉信号延时发送装料信号
     *
     * @param sendEapSignalDto
     * @param bindingResult
     * @return
     */
    @PostMapping("/sendEapSignal")
    @ApiOperation(value = "人工补发基础信号上传")
    public Result sendEapSignal(@RequestBody SendEapSignalDto sendEapSignalDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.PC.getKey());
    }


    /**
     * 开炉信号延时发送装料信号
     *
     * @param longCrystalVO
     * @return
     */
    @PostMapping("/updateLastLongCrstalWeight")
    @ApiOperation(value = "更新最后一次长晶棒重量")
    public Result updateLastLongCrstalWeight(@RequestBody LongCrystalVO longCrystalVO) {
        return eapService.updateLastLongCrstalWeight(longCrystalVO);
    }

    /**
     * 设备上传信号
     *
     * @param sendDeviceEapSignalDto
     * @param bindingResult
     * @return
     */
    @PostMapping("/sendDeviceEapSignal")
    @ApiOperation(value = "设备基础信号上传")
    public Result sendDeviceEapSignal(@RequestBody SendDeviceEapSignalDto sendDeviceEapSignalDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SendEapSignalDto sendEapSignalDto = new SendEapSignalDto();
        sendEapSignalDto.setEquipmentCode(sendDeviceEapSignalDto.getDeviceCode());

        Object windUpObj = sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.WIND_UP);
        CrystalInfoDto crystalInfoDto = new CrystalInfoDto();
        //抽空时间
        if(sendDeviceEapSignalDto.getStartCollectionData().containsKey(SendDeviceEapSignalDto.ENTRY_EVACUATION_TIME)){
            String time = sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.ENTRY_EVACUATION_TIME).toString();
            try {
                if(null != time){
                    Date parse = DateUtil.longSdf.parse(time);
                    crystalInfoDto.setRodProductionTime(parse);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        //取熔料时间
        if(sendDeviceEapSignalDto.getStartCollectionData().containsKey(SendDeviceEapSignalDto.MELTING_TIME)){
            String time = sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MELTING_TIME).toString();
            try {
                if(null != time){
                    Date parse = DateUtil.longSdf.parse(time);
                    crystalInfoDto.setMeltingTime(parse);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        switch (sendDeviceEapSignalDto.getTaskCode()) {
            //开炉-信号
            case SendDeviceEapSignalDto.OPEN_FURNACE:
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.开炉.getKey());
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            //抽真空-信号
            case SendDeviceEapSignalDto.VACUUM_PUMPING:
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.抽真空.getKey());
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            case SendDeviceEapSignalDto.MOLTEN_MATERIAL:
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.熔料.getKey());
                crystalInfoDto.setResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.RESIDUAL_WEIGHT)));
                sendEapSignalDto.setCrystalInfoDto(crystalInfoDto);
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            //取段结晶-信号
            case SendDeviceEapSignalDto.CLOSE_METHOD:
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.取段结晶.getKey());
                crystalInfoDto.setLength(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_LENGTH)));
                crystalInfoDto.setWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_WEIGHT)));
                crystalInfoDto.setResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.RESIDUAL_WEIGHT)));
                crystalInfoDto.setCrystalIntroductionResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_INTRODUCTION_RESIDUAL_WEIGHT)));
                crystalInfoDto.setWindUp(windUpObj == null ? "N" : windUpObj.toString());
                crystalInfoDto.setHeadLen(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.HEAD_LEN)));
                crystalInfoDto.setTailLen(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.TAIL_LEN)));
                crystalInfoDto.setMaxDiam(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MAX_DIAM)));
                crystalInfoDto.setMinDiam(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MIN_DIAM)));
                crystalInfoDto.setIsometricLength(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_LENGTH)));
                crystalInfoDto.setCrystalCrucibleRotation(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_CRUCIBLE_ROTATION)));
                sendEapSignalDto.setCrystalInfoDto(crystalInfoDto);
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            //取段稳温-信号
            case SendDeviceEapSignalDto.SEGMENTED_STABLE_TEMPERATURE:
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.取段稳温.getKey());
                crystalInfoDto.setLength(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_LENGTH)));
                crystalInfoDto.setWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_WEIGHT)));
                crystalInfoDto.setResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.RESIDUAL_WEIGHT)));
                crystalInfoDto.setCrystalIntroductionResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_INTRODUCTION_RESIDUAL_WEIGHT)));
                crystalInfoDto.setWindUp(windUpObj == null ? "N" : windUpObj.toString());
                crystalInfoDto.setHeadLen(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.HEAD_LEN)));
                crystalInfoDto.setTailLen(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.TAIL_LEN)));
                crystalInfoDto.setMaxDiam(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MAX_DIAM)));
                crystalInfoDto.setMinDiam(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MIN_DIAM)));
                crystalInfoDto.setIsometricLength(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_LENGTH)));
                crystalInfoDto.setCrystalCrucibleRotation(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_CRUCIBLE_ROTATION)));
                sendEapSignalDto.setCrystalInfoDto(crystalInfoDto);
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            //停炉-信号
            case SendDeviceEapSignalDto.SHUTDOWN_FURNACE:
//                redisUtils.hmSet("all_device_shutdown_time", sendEapSignalDto.getEquipmentCode(), DateUtil.formatDate(new Date(), DateUtil.longFormat));
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.停炉.getKey());
                crystalInfoDto.setLength(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_LENGTH)));
                crystalInfoDto.setWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_WEIGHT)));
                crystalInfoDto.setResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.RESIDUAL_WEIGHT)));
                crystalInfoDto.setCrystalIntroductionResidualWeight(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_INTRODUCTION_RESIDUAL_WEIGHT)));
                crystalInfoDto.setWindUp(windUpObj == null ? "N" : windUpObj.toString());
                crystalInfoDto.setHeadLen(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.HEAD_LEN)));
                crystalInfoDto.setTailLen(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.TAIL_LEN)));
                crystalInfoDto.setMaxDiam(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MAX_DIAM)));
                crystalInfoDto.setMinDiam(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.MIN_DIAM)));
                crystalInfoDto.setIsometricLength(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_LENGTH)));
                crystalInfoDto.setCrystalCrucibleRotation(NumberUtil.Object2BigDecimal(sendDeviceEapSignalDto.getStartCollectionData().get(SendDeviceEapSignalDto.CRYSTAL_CRUCIBLE_ROTATION)));
                sendEapSignalDto.setCrystalInfoDto(crystalInfoDto);
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            //预装料
            case SendDeviceEapSignalDto.PREPARE_INPUT_MATERIAL:
                sendEapSignalDto.setSignal(EnumValuesEap.EapSignalType.预装料.getKey());
                return eapService.sendEapSignal(sendEapSignalDto, EnumValuesEap.SignalSource.EAP.getKey());
            default:
                throw new BusinessException("该信号没有数据处理方法");
        }
    }

    /**
     * 接收EAP上传拉晶情况数据信号
     */
    @PostMapping("/crystalpulling/receive")
    @ApiOperation(value = "接收EAP上传拉晶情况数据信号")
    public Result receive(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.crystalpullingHandler(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success();
    }

    /**
     * 接收EAP上传拉晶情况实时状态数据
     */
    @PostMapping("/crystalpulling/realTime")
    @ApiOperation(value = "接收EAP上传拉晶情况数据信号")
    public Result crystalpullingRealTime(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.crystalpullingRealTime(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success();
    }

    /**
     * 接收EAP上传拉晶情况数据信号
     */
    @PostMapping("/process/receive")
    @ApiOperation(value = "接收EAP上传拉晶情况数据信号1")
    public Result processReceive(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.processReceive(dto);
        } catch (Exception e) {
            log.error("接收EAP上传拉晶情况数据信号1", e);
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success();
    }

    /**
     * 接收EAP上传工时数据信号
     */
    @PostMapping("/workingHours/receive")
    @ApiOperation(value = "接收EAP上传工时信号")
    public Result workingHours(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.workingHours(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }


    /**
     * 接收EAP上传工艺工序
     */
    @PostMapping("/workingStep/receive")
    @ApiOperation(value = "接收EAP上传工艺工序信号")
    public Result workingStep(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.workingStep(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    /**
     * 拆清开始
     */
    @PostMapping("/dismantlingStart1")
    @ApiOperation(value = "接收IPC上传拆清开始信号")
    public Result dismantlingStart1(@RequestBody DismantlingDto dismantlingDto) {
        try {
            eapService.dismantlingStart(dismantlingDto);
        } catch (Exception e) {
            log.error("拆清结束开始",e);
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success();
    }
    /**
     * 接收EAP上传12小时未等径
     */
    @PostMapping("/delayed")
    @ApiOperation(value = "12小时未等径")
    public Result delayed(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.delayed(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    /**
     * 接收EAP扩肩成活率
     */
    @PostMapping("/shoulder/survivalRate")
    @ApiOperation(value = "接收EAP扩肩成活率")
    public Result shoulderSurvivalRate(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.shoulderSurvivalRate(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }


    /**
     * 接收EAP引晶成活率
     */
    @PostMapping("/shoulder/seedingRate")
    @ApiOperation(value = "接收EAP引晶成活率")
    public Result seedingRate(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.shoulderSeedingRate(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }


    /**
     * 接收EAP扩断基础表
     */
    @PostMapping("/expansion/base")
    @ApiOperation(value = "接收EAP扩断基础表")
    public Result expansion(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.expansionBase(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    /**
     * 接收EAP断苞基础表
     */
    @PostMapping("/brokenBract/base")
    @ApiOperation(value = "接收EAP断苞基础表")
    public Result brokenBract(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.brokenBractBase(dto);
        } catch (Exception e) {
            return ResultGenerator.fail("处理发生异常：" + e.getMessage());
        }
        return ResultGenerator.success();
    }

    /**
     * 接收EAP成晶基础表
     */
    @PostMapping("/successCrystal/base")
    @ApiOperation(value = "接收EAP成晶基础表")
    public Result successCrystal(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.successCrystalBase(dto);
        } catch (Exception e) {
            return ResultGenerator.fail("处理发生异常：" + e.getMessage());
        }
        return ResultGenerator.success();
    }

    /**
     * 接收EAP引断基础表
     */
    @PostMapping("/crystalBroken/base")
    @ApiOperation(value = "接收EAP引断基础表")
    public Result crystalBroken(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.crystalBrokenBase(dto);
        } catch (Exception e) {
            return ResultGenerator.fail("处理发生异常：" + e.getMessage());
        }
        return ResultGenerator.success();
    }


    /**
     * 接收EAP上传备料信号
     */
    @PostMapping("/crystalpulling/prepare")
    @ApiOperation(value = "接收EAP上传备料信号")
    public Result prepare(@RequestBody ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.materialPrepareSignal(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success();
    }



    /**
     * ipc获取物料操作列表
     */
    @PostMapping("/materialOperationList")
    @ApiOperation(value = "ipc物料操作获取任务")
    public Result<List<MaterialTaskDto>> materialOperationList(@RequestBody @Valid @ApiParam(value = "Dto对象")MaterialOperationDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        List<MaterialTaskDto> taskListDto;
        try {
            taskListDto = eapService.materialOperationList(dto);
        } catch (Exception e) {
            log.error(ExceptionUtil.stacktraceToString(e));
            return ResultGenerator.fail(e.getMessage());
        }

        return ResultGenerator.success(taskListDto);
    }

    /**
     * ipc物料任务操作
     */
    @PostMapping("/materialOperationAction")
    @ApiOperation(value = "ipc物料任务操作")
    public Result materialOperationAction(@RequestBody @Valid @ApiParam(value = "Dto对象")MaterialOperationActionDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        try {
             eapService.materialOperationAction(dto);
        } catch (Exception e) {
            log.error(ExceptionUtil.stacktraceToString(e));
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    @PostMapping("/manualShutdown")
    @ApiOperation(value = "手动停炉")
    public Result manualShutdown(@RequestParam("equipmentCode") @NotBlank(message = "设备号不能为空") String equipmentCode, @RequestParam(value = "abnormalCause") String abnormalCause) {
        eapService.manualShutdown(equipmentCode,abnormalCause);
        return ResultGenerator.success();
    }

    /**
     * 接收EAP上传余料数据信号
     */
    @Jinko(author = "yyl", value = "接收EAP上传余料数据信号")
    @PostMapping("/surplus/receive")
    @ApiOperation(value = "接收EAP上传余料数据信号")
    public Result surplusReceive(@RequestBody @Valid ToMESData dto, BindingResult bindingResult) {
        try {
            eapService.surplusReceive(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }


    /**
     * 接收EAP上传事故异常数据信号
     */
    @PostMapping("/accidentAnomaly")
    @ApiOperation(value = "事故异常")
    public Result accidentAnomaly(@RequestBody ToMESData dto) {
        try {
            eapService.accidentAnomaly(dto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

}
