package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.base;

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEquipmentExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdShiftRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesShiftService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdShiftContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.util.StationKvBeanUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.base.util.StringUtil;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
import cn.estsh.i3plus.pojo.mes.repository.MesConfigRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesDowntimeRecordRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesProdShiftRecordRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWcEquipmentRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * @Description: 开关班记录表
 * @Author: gsz
 * @Date: 2024/5/21 14:16
 * @Modify:
 */
@Service
@Slf4j
public class MesProdShiftRecordServiceImpl implements IMesProdShiftRecordService {

    @Autowired
    private MesProdShiftRecordRepository mesProdShiftRecordRDao;

    @Autowired
    private MesConfigRepository configRepository;

    @Autowired
    private MesDowntimeRecordRepository mesDowntimeRecordRDao;

    @Autowired
    private MesWcEquipmentRepository wcEquipmentRepository;

    @Autowired
    private IMesEquipmentExtService mesEquipmentExtService;

    @Autowired
    private IMesShiftService mesShiftService;

    @Autowired
    private IMesProductionCustomContextStepService productionCustomContextStepService;

    @Override
    public ListPager<MesProdShiftRecord> queryMesProdShiftRecordByPager(MesProdShiftRecord bean, Pager pager) {

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(bean.getWorkCenterCode(), "workCenterCode", packBean);
        DdlPreparedPack.getStringEqualPack(bean.getShiftGroup(), "shiftGroup", packBean);
        DdlPreparedPack.getStringEqualPack(bean.getShiftCode(), "shiftCode", packBean);
        if (!StringUtil.isEmpty(bean.orderBy())) {
            packBean.setOrderByStr(bean.orderBy());
        } else {
            DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{"createDatetime"}, packBean);
        }
        pager = PagerHelper.getPager(pager, mesProdShiftRecordRDao.findByHqlWhereCount(packBean));

        List<MesProdShiftRecord> resultList = mesProdShiftRecordRDao.findByHqlWherePage(packBean, pager);

