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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesShiftService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
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.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesProdShiftRecord;
import cn.estsh.i3plus.pojo.mes.bean.MesShift;
import cn.estsh.i3plus.pojo.mes.repository.MesShiftRepository;
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.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @Description: 产线与班次的对应关系
 * @Author: gsz
 * @Date: 2024/5/21 14:16
 * @Modify:
 */
@Service
@Slf4j
public class MesShiftServiceImpl implements IMesShiftService {

    @Autowired
    private MesShiftRepository mesShiftRepository;

    @Override
    public ListPager<MesShift> queryMesShiftByPager(MesShift bean, Pager pager) {

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(bean.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(bean.getWorkCenterCode(), "workCenterCode", packBean);
        DdlPreparedPack.getStringEqualPack(bean.getShiftCode(), "shiftCode", packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{"createDatetime"}, packBean);
        pager = PagerHelper.getPager(pager, mesShiftRepository.findByHqlWhereCount(packBean));

        List<MesShift> resultList = mesShiftRepository.findByHqlWherePage(packBean, pager);

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

    @Override
    public List<MesShift> queryMesShift(String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.SHIFT_CODE}, packBean);
        return mesShiftRepository.findByHqlWhere(packBean);
    }

    @Override
    public Map<String, String> getShiftTimeMap(MesProdShiftRecord record) {
        if (StringUtils.isEmpty(record.getStartTime())) return null;
        List<MesShift> shiftList = queryMesShift(record.getOrganizeCode(), record.getWorkCenterCode());
        if (CollectionUtils.isEmpty(shiftList)) return null;
        Optional<MesShift> shiftOptional = shiftList.stream().filter(t -> t.getShiftCode().equals(record.getShiftCode())).findFirst();
        if (null == shiftOptional || !shiftOptional.isPresent()) return null;
        if (StringUtils.isEmpty(shiftOptional.get().getStartTime()) || StringUtils.isEmpty(shiftOptional.get().getEndTime())) return null;
        if (StringUtils.isEmpty(shiftList.get(0).getStartTime())) return null;

        //当天
        String today = TimeTool.getToday();
        //当天早班的开始时间
        String todayStartTime = today + MesPcnExtConstWords.ONE_SPACE + shiftList.get(0).getStartTime();
        //实际开班时间 比 当天早班的开始时间 小的情况下, 代表的是前一天的班次
        if (record.getStartTime().compareTo(todayStartTime) < 0) {
            String yesterday = calcDay(today, -1);
            return calcShiftTime(shiftOptional.get().getStartTime(), shiftOptional.get().getEndTime(), yesterday);
        } else {
            //当天的班次
            return calcShiftTime(shiftOptional.get().getStartTime(), shiftOptional.get().getEndTime(), today);
        }
    }

    //计算的实际班次开始与结束的时间
    private Map<String, String> calcShiftTime(String shiftStartTime, String shiftEndTime, String calcDay) {
        //待计算的实际班次开始与结束的时间
        String startTime, endTime;
        if (shiftStartTime.compareTo(shiftEndTime) < 0) {
            //不跨天
            startTime = calcDay + MesPcnExtConstWords.ONE_SPACE + shiftStartTime;
            endTime = calcDay + MesPcnExtConstWords.ONE_SPACE + shiftEndTime;
        } else {
            //跨天
            startTime = calcDay + MesPcnExtConstWords.ONE_SPACE + shiftStartTime;
            endTime = calcDay(calcDay, 1) + MesPcnExtConstWords.ONE_SPACE + shiftEndTime;
        }
        Map<String, String> shiftTimeMap = new HashMap<>(2);
        shiftTimeMap.put(MesPcnExtConstWords.START_TIME, startTime);
        shiftTimeMap.put(MesPcnExtConstWords.END_TIME, endTime);
        return shiftTimeMap;
    }

    //计算天数
    @Override
    public String calcDay(String day, int amount) {
        try {
            DateFormat sdf = new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SEPARATOR);
            return TimeTool.timeCalc(sdf.parse(day), Calendar.DATE, amount, MesPcnExtConstWords.DATE_FORMAT_SEPARATOR);
        } catch (ParseException e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("时间计算失败")
                    .build();
        }
    }

    //根据当前时间计算实际整天班次的时间
    @Override
    public Map<String, String> calcAllDayShiftTimeMapByCurTime(String organizeCode, String workCenterCode) {
        //根据生产线查询关联的班次集合, 根据班次代码正序
        List<MesShift> shiftList = queryMesShift(organizeCode, workCenterCode);
        if (CollectionUtils.isEmpty(shiftList)) return null;
        if (StringUtils.isEmpty(shiftList.get(0).getStartTime()) || StringUtils.isEmpty(shiftList.get(shiftList.size() - 1).getEndTime())) return null;

        //当天
        String today = TimeTool.getToday();
        //当天早班的开始时间
        String todayStartTime = today + MesPcnExtConstWords.ONE_SPACE + shiftList.get(0).getStartTime();

        //当前时间 比 当天早班的开始时间 小的情况下, 代表的是前一天的班次
        Map<String, String> shiftTimeMap;
        if (TimeTool.getNowTime(true).compareTo(todayStartTime) < 0) {
            String yesterday = calcDay(today, -1);
            shiftTimeMap = calcShiftTime(shiftList.get(0).getStartTime(), shiftList.get(shiftList.size() - 1).getEndTime(), yesterday);
            shiftTimeMap.put(MesPcnExtConstWords.LOT_NO, yesterday);
        } else {
            //当天的班次
            shiftTimeMap = calcShiftTime(shiftList.get(0).getStartTime(), shiftList.get(shiftList.size() - 1).getEndTime(), today);
            shiftTimeMap.put(MesPcnExtConstWords.LOT_NO, today);
        }

        return shiftTimeMap;
    }

    //根据当前时间计算当前班次的时间
    @Override
    public Map<String, String> calcCurShiftTimeMapByCurTime(String organizeCode, String workCenterCode) {
        //根据生产线查询关联的班次集合, 根据班次代码正序
        List<MesShift> shiftList = queryMesShift(organizeCode, workCenterCode);
        if (CollectionUtils.isEmpty(shiftList)) return null;

        String nowTime = TimeTool.getNowTime(true);
        String today = nowTime.substring(0, 10);
        String time = nowTime.substring(11);

        MesShift shiftOp = null;
        for (MesShift shift : shiftList) {
            if (null == shift || StringUtils.isEmpty(shift.getStartTime()) || StringUtils.isEmpty(shift.getEndTime())) continue;
            if (shift.getStartTime().compareTo(shift.getEndTime()) < 0) {
                if (shift.getStartTime().compareTo(time) <= 0 && shift.getEndTime().compareTo(time) >= 0) shiftOp = shift;
            } else {
                if (shift.getStartTime().compareTo(time) <= 0 || shift.getEndTime().compareTo(time) >= 0) shiftOp = shift;
            }
        }

        if (null == shiftOp) return null;

        //当天早班的开始时间
        String todayStartTime = today + MesPcnExtConstWords.ONE_SPACE + shiftList.get(0).getStartTime();
        //实际开班时间 比 当天早班的开始时间 小的情况下, 代表的是前一天的班次
        if (nowTime.compareTo(todayStartTime) < 0) {
            String yesterday = calcDay(today, -1);
            return calcShiftTime(shiftOp.getStartTime(), shiftOp.getEndTime(), yesterday);
        } else {
            //当天的班次
            return calcShiftTime(shiftOp.getStartTime(), shiftOp.getEndTime(), today);
        }

    }

}
