package com.sw.mes.yb.mcs.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.enums.SectionIndexRangeEnum;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.yb.fls.dto.BindingDto;
import com.sw.mes.yb.fls.dto.BindingInfoDto;
import com.sw.mes.yb.fls.dto.SampleTypeDto;
import com.sw.mes.yb.fls.dto.TrayAutoUnBinding;
import com.sw.mes.yb.fls.service.FlsToMesService;
import com.sw.mes.yb.mcs.dto.*;
import com.sw.mes.yb.mcs.dto.fillingMaterial.McsMoPrepareWorkReportingDto;
import com.sw.mes.yb.mcs.dto.fillingMaterial.McsMoWorkReportingDto;
import com.sw.mes.yb.mcs.entity.CodingRecord;
import com.sw.mes.yb.mcs.service.CodingRecordService;
import com.sw.mes.yb.mcs.service.YbMcsToMesService;
import com.sw.mes.yb.mcs.vo.HiddenCrackDetectionVo;
import com.sw.mes.yb.pad.service.ProductionPaintingLineService;
import com.sw.mes.yb.pc.service.SideSkinCodingRuleService;
import com.sw.mes.yb.production.entity.AgainTaskDetail;
import com.sw.mes.yb.production.entity.AgainTaskPrepare.AgainTaskPrepare;
import com.sw.mes.yb.production.entity.LoadingTask;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.service.*;
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.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: GaoXinJian
 * @Date: 2022-01-13 13:23
 */
@RestController
@RequestMapping("/mcsToMesController")
@Slf4j
@Api(description = "mcs与mes通信接口")
public class McsToMesController {

    @Autowired
    YbMcsToMesService mcsToMesService;
    @Autowired
    FlsToMesService flsToMesService;
    @Autowired
    private SideSkinCodingRuleService sideSkinCodingRuleService;

    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    private CodingRecordService codingRecordService;

    @Autowired
    private YbInspectDataService ybInspectDataService;

    @Autowired
    private AgainTaskService againTaskService;
    @Autowired
    private LoadingTaskService loadingTaskService;

    @Autowired
    private AgainTaskDetailService againTaskDetailService;

    @Autowired
    private AgainTaskPrepareService againTaskPrepareService;

    @Autowired
    private ProductionPaintingLineService productionPaintingLineService;

    @ApiOperation(value = "晶段检验过点上传接口")
    @PostMapping("/segmentCheckInfo")
    public Result segmentCheckInfo(@RequestBody SegmentCheckInfoDto segmentCheckInfoDto, HttpServletRequest request, HttpServletResponse response) {
        mcsToMesService.segmentCheckInfo(segmentCheckInfoDto);
//        log.info(segmentCheckInfoDto.toString());

        return ResultGenerator.success();
    }

