package com.sw.mes.wipstorage.controller;

import cc.cczn.matrix.common.monitor.entry.MatrixEntry;
import cc.cczn.matrix.common.monitor.entry.NodeType;
import cc.cczn.matrix.common.monitor.watch.TimeWatch;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.entity.FactoryModel;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.workinprocess.dto.PlanProcessingOrderWipStorageDto;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.entity.WipStorage;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.api.system.FbFeignClients;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
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.wipstorage.service.WipStorageYbService;
import com.sw.mes.yb.production.service.CrystalBatchOperationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/yb/wipStorage")
@Slf4j
@Api(description = "在制品接口")
public class WipStorageYbController {
    @Autowired
    ModelMapper modelMapper;
    @Autowired
    private WipStorageYbService wipStorageYbService;
    @Autowired
    private WipStorageService wipStorageService;
    @Autowired
    private YbInspectDataService inspectDataBaseService;
    @Autowired
    private FbFeignClients fbFeignClients;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;


    @Autowired
    private CrystalBatchOperationService crystalBatchOperationService;

    @Autowired
    private EquipmentService equipmentService;

    @ApiOperation("出站")
    @GetMapping("/outStation")
    public Result outStation(@RequestParam String processingOrderCode, @RequestParam(required = false) String wipStorageCode,
                             @RequestParam(required = false) String flowLineLable, @RequestParam(required = false) Integer type,
                             @RequestParam(required = false) Boolean backcutFlag) {
        if (type == null) {
            type = 0;
        }
        if (StringUtils.isBlank(flowLineLable)) {
            flowLineLable = "A";
        }
        if (null != backcutFlag && backcutFlag) {
            flowLineLable = "B";
        }
        PlanProcessingOrderWipStorageDto result = wipStorageService.selectWipStorage(processingOrderCode, wipStorageCode, true);
        FactoryModel factoryModel = wipStorageService.getFactoryModel(result.getWipStorage().getProcessId(), result.getWipStorage().getProcessName());
        //往后，退一站
        EnumValuesFactory.WipStorageCode cWipStorageCode = EnumValuesFactory.WipStorageCode.getEnum(factoryModel.getCode());
        if (cWipStorageCode != null) {
            List<String> sectionNoArr = new ArrayList<>();
            String sectionCompose = null;
            if (type == 0) {
                if (result.getPlanProcessingOrder().getMaterialType() == EnumValuesFactory.MaterialType.圆棒.getKey()) {
                    sectionCompose = inspectDataBaseService.getSectionComposeBySectionNo(result.getPlanProcessingOrder().getCode());
                } else {
                    Result<String> resultSectionCompose = fbFeignClients.getSectionComposeBySectionNo(result.getPlanProcessingOrder().getCode());
                    if (resultSectionCompose.getCode() != ResultCode.SUCCESS.getCode()) {
                        return resultSectionCompose;
                    }
                    sectionCompose = resultSectionCompose.getData();
                }
            }
            if (StringUtils.isNotBlank(sectionCompose)) {
                String[] sectionComposeArr = sectionCompose.split(",");
                for (String sectionCom : sectionComposeArr){
                    if (StringUtils.isNotBlank(sectionCom)){
                        sectionNoArr.add(sectionCom.trim().toUpperCase());
                    }
                }
                //sectionNoArr = Arrays.asList(sectionComposeArr);
            } else {
                sectionNoArr.add(processingOrderCode.trim().toUpperCase());
            }
            //添加批次锁定校验
            for (String code : sectionNoArr) {
                if (StringUtils.equals(EnumValuesFactory.WipStorageCode.毛棒截断.getKey(), wipStorageCode)) {
                    crystalBatchOperationService.judgeCrystalNoIsLock(code, null, true);
                } else {
                    crystalBatchOperationService.judgeCrystalNoIsLock(null, code, false);
                }
            }

            switch (cWipStorageCode) {
                case 开方:
                    return wipStorageYbService.execKfOut(sectionNoArr, result, flowLineLable, wipStorageCode);
                case 磨倒:
                    return wipStorageYbService.execKfOut(sectionNoArr, result, flowLineLable, wipStorageCode);
                case 毛棒截断:
                    return wipStorageYbService.execJd(result, true);
                case 圆棒截断:
                    return wipStorageYbService.execJd(result, true);
                case 方棒截断:
                    return wipStorageYbService.execJd(result, true);
                default:
                    throw new BusinessException("当前站点，不支持该页面操作");
            }
        }


        throw new BusinessException("在制品站点异常");
    }

    @ApiOperation("出站")
    @GetMapping("/outStation1")
    public Result outStation(@RequestParam String code, @RequestParam(required = false) String inStation,
                             @RequestParam(required = false) String outStation) {
        long stationTime = wipStorageYbService.getStationTime(code, inStation, outStation);
        return ResultGenerator.success(stationTime);
    }

