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

import cn.estsh.i3plus.ext.mes.api.base.jx.IJxTimeSegmentStatisticsService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesTimeSegmentStatistics;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesTimeSegmentStatisticsRepository;
import cn.estsh.i3plus.ext.mes.pojo.sqlpack.MesExtHqlPack;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
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.impp.framework.boot.exception.ImppExceptionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.util.List;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @Description : 分时段统计方式实现
 * @Reference :
 * @Author : wangjie
 * @CreateDate : 2023/02/06 13:42
 * @Modify:
 **/
@Service
public class JxTimeSegmentStatisticsService implements IJxTimeSegmentStatisticsService {

    @Autowired
    private MesTimeSegmentStatisticsRepository timeSegmentStatisticsRepository;

    @Override
    public ListPager<MesTimeSegmentStatistics> queryTimeSegmentStatisticsByPager(MesTimeSegmentStatistics timeSegmentStatistics, Pager pager) {
        DdlPackBean hqlPack = MesExtHqlPack.getTimeSegmentStatistics(timeSegmentStatistics);
        pager = PagerHelper.getPager(pager, timeSegmentStatisticsRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(timeSegmentStatistics.orderBy());
        return new ListPager(timeSegmentStatisticsRepository.findByHqlWherePage(hqlPack, pager), pager);
    }

    @Override
    public void insertTimeSegmentStatistics(MesTimeSegmentStatistics timeSegmentStatistics){
        List<MesTimeSegmentStatistics> timeSegmentStatisticsList = getTimeSegmentStatisticsList(timeSegmentStatistics.getOrganizeCode(), timeSegmentStatistics.getWorkCenterCode(), timeSegmentStatistics.getShiftCode());
        checkTimeIsValid(timeSegmentStatisticsList, timeSegmentStatistics);
        timeSegmentStatistics.setTimeLength(getTimeLength(timeSegmentStatistics.getStartTime(), timeSegmentStatistics.getEndTime(), TimeTool.getToday()));
        timeSegmentStatistics.setTimeSegmentCode(getTimeSegmentCode(timeSegmentStatistics));
        timeSegmentStatistics.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        ConvertBean.serviceModelInitialize(timeSegmentStatistics, timeSegmentStatistics.getCreateUser());
        timeSegmentStatisticsRepository.insert(timeSegmentStatistics);
    }

    @Override
    public void updateTimeSegmentStatistics(MesTimeSegmentStatistics timeSegmentStatistics) {
        List<MesTimeSegmentStatistics> timeSegmentStatisticsList = getTimeSegmentStatisticsList(timeSegmentStatistics.getOrganizeCode(), timeSegmentStatistics.getWorkCenterCode(), timeSegmentStatistics.getShiftCode());
        Optional<MesTimeSegmentStatistics> timeSegmentStatisticsDbOp = CollectionUtils.isEmpty(timeSegmentStatisticsList) ? null : timeSegmentStatisticsList.stream().filter(o -> (null != o && o.getId().compareTo(timeSegmentStatistics.getId()) == 0)).findFirst();
        if (null == timeSegmentStatisticsDbOp || !timeSegmentStatisticsDbOp.isPresent())
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("ID[%s]记录不存在!", timeSegmentStatistics.getId())
                    .build();
        timeSegmentStatisticsList = timeSegmentStatisticsList.stream().filter(o -> (null != o && o.getId().compareTo(timeSegmentStatistics.getId()) != 0)).collect(Collectors.toList());
        checkTimeIsValid(timeSegmentStatisticsList, timeSegmentStatistics);
        MesTimeSegmentStatistics timeSegmentStatisticsDb = timeSegmentStatisticsDbOp.get();
        timeSegmentStatisticsDb.setWorkCenterCode(timeSegmentStatistics.getWorkCenterCode());
        timeSegmentStatisticsDb.setShiftCode(timeSegmentStatistics.getShiftCode());
        timeSegmentStatisticsDb.setStartTime(timeSegmentStatistics.getStartTime());
        timeSegmentStatisticsDb.setEndTime(timeSegmentStatistics.getEndTime());
        timeSegmentStatisticsDb.setTimeLength(getTimeLength(timeSegmentStatisticsDb.getStartTime(), timeSegmentStatisticsDb.getEndTime(), TimeTool.getToday()));
        timeSegmentStatisticsDb.setTimeSegmentCode(getTimeSegmentCode(timeSegmentStatisticsDb));
        timeSegmentStatisticsDb.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
        ConvertBean.serviceModelUpdate(timeSegmentStatisticsDb, timeSegmentStatistics.getModifyUser());
        timeSegmentStatisticsRepository.save(timeSegmentStatisticsDb);
    }

    private void checkTimeIsValid(List<MesTimeSegmentStatistics> timeSegmentStatisticsList, MesTimeSegmentStatistics timeSegmentStatistics) {
        if (!checkTimeFormat(timeSegmentStatistics.getStartTime()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("开始时间[%s]格式错误,请检查时间格式[%s]!", timeSegmentStatistics.getStartTime(), MesExtConstWords.TIME_TRUNCATE_SECOND_FORMAT)
                    .build();
        if (!checkTimeFormat(timeSegmentStatistics.getEndTime()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("结束时间[%s]格式错误,请检查时间格式[%s]!", timeSegmentStatistics.getEndTime(), MesExtConstWords.TIME_TRUNCATE_SECOND_FORMAT)
                    .build();
        if (!checkTimeStartBeforeEnd(timeSegmentStatistics.getStartTime(), timeSegmentStatistics.getEndTime()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("开始时间[%s]必须小于结束时间[%s]!", timeSegmentStatistics.getStartTime(), timeSegmentStatistics.getEndTime())
                    .build();
        String startTime = timeSegmentStatistics.getStartTime();
        String endTime = timeSegmentStatistics.getEndTime();
        timeSegmentStatistics.setStartTime(startTime + MesExtConstWords.APPEND_SECONDS);
        timeSegmentStatistics.setEndTime(endTime + MesExtConstWords.APPEND_SECONDS);
        MesTimeSegmentStatistics item = checkTimeCompareToDataList(timeSegmentStatisticsList, timeSegmentStatistics);
        if (null != item)
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("开始时间[%s]结束时间[%s]与已维护的生产线[%s]班次代码[%s]配置的开始时间[%s]结束时间[%s]存在时间重叠!",
                            startTime, endTime, item.getWorkCenterCode(), item.getShiftCode(), item.getStartTime(), item.getEndTime())
                    .build();
    }

    @Override
    public Boolean checkTimeFormat(String time) { return TimeTool.checkDateFormat(time, MesExtConstWords.TIME_TRUNCATE_SECOND_FORMAT); }

    @Override
    public Boolean checkTimeStartBeforeEnd(String startTime, String endTime) { return startTime.compareTo(endTime) < 0 ? true : false; }

    @Override
    public MesTimeSegmentStatistics checkTimeCompareToDataList(List<MesTimeSegmentStatistics> timeSegmentStatisticsList, MesTimeSegmentStatistics timeSegmentStatistics) {
        if (CollectionUtils.isEmpty(timeSegmentStatisticsList)) return null;
        for (MesTimeSegmentStatistics item : timeSegmentStatisticsList) {
            if (StringUtils.isEmpty(item.getStartTime()) || StringUtils.isEmpty(item.getEndTime())) continue;
            if (timeSegmentStatistics.getStartTime().compareTo(item.getStartTime()) <= 0 && timeSegmentStatistics.getEndTime().compareTo(item.getStartTime()) > 0) return item;
            if (timeSegmentStatistics.getStartTime().compareTo(item.getStartTime()) >= 0 && timeSegmentStatistics.getStartTime().compareTo(item.getEndTime()) < 0) return item;
        }
        return null;
    }

    @Override
    public String getTimeLength(String startTime, String endTime, String today) {
        try {
            return String.valueOf(TimeTool.getSecoundsBetweenTime(1, getTimeAppendToday(today, startTime), getTimeAppendToday(today, endTime)));
        } catch (ParseException e) {
            return null;
        }
    }

    private String getTimeAppendToday(String today, String time) {
        return new StringJoiner(MesExtConstWords.ONE_SPACE).add(today).add(time).toString();
    }

    @Override
    public String getTimeSegmentCode(MesTimeSegmentStatistics timeSegmentStatistics) {
        return new StringJoiner(MesExtConstWords.COLON).add(timeSegmentStatistics.getWorkCenterCode()).add(timeSegmentStatistics.getShiftCode()).add(timeSegmentStatistics.getStartTime().substring(0, 5)).toString().replaceAll(MesExtConstWords.COLON, MesExtConstWords.EMPTY);
    }

    @Override
    public void doDisable(Long[] ids, String userName) { updateStatusByIds(ids, userName, CommonEnumUtil.IS_VAILD.INVAILD.getValue(), true); }

    @Override
    public void doEnable(Long[] ids, String organizeCode, String userName) { updateStatusByIds(ids, userName, CommonEnumUtil.IS_VAILD.VAILD.getValue(), true); }

    @Override
    public void deleteByIds(Long[] ids, String userName) { updateStatusByIds(ids, userName, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), false); }

    private void updateStatusByIds(Long[] ids, String userName, int status, Boolean flag) {
        for (Long id : ids) {
            MesTimeSegmentStatistics timeSegmentStatistics = timeSegmentStatisticsRepository.getById(id);
            if (null == timeSegmentStatistics) return;
            if (flag && timeSegmentStatistics.getIsValid() == status) return;
            if (!flag && timeSegmentStatistics.getIsDeleted() == status) return;
            if (flag) timeSegmentStatistics.setIsValid(status);
            else timeSegmentStatistics.setIsDeleted(status);
            timeSegmentStatistics.setSystemSyncStatus(MesExtEnumUtil.IF_SYNC_STATUS.NO_SYNC.getValue());
            ConvertBean.serviceModelUpdate(timeSegmentStatistics, userName);
            timeSegmentStatisticsRepository.save(timeSegmentStatistics);
        }
    }

    @Override
    public List<MesTimeSegmentStatistics> getTimeSegmentStatisticsList(String organizeCode, String workCenterCode, String shiftCode) {
        return timeSegmentStatisticsRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.WORK_CENTER_CODE, MesExtConstWords.SHIFT_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, shiftCode});
    }

}