        return new ListPager<>(resultList, pager);
    }

    @Override
    public void insertMesProdShiftRecord(MesProdShiftRecord item) {
        //唯一性校验
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(item.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(item.getWorkCenterCode(), "workCenterCode", packBean);
//        DdlPreparedPack.getStringEqualPack(item.getShiftGroup(), "shiftGroup", packBean);
        DdlPreparedPack.getIsNull("endTime", packBean);

        boolean flg = mesProdShiftRecordRDao.isExitByHql(packBean);
        if (flg) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("开关班记录产线【%s】班组代码【%s】已经存在，请检查数据",
                            item.getWorkCenterCode(), item.getShiftGroup())
                    .build();
        }
        ConvertBean.serviceModelInitialize(item, item.getUserInfo());
        mesProdShiftRecordRDao.insert(item);

        //缓存班次数据
        productionCustomContextStepService.dispatchProdShiftDataContext(item.getOrganizeCode(), item.getWorkCenterCode(), getProdShiftData(item));

    }

    //如果结班,会清除缓存中的班次数据
    @Override
    public void saveMesProdShiftRecord(MesProdShiftRecord item) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(item.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(item.getWorkCenterCode(), "workCenterCode", packBean);
        DdlPreparedPack.getStringEqualPack(item.getShiftGroup(), "shiftGroup", packBean);
        DdlPreparedPack.getStringEqualPack(item.getShiftCode(), "shiftCode", packBean);
//        DdlPreparedPack.getStringEqualPack(item.getStartTime(), "startTime", packBean);
        DdlPreparedPack.getIsNull("endTime", packBean);

        MesProdShiftRecord mesProdShiftRecord = mesProdShiftRecordRDao.getByProperty(packBean);
        if (StringUtil.isEmpty(mesProdShiftRecord)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("开关班记录产线【%s】班组代码【%s】 不存在，请检查数据",
                            item.getWorkCenterCode(), item.getShiftGroup())
                    .build();
        }
        mesProdShiftRecord.setShiftGroup(item.getShiftGroup());
        mesProdShiftRecord.setShiftCode(item.getShiftCode());
        mesProdShiftRecord.setEndTime(item.getEndTime());
        mesProdShiftRecord.setWorkStatus(item.getWorkStatus());
        ConvertBean.serviceModelUpdate(mesProdShiftRecord, item.getUserInfo());
        mesProdShiftRecordRDao.update(mesProdShiftRecord);
        //结班后， 系统生产一条停机记录，原因：无订单停机
        MesConfig reasonCfg = configRepository.getByProperty(
                new String[]{"cfgKey", "organizeCode", "isValid", "isDeleted"},
                new Object[]{ "MES_DOWNTIME_RECORD_SHIFT_REASON", item.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.IS_DEAL.NO.getValue()});

        String reason = "";
        if (!Objects.isNull(reasonCfg) && StringUtils.isEmpty(reasonCfg.getCfgValue())) {
            reason = reasonCfg.getCfgValue();
        }
        MesConfig typeCfg = configRepository.getByProperty(
                new String[]{"cfgKey", "organizeCode", "isValid", "isDeleted"},
                new Object[]{"MES_DOWNTIME_RECORD_SHIFT_TYPE", item.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.IS_DEAL.NO.getValue()});
        String type = "";
        if (!Objects.isNull(typeCfg) && StringUtils.isEmpty(typeCfg.getCfgValue())) {
            type = typeCfg.getCfgValue();
        }
        List<MesWcEquipment> wcEquipmentDbList = wcEquipmentRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE},
                new Object[]{item.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), item.getWorkCenterCode()});
        if (CollectionUtils.isEmpty(wcEquipmentDbList)) {
            MesPcnException.throwMesBusiException("产线【%s】工位设备信息不存在", item.getWorkCenterCode());
        }
        for (MesWcEquipment mesWcEquipment : wcEquipmentDbList) {
            DdlPackBean ddlPackBeanDowntime = DdlPackBean.getDdlPackBean(item.getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(mesWcEquipment.getEquipmentCode(), "equipmentCode", ddlPackBeanDowntime);
            if (!StringUtil.isEmpty(reason)) {
                DdlPreparedPack.getStringEqualPack(reason, "reasonCode", ddlPackBeanDowntime);
            }
            if (!StringUtil.isEmpty(type)) {
                DdlPreparedPack.getStringEqualPack(type, "reasonTypeCode", ddlPackBeanDowntime);
            }
            MesDowntimeRecord mesDowntimeRecordDao = mesDowntimeRecordRDao.getByProperty(ddlPackBeanDowntime);
            if (Objects.isNull(mesDowntimeRecordDao)) {
                MesEquipment mesEquipment = mesEquipmentExtService.getMesEquipment(item.getOrganizeCode(), mesWcEquipment.getEquipmentCode());
                if (Objects.isNull(mesEquipment)) {
                    MesPcnException.throwMesBusiException("设备【%s】信息不存在", mesWcEquipment.getEquipmentCode());
                }
                //新增设备停机记录
                MesDowntimeRecord mesDowntimeRecord = new MesDowntimeRecord();
                mesDowntimeRecord.setOrganizeCode(item.getOrganizeCode());
                mesDowntimeRecord.setEquipId(mesEquipment.getEquipId());
                mesDowntimeRecord.setEquipmentCode(mesEquipment.getEquipmentCode());
                mesDowntimeRecord.setAreaCode(item.getAreaCode());
                mesDowntimeRecord.setWorkCenterCode(item.getWorkCenterCode());
                mesDowntimeRecord.setWorkCellCode(mesWcEquipment.getWorkCellCode());
                mesDowntimeRecord.setReasonCode(StringUtil.isEmpty(reason) ? "" : reason);
                mesDowntimeRecord.setReasonTypeCode(StringUtil.isEmpty(type) ? "" : type);
                ConvertBean.serviceModelInitialize(mesDowntimeRecord, item.getUserInfo());

                mesDowntimeRecordRDao.insert(mesDowntimeRecord);
//                //将当前新增数据的create_date_time时间些到上一条记录的modify_date_time字段
//                DdlPackBean ddlPackBeanOt = DdlPackBean.getDdlPackBean(organizeCode);
//                DdlPreparedPack.getStringEqualPack(mesEquipment.getEquipmentCode(), "equipmentCode", ddlPackBeanOt);
//                ddlPackBeanOt.setWhereAppend(ddlPackBeanOt.getWhereAppend() + " order by createDatetime desc ");
//                MesDowntimeRecord mesDowntimeRecordOt = mesDowntimeRecordRDao.getByProperty(ddlPackBeanOt);
//                if (StringUtil.isEmpty(mesDowntimeRecordOt)) {
//                    mesDowntimeRecordOt.setModifyDatetime(mesDowntimeRecord.getCreateDatetime());
//                    mesDowntimeRecordOt.setModifyUser(AuthUtil.getSessionUser().getUserName());
//                    mesDowntimeRecordRDao.update(mesDowntimeRecordOt);
//                }
            } else {
                ConvertBean.serviceModelUpdate(mesDowntimeRecordDao, "MesDowntimeRecordJob");
                mesDowntimeRecordRDao.update(mesDowntimeRecordDao);
            }
        }

        //如果结班,会清除缓存中的班次数据
        if (item.getWorkStatus().compareTo(MesExtEnumUtil.WORK_STATUS.END.getValue()) == 0) {
            productionCustomContextStepService.removeProdShiftDataContext(item.getOrganizeCode(), item.getWorkCenterCode());
        }

    }

    @Override
    public MesProdShiftRecord queryMesProdShiftRecord(MesProdShiftRecord bean) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(bean.getWorkCenterCode(), "workCenterCode", packBean);
        DdlPreparedPack.getStringEqualPack(bean.getShiftGroup(), "shiftGroup", packBean);
        if (bean.getWorkStatus() != null) {
            DdlPreparedPack.getNumEqualPack(bean.getWorkStatus(), "workStatus", packBean);
        }
        packBean.setOrderByStr(bean.orderBy());

        return mesProdShiftRecordRDao.getByProperty(packBean);
    }

    @Override
    public MesProdShiftRecord getProdShiftRecordOpenStatus(String organizeCode, String workCenterCode) {
        MesProdShiftRecord prodShiftRecord = getProdShiftRecordCdtDesc(organizeCode, workCenterCode);
        if (prodShiftRecord != null && !StringUtils.isEmpty(prodShiftRecord.getWorkStatus()) && prodShiftRecord.getWorkStatus().compareTo(MesExtEnumUtil.WORK_STATUS.START.getValue()) == 0) return prodShiftRecord;
        return null;
    }

    @Override
    public MesProdShiftRecord getProdShiftRecordCdtDesc(String organizeCode, String workCenterCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesPcnExtConstWords.CREATE_DATE_TIME}, packBean);
        return mesProdShiftRecordRDao.getByProperty(packBean);
    }

    //封装展示组件班组班次内容
    @Override
    public List<StationKvBean> getProdShiftData(MesProdShiftRecord record) {
        if (null == record) return null;
        List<StationKvBean> stationKvBeans = StationKvBeanUtil.addStationKvBeanList(new ArrayList<>(),
                new StationKvBean(MesPcnExtConstWords.SHIFT_GROUP, "班组", record.getShiftGroup()),
                new StationKvBean(MesPcnExtConstWords.SHIFT_GROUP_NAME, "班组名称", record.getShiftGroupName()),
                new StationKvBean(MesPcnExtConstWords.SHIFT_CODE, "班次", record.getShiftCode()),
                new StationKvBean(MesPcnExtConstWords.SHIFT_NAME, "班次名称", record.getShiftName()));

        //班次开始时间 ，班次结束时间
        Map<String, String> shiftTimeMap = mesShiftService.getShiftTimeMap(record);
        if (!CollectionUtils.isEmpty(shiftTimeMap)) {
            StationKvBeanUtil.addStationKvBeanList(stationKvBeans,
                    new StationKvBean(MesPcnExtConstWords.START_TIME,"开始时间", shiftTimeMap.get(MesPcnExtConstWords.START_TIME)),
                    new StationKvBean(MesPcnExtConstWords.END_TIME,"结束时间",shiftTimeMap.get(MesPcnExtConstWords.END_TIME)));
        }

        return stationKvBeans;
    }

    //获取展示组件班组班次内容
    @Override
    public List<StationKvBean> getShiftRecordStationKvBeans(String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null;
        // 获取班次信息 redis
        List<StationKvBean> prodShiftDataContext = productionCustomContextStepService.getProdShiftDataContext(organizeCode, workCenterCode);
        if (CollectionUtils.isEmpty(prodShiftDataContext)) {
            // 查询数据库
            MesProdShiftRecord prodShiftRecord = getProdShiftRecordOpenStatus(organizeCode, workCenterCode);
            if (prodShiftRecord != null) {
                prodShiftDataContext = getProdShiftData(prodShiftRecord);
                productionCustomContextStepService.dispatchProdShiftDataContext(organizeCode, workCenterCode, prodShiftDataContext);
            }
        }
        return prodShiftDataContext;
    }

    //获取生产线的当前班组班次信息
    @Override
    public MesProdShiftContext getMesProdShiftKvBean(String organizeCode, String workCenterCode) {

        List<StationKvBean> prodShiftDataContext = getShiftRecordStationKvBeans(organizeCode, workCenterCode);
        if (CollectionUtils.isEmpty(prodShiftDataContext)) return null;

        return getMesProdShiftKvBean(prodShiftDataContext);
    }

    //封装当前班组班次信息
    @Override
    public MesProdShiftContext getMesProdShiftKvBean(List<StationKvBean> prodShiftDataContext) {
        if (CollectionUtils.isEmpty(prodShiftDataContext)) return null;

        StationKvBean shiftGroupKvBean = prodShiftDataContext.stream().filter(stationKvBean -> com.google.common.base.Objects.equal(stationKvBean.getKey(), MesPcnExtConstWords.SHIFT_GROUP)).findFirst().orElse(null);
        StationKvBean shiftCodeKvBean = prodShiftDataContext.stream().filter(stationKvBean -> com.google.common.base.Objects.equal(stationKvBean.getKey(), MesPcnExtConstWords.SHIFT_CODE)).findFirst().orElse(null);

        MesProdShiftContext mesProdShiftContext = new MesProdShiftContext();
        mesProdShiftContext.setShiftCode(shiftGroupKvBean == null ? null : shiftCodeKvBean.getValue());
        mesProdShiftContext.setShiftGroup(shiftCodeKvBean == null ? null : shiftGroupKvBean.getValue());
        return  mesProdShiftContext;
    }

}