    /**
     * pad 通用进站
     *
     * @param processingOrderCode 进站工单号
     * @param deviceCode          设备编号
     * @param wipStorageCode      站点代码
     * @return
     */
    @ApiOperation("pda进站")
    @GetMapping("/inStation")
    public Result inStation(@RequestParam String processingOrderCode, @RequestParam(required = false) String deviceCode, @RequestParam(required = false) String wipStorageCode, @RequestParam(required = false) Integer type) {
        try {
            MatrixEntry.startEntry("inStation");
            Result resultOut = null;
            String[] codes = processingOrderCode.split(",");
            //设备格式去除空格和大写化
            if (StringUtils.isNotBlank(deviceCode)) {
                deviceCode = deviceCode.trim().toUpperCase();
            }

            //添加卡控，禁止方棒检验在PDA上进站操作
            if (StringUtils.equals(EnumValuesFactory.WipStorageCode.方棒检验.getKey(), wipStorageCode)) {
                throw new BusinessException("禁止方棒检验单晶在PDA上进站操作，单晶编号为：" + processingOrderCode);
            }
            for (int i = 0; i < codes.length; i++) {
                String code = codes[i];

                //编号格式去除空格和大写化
                if (StringUtils.isNotBlank(code)){
                    code = code.trim().toUpperCase();
                }
                //添加站点设备信息校验
                try {
                    MatrixEntry.entry("checkDevicePosition: " + i, NodeType.METHOD);
                    this.checkDevicePosition(deviceCode, wipStorageCode, processingOrderCode);
                    MatrixEntry.exit();
                } catch (Exception e) {
                    return ResultGenerator.fail(e.getMessage());
                }
                //添加批次锁定校验
                MatrixEntry.entry("judgeCrystalNoIsLock: " + i, NodeType.METHOD);
                if (StringUtils.equals(EnumValuesFactory.WipStorageCode.毛棒截断.getKey(), wipStorageCode)) {
                    //添加批次锁定校验
                    crystalBatchOperationService.judgeCrystalNoIsLock(code, null, true);
                } else {
                    //添加批次锁定校验
                    crystalBatchOperationService.judgeCrystalNoIsLock(null, code, false);
                }
                MatrixEntry.exit();

                MatrixEntry.entry(EnumValuesFactory.WipStorageCode.圆棒检验.getKey() + i, NodeType.METHOD);
                //添加业务代码
                if (StringUtils.equals(EnumValuesFactory.WipStorageCode.圆棒检验.getKey(), wipStorageCode)) {
                    //判断
                    YbInspectData bySectionNo = inspectDataBaseService.findBySectionNo(processingOrderCode);
                    if (null == bySectionNo || StringUtils.isBlank(bySectionNo.getProductLevel())) {
//                    if (null == bySectionNo) {
                        throw new BusinessException("该单晶评级结果不合格（未检测/检测数据不合格），单晶编号为：" + processingOrderCode);
//                        throw new BusinessException("圆棒检验数据不存在，单晶编号为：" + processingOrderCode);
                    }
                    //晶段类型：标棒，评级类型：正常
                    if (!StringUtils.equals(bySectionNo.getGradeType(),"正常") || !StringUtils.equals(bySectionNo.getSectionType(),"标棒")){
//                    if (!StringUtils.equals(bySectionNo.getSectionType(),"标棒")){
//                        throw new BusinessException("该单晶类型不是标棒（未检测/检测数据不合格）,单晶编号为：" + processingOrderCode);
                        throw new BusinessException("该单晶类型不是标棒或评级结果不合格（未检测/检测数据不合格）,单晶编号为：" + processingOrderCode);
                    }
                    wipStorageCode = EnumValuesFactory.WipStorageCode.开方.getKey();
                    List<PlanProcessingOrder> planProcessingOrderList = planProcessingOrderService.findByCodeOrderByIdDesc(processingOrderCode);
                    if (CollectionUtils.isNotEmpty(planProcessingOrderList)) {
                        WipStorage currentWipStorage = planProcessingOrderList.get(0).getWipStorage();
                        if (null != currentWipStorage && StringUtils.equals(EnumValuesFactory.WipStorageCode.圆棒检验.getValue(), currentWipStorage.getProcessName())
                                && null != currentWipStorage.getStatus() && currentWipStorage.getStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey()) {
                            //圆棒检验待出站时，先出站
                            wipStorageService.outStation(code, "B", EnumValuesFactory.WipStorageStatus.待进站.getKey());
                        }
                    }
                }
                MatrixEntry.exit();

                MatrixEntry.entry("selectWipStorage" + i, NodeType.METHOD);
                PlanProcessingOrderWipStorageDto result = wipStorageService.selectWipStorage(code, wipStorageCode, false);
                MatrixEntry.exit();

                List<String> sectionNoArr = new ArrayList<>();
                String sectionCompose = null;
                if (type == null) {
                    type = 0;
                }

                if (type == 0) {
                    MatrixEntry.entry("type == 0: " + i, NodeType.METHOD);
                    if (result.getPlanProcessingOrder().getMaterialType() == EnumValuesFactory.MaterialType.圆棒.getKey()) {
                        sectionCompose = inspectDataBaseService.getSectionComposeBySectionNo(result.getPlanProcessingOrder().getCode());
                    } else {
                        Result<String> resultSectionCompose = fbFeignClients.getSectionComposeBySectionNo(result.getPlanProcessingOrder().getCode());
                        if (resultSectionCompose.getCode() != ResultCode.SUCCESS.getCode()) {
                            return resultSectionCompose;
                        }
                        sectionCompose = resultSectionCompose.getData();
                    }
                    MatrixEntry.exit();
                }

                if (StringUtils.isNotBlank(sectionCompose)) {
                    String[] sectionComposeArr = sectionCompose.split(",");
                    sectionNoArr = Arrays.asList(sectionComposeArr);
                } else {
                    sectionNoArr.add(code);
                }
                MatrixEntry.entry("padInStation: " + i, NodeType.METHOD);
                if (i == 0) {
                    resultOut = wipStorageYbService.padInStation(sectionNoArr, deviceCode, wipStorageCode);
                } else {
                    wipStorageYbService.padInStation(sectionNoArr, deviceCode, wipStorageCode);
                }
                MatrixEntry.exit();
            }
            return resultOut;

        } finally {
            MatrixEntry.endEntry();
        }
    }