    @ApiOperation(value = "圆棒检测结果上传")
    @PostMapping("/ybCheckResult")
    public Result ybCheckResult(@RequestBody String paramJson) {
        YbCheckResultDto ybCheckResultDto = JSON.parseObject(paramJson, YbCheckResultDto.class);

        log.info("圆棒检测结果上传:{}", paramJson);
        try {
            return ybInspectDataService.ybCheckResult(ybCheckResultDto);
        } catch (Exception e) {
            log.error("error_in_mcs_ybCheckResult", e);
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "MCS圆棒检测结果上传测试")
    @PostMapping("/reciveYbCheckResult")
    public Result reciveYbCheckResult(@RequestBody String text) {
        try {
            YbCheckResultDto ybCheckResultDto = JSONObject.parseObject(text, YbCheckResultDto.class);
            return mcsToMesService.ybCheckResult(ybCheckResultDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());

        }
    }

    @ApiOperation(value = "圆棒打码信息请求")
    @PostMapping("/skinCodingInfo")
    public Result skinCodingInfo(@RequestBody SkinCodingInfoDto skinCodingInfoDto) {

        String productTypeResult = " ";
        String sideLengthRangeResult = " ";

        if (skinCodingInfoDto.getSegmentNo() == null) {
            return ResultGenerator.fail("晶棒编号不能为空!");
        }
        String segmentNo = skinCodingInfoDto.getSegmentNo();
        try {
            CodingRecord codingRecord = new CodingRecord();
            codingRecord.setSectionNo(segmentNo);
            codingRecord.setCreateDate(new Date());
            codingRecordService.saveOrUpdate(codingRecord);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int len = segmentNo.length();

        String crystalNo = segmentNo.substring(0, 16);
//        String fromMark = segmentNo.substring(SectionIndexRangeEnum.基地追溯产品类型.getBeginIndex(), SectionIndexRangeEnum.基地追溯产品类型.getEndIndex());
//        if (fromMark.matches("[A-Z]+")) {
//            crystalNo = segmentNo.substring(SectionIndexRangeEnum.毛棒范围.getBeginIndex(), SectionIndexRangeEnum.毛棒范围.getEndIndex());
//        }
        //查询长晶棒产出表
        LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(crystalNo);
        if (byCrystalNo == null) {
            return ResultGenerator.fail("晶棒编号不存在!");
        }

//        List<DictionaryItem> toMCSProductSpec = dictionaryItemService.findByThemeValueAndEnable("ToMCSProductSpecNew", true);
//        Map<String, DictionaryItem> specMap = toMCSProductSpec.stream().collect(Collectors.toMap(DictionaryItem::getName, Function.identity(), (t1, t2) -> t1));
//        String productType = byCrystalNo.getSpecs();
//        if (specMap.containsKey(productType)) {
//
//            productTypeResult = specMap.get(productType).getValue();
////            byCrystalNo.setProductType(specMap.get(productType).getValue());
//        }

        //边长范围
//        List<DictionaryItem> multipleSideLogics = dictionaryItemService.findByThemeValueAndEnable("multipleSideLogic", true);
//        if (null != multipleSideLogics) {
//            Map<String, DictionaryItem> multipleSideLogicMap = multipleSideLogics.stream().collect(Collectors.toMap(DictionaryItem::getName, Function.identity(), (t1, t2) -> t1));
//            String sideLengthRange = byCrystalNo.getSideLengthRange();
//            if (multipleSideLogicMap.containsKey(sideLengthRange)) {
////                byCrystalNo.setSideLengthRange(multipleSideLogicMap.get(sideLengthRange).getExtendValue1());
//                sideLengthRangeResult = multipleSideLogicMap.get(sideLengthRange).getExtendValue1();
//            }
//        }
//
//        JSONObject jsonObject = new JSONObject();
//        //增加 是否打打码、规格、前边皮、后边皮
//        //String skinCoding = sideSkinCodingRule == null ? null : sideSkinCodingRule.getCodeMark();
//        //前边皮编码
//        jsonObject.put("frontSkinCoding", "");
//        //后边皮编码
//        jsonObject.put("backSkinCoding", "");
//        //规格：晶段编号截取4-6
//
////        jsonObject.put("productType", productTypeResult);
//        String productGrade = byCrystalNo.getProductGrade();
//        jsonObject.put("level", StringUtils.equals(byCrystalNo.getProductGrade(), "-") ? "A1" : byCrystalNo.getProductGrade());
//        if (productGrade.contains("A1")) {
//            jsonObject.put("level", "A1");
//        }
//        YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(segmentNo);
//        List<CodingRecord> codingRecordBySectionNo = codingRecordService.getCodingRecordBySectionNo(segmentNo);
//        if (null != bySectionNo && null != bySectionNo.getProductLevel() && null != codingRecordBySectionNo && codingRecordBySectionNo.size() > 1) {
//            if (bySectionNo.getProductLevel().contains("A1")) {
//                jsonObject.put("level", "A1");
//            }
//            if (bySectionNo.getProductLevel().contains("A2")) {
//                jsonObject.put("level", "A2");
//            }
//        }
//        //是否打码：有规则打码，无规则不打码
//        jsonObject.put("isCoding", true);
//        // 拼接规则：掺杂剂-规格-等级
//        jsonObject.put("productGrade", byCrystalNo.getDopant() + "-" + jsonObject.getString("productType") + "-" + jsonObject.getString("level") + "-" + sideLengthRangeResult);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "mcs托盘自动解绑接口")
    @PostMapping("/trayAutoUnBinding")
    public Result trayAutoUnBinding(@RequestBody TrayAutoUnBinding trayAutoUnBinding) {

        flsToMesService.trayAutoUnBinding(trayAutoUnBinding, "mcs");
        return ResultGenerator.success();
    }

    @ApiOperation(value = "画线数据请求接口")
    @PostMapping(value = "getPaintingLineInfo")
    public Result getPaintingLineInfo(@ApiParam(value = "送验车编号") @RequestParam String code) {
        try {
            return flsToMesService.getPaintingLineInfo(code);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.message(500, "系统异常", null);
        }

    }


    @ApiOperation(value = "画线数据手动请求接口")
    @PostMapping(value = "getPaintingLineInfoManual")
    public Result getPaintingLineInfoManual(@ApiParam(value = "毛棒单晶编号") @RequestParam String crystalNo) {
        try {
            return flsToMesService.getPaintingLineInfoManual(crystalNo);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.message(500, "系统异常", null);
        }

    }

    @ApiOperation(value = "上料解绑载具车信息（截断机上料：晶棒与载具车解绑）")
    @PostMapping(value = "/unbindInfo")
    public Result unbindInfo(@RequestBody UnbindInfoDto unbindInfoDto) {
        try {
            Result result = mcsToMesService.unbindInfo(unbindInfoDto);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.message(500, e.getMessage(), null);
        }
    }

    @ApiOperation(value = "绑定接收信息上传(截断机下料：晶段与托盘绑定)")
    @PostMapping(value = "/bindingInfo")
    public Result bindingInfo(@RequestBody BindingInfoDto bindingInfoDto) {
        try {
            return flsToMesService.bindingInfo(bindingInfoDto);
        } catch (Exception e) {
            return ResultGenerator.message(500, "系统异常:" + e.getMessage(), null);
        }
    }

    @ApiOperation(value = "绑定接收信息校验(截断机下料：晶段与托盘绑定)")
    @PostMapping(value = "/bindingInfoVerify")
    public Result bindingInfoVerify(@RequestBody BindingInfoDto bindingInfoDto) {
        try {
            return flsToMesService.bindingInfoVerify(bindingInfoDto);
        } catch (Exception e) {
            return ResultGenerator.message(500, "系统异常:" + e.getMessage(), null);
        }
    }

    @ApiOperation(value = "样片检测数据上传接口")
    @PostMapping(value = "sampleInfo")
    public Result sampleInfo(@RequestBody SampleCheckInfoDto sampleCheckInfoDto) {
        Result result = mcsToMesService.sampleInfo(sampleCheckInfoDto);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "样片类别请求接口")
    @GetMapping(value = "getSampleType")
    public Result getSampleType(@ApiParam(value = "托盘号") @RequestParam String code) {
        SampleTypeDto sampleTypeDto = new SampleTypeDto();
        return ResultGenerator.success(sampleTypeDto);
    }

    @ApiOperation(value = "头尾料、回收料类别请求接口")
    @PostMapping(value = "/getHeadTailMaterialType")
    public Result<HeadTailMaterialTypeDto> getHeadTailMaterialType(@ApiParam(value = "回收料编号") @RequestParam String code) {
        try {
            HeadTailMaterialTypeDto headTailMaterialType = mcsToMesService.getHeadTailMaterialType(code);
            if (headTailMaterialType != null) {
                return ResultGenerator.success(headTailMaterialType);
            } else {
                return ResultGenerator.fail("未匹配到头尾料类别");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail("匹配头尾料类别异常" + e.getMessage());
        }
    }

    @ApiOperation(value = "头尾料、回收料绑定接口")
    @PostMapping(value = "/biddingRecycledMaterial")
    public Result biddingRecycledMaterial(@RequestBody RecycledBindingInfoDto recycledBindingInfoDto) {
        try {
            Result result = mcsToMesService.biddingRecycledMaterial(recycledBindingInfoDto);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail("头尾料、回收料绑定解绑异常！：" + e.getMessage());
        }
    }

    @ApiOperation(value = "头尾料回收上传接口")
    @PostMapping(value = "/headTailMaterialInfo")
    public Result headTailMaterialInfo(@RequestBody HeadTailMaterialInfoDto headTailMaterialInfoDto) {
        mcsToMesService.headTailMaterialInfo(headTailMaterialInfoDto);
        return ResultGenerator.success();
    }


    @ApiOperation(value = "获取晶段站点信息接口")
    @PostMapping(value = "/sectionWipStorageInfo")
    public Result sectionWipStorageInfo(@RequestBody SkinCodingInfoDto skinCodingInfoDto) {
        return mcsToMesService.sectionWipStorageInfo(skinCodingInfoDto);
    }


    @ApiOperation(value = "操作晶棒过站（圆棒检验待进站->圆棒检验进站）")
    @PostMapping(value = "/ybInspectStationIn")
    public Result ybInspectStationIn(@RequestBody SkinCodingInfoDto skinCodingInfoDto) {
        return mcsToMesService.ybInspectStationIn(skinCodingInfoDto);
    }


    /**
     * 用于自动模式截断下料绑定
     * mcs调mes校验，传入晶编，来校验站点，晶段必须为圆棒检验待进站状态，再校验新表是否已存在该晶编，存在则告警，不存在则录入
     *
     * @param pdaBingDto
     * @return
     */
    @ApiOperation(value = "截断自动下料校验接口")
    @PostMapping("/checkForAutoBind")
    public Result checkForAutoBind(@RequestBody PdaBingDto pdaBingDto) {

        return mcsToMesService.checkForAutoBind(pdaBingDto);
    }

    @ApiOperation(value = "msc圆棒订单匹配接口")
    @PostMapping("/squareOrder")
    public Result squareOrder(@RequestBody SquareOrderMesDto squareOrderDto, HttpServletRequest request) {
        try {
            return mcsToMesService.squareOrder(squareOrderDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.message(400, e.getMessage(), null);
        }
    }

    @ApiOperation(value = "冷却缓存库自动位错设备数据")
    @PostMapping("/staggerPositionInfo")
    public Result staggerPositionInfo(@RequestBody String param) {
        try {
            DislocationInfoDto dislocationDto = Optional.ofNullable(param).map(o -> o.trim()).filter(o -> o.startsWith("{")).filter(o -> o.endsWith("}"))
                    .map(o -> JSONObject.parseObject(o)).map(o -> o.toJavaObject(DislocationInfoDto.class)).orElse(null);
            return mcsToMesService.staggerPositionInfo(dislocationDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.message(400, e.getMessage(), null);
        }
    }

    @ApiOperation(value = "查询晶棒信息")
    @PostMapping("/findBindingInfoBySectionNo")
    public Result findBindingInfoBySectionNo(@RequestBody @Valid SectionInfo info, BindingResult bindingResult) {
        try {
            if (bindingResult.hasErrors()) {
                return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
            }
            CrystalTrayBindInfoResult result = mcsToMesService.findBindingInfoBySectionNo(info);
            return ResultGenerator.success(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询晶棒信息:", e);
            return ResultGenerator.fail("出现错误:" + e.getMessage());
        }
    }


    @ApiOperation(value = "方棒库上传出库数据")
    @PostMapping(value = "/uploadInventory")
    public Result uploadInventory(@RequestBody List<McsFbInventoryDto> fbInventoryDto) {
        if (CollectionUtils.isEmpty(fbInventoryDto)) {
            return ResultGenerator.fail("入参不能为空！");
        }
        try {
            return mcsToMesService.uploadInventory(fbInventoryDto);
        } catch (Exception e) {
            return ResultGenerator.message(500, "系统异常:" + e.getMessage(), null);
        }
    }

    @ApiOperation(value = "查询长晶棒信息")
    @PostMapping(value = "/getLongCrystalInfo")
    public Result getLongCrystalInfo(@ApiParam(value = "毛棒单晶编号") @RequestParam String crystalNo) {
        try {
            //查询长晶棒产出表
            LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(crystalNo);
            if (StringUtils.isBlank(byCrystalNo.getCrystalNo())) {
                return ResultGenerator.fail("没有符合条件的数据");
            }
            return ResultGenerator.success(byCrystalNo);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.message(500, "系统异常", null);
        }

    }

    @ApiOperation(value = "方棒打托去向mcs")
    @PostMapping(value = "/matchMakeTrayRuleForMCS")
    public Result matchMakeTrayRuleMcs(@RequestBody BindingDto bindingDto) {
        try {
//            return flsToMesService.matchMakeTrayRule(bindingDto);
            return flsToMesService.matchMakeTrayRuleV2(bindingDto);
        } catch (Exception e) {
            return ResultGenerator.message(500, "系统异常:" + e.getMessage(), null);
        }
    }

    @ApiOperation(value = "生产任务报工接口")
    @PostMapping("/mcsMoPrepareWorkReportingInterface")
    public Result mcsMoPrepareWorkReportingInterface(@RequestBody McsMoWorkReportingDto dto) {
        try {
            String idStr = dto.getOrderNo().substring(2);
            if (dto.getOrderNo().startsWith("0-")) {//装料
                LoadingTask task = loadingTaskService.get(Long.valueOf(idStr));
                return mcsToMesService.moWorkReportingInterface(dto, task);
            } else if (dto.getOrderNo().startsWith("1-") || dto.getOrderNo().startsWith("2-")) {//初始取段
                AgainTaskDetail task = againTaskDetailService.get(Long.valueOf(idStr));
                return mcsToMesService.moWorkReportingInterface(dto, task);
            } else if (dto.getOrderNo().startsWith("3-")) {//预装料任务
                AgainTaskPrepare task = againTaskPrepareService.get(Long.valueOf(idStr));
                return mcsToMesService.moWorkReportingInterface(dto, task);
            } else {
                return ResultGenerator.fail("未知的任务ID");
            }
        } catch (IndexOutOfBoundsException e) {
            return ResultGenerator.fail("任务ID格式错误");
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "预装料任务出库接口")
    @PostMapping("/mcsMoWorkReporting")
    public Result mcsMoWorkReporting(@RequestBody McsMoPrepareWorkReportingDto dto) {
        try {
            AgainTaskPrepare taskPrepare = againTaskPrepareService.get(Long.valueOf(dto.getPrepareOrderNo().substring(2)));
            if (taskPrepare == null) {
                return ResultGenerator.fail("预装料任务" + dto.getPrepareOrderNo() + "不存在！");
            }
            AgainTaskDetail task = againTaskDetailService.get(Long.valueOf(dto.getOrderNo().substring(2)));
            if (task == null) {
                return ResultGenerator.fail("罐料任务" + dto.getOrderNo() + "不存在！");
            }

            return mcsToMesService.mcsMoWorkReporting(taskPrepare, task);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "mcs自动送验绑定")
    @PostMapping("/inspectionBiddingTray")
    public Result inspectionBiddingTray(@RequestBody @Valid @ApiParam(value = "送验绑定信息上传对象") InspectionBindingInfoDto inspectionBindingInfoDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        try {
            mcsToMesService.build(inspectionBindingInfoDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "圆棒面斜、隐裂检测数据上报MES")
    @PostMapping("/hiddenCrackDetection")
    public Result<HiddenCrackDetectionVo> hiddenCrackDetection(@RequestBody String text, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        HiddenCrackDetectionVo vo=null;
        try {
            HiddenCrackDetectionDto hiddenCrackDetectionDto = JSONObject.parseObject(text, HiddenCrackDetectionDto.class);
             vo = mcsToMesService.hiddenCrackDetection(hiddenCrackDetectionDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success(vo);
    }

}