    /**
     * pad 通用进出站
     *
     * @param processingOrderCode 进站工单号
     * @param deviceCode          设备编号
     * @param wipStorageCode      站点代码
     * @param backcutFlag         返切标识
     * @return
     */
    @ApiOperation("pda进站出站")
    @GetMapping("/inAndOutStation")
    public Result inAndOutStation(@RequestParam String processingOrderCode, @RequestParam(required = false) String deviceCode,
                                  @RequestParam(required = false) String wipStorageCode, @RequestParam(required = false) Integer type,
                                  @RequestParam(required = false) Boolean backcutFlag) {
        Result result = null;
        try {
            TimeWatch.startWatch("inAndOutStation");//开始watch
            TimeWatch.watch("inStation");
            Result inResult = this.inStation(processingOrderCode, deviceCode, wipStorageCode, type);
            TimeWatch.watch("outStation");
            Result outResult = this.outStation(processingOrderCode, StringUtils.equals(EnumValuesFactory.WipStorageCode.圆棒检验.getKey(), wipStorageCode) ? EnumValuesFactory.WipStorageCode.开方.getKey() : wipStorageCode, "", type, backcutFlag);
            if (inResult.getCode() == ResultCode.SUCCESS.getCode() && outResult.getCode() == ResultCode.SUCCESS.getCode()) {
                return ResultGenerator.success("操作成功");
            } else if (inResult.getCode() != ResultCode.SUCCESS.getCode()) {
                return ResultGenerator.success("PDA进站操作失败！" + inResult.getMessage());
            } else if (outResult.getCode() != ResultCode.SUCCESS.getCode()) {
                return ResultGenerator.success("PDA出站操作失败！" + inResult.getMessage());
            }
            return result;
        } finally {
            TimeWatch.stopWatch(100);//结束watch,注意一定要释放
        }
    }

    private void checkDevicePosition(String deviceCode, String wipStorageCode, String processingOrderCode) {
        if (StringUtils.isNotBlank(wipStorageCode)) {
            Equipment byCode = equipmentService.findByCode(deviceCode);
            if (StringUtils.isBlank(deviceCode)) {
                throw new RuntimeException("进站设备编号为空！进站工单号为：" + processingOrderCode);
            }
            if (null == byCode) {
                throw new RuntimeException("进站设备台账记录不存在，请先核对设备编号：" + deviceCode + ";进站工单号为：" + processingOrderCode);
            }

            if (null == byCode.getDevice()) {
                throw new RuntimeException("进站设备台账记录设备类型为空，请先核对设备编号：" + deviceCode + ";进站工单号为：" + processingOrderCode);
            }
            if (StringUtils.equals(EnumValuesFactory.WipStorageCode.毛棒截断.getKey(), wipStorageCode)) {
                if (!StringUtils.equals(byCode.getDevice().getName(), EnumValuesFactory.DeviceCategory.截断机.getValue())) {
                    throw new RuntimeException("截断进站设备非截断机设备，请先核对设备编号：" + deviceCode + ";设备类型为：：" + byCode.getDevice().getName());
                }
            } else if (StringUtils.equals(EnumValuesFactory.WipStorageCode.圆棒检验.getKey(), wipStorageCode) || StringUtils.equals(EnumValuesFactory.WipStorageCode.开方.getKey(), wipStorageCode)) {

                if (!StringUtils.equals(byCode.getDevice().getName(), "刀剖机")) {
                    throw new RuntimeException("刀剖进站设备非刀剖机设备，请先核对设备编号：" + deviceCode + ";设备类型为：：" + byCode.getDevice().getName());
                }
            } else if (StringUtils.equals(EnumValuesFactory.WipStorageCode.磨倒.getKey(), wipStorageCode)) {

                if (!StringUtils.equals(byCode.getDevice().getName(), "平磨机")) {
                    throw new RuntimeException("磨削进站设备非平磨机设备，请先核对设备编号：" + deviceCode + ";设备类型为：：" + byCode.getDevice().getName());
                }
            }
        }
    }
}
