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

import cn.estsh.i3plus.ext.mes.api.base.IShiftExtService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesShiftExt;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesShiftExtRepository;
import cn.estsh.i3plus.ext.mes.pojo.sqlpack.MesExtHqlPack;
import cn.estsh.i3plus.ext.mes.pojo.util.ConvertBeanExt;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
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.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.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class ShiftExtService implements IShiftExtService {

    @Autowired
    private MesShiftExtRepository shiftExtRepository;

    @Autowired
    private MesShiftRepository shiftRepository;

    @Override
    public ListPager<MesShiftExt> queryShiftByPager(MesShiftExt shiftExt, Pager pager) {
        DdlPackBean hqlPack = MesExtHqlPack.getShiftExt(shiftExt);
        pager = PagerHelper.getPager(pager, shiftExtRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(shiftExt.orderBy());
        return new ListPager(shiftExtRepository.findByHqlWherePage(hqlPack, pager), pager);
    }

    @Override
    public MesShiftExt insertShift(MesShiftExt shiftExt) {
        DdlPackBean packBean = MesExtHqlPack.getAllBaseData(shiftExt.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(shiftExt.getAreaCode(), MesExtConstWords.AREA_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(shiftExt.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(shiftExt.getShiftCode(), MesExtConstWords.SHIFT_CODE, packBean);
        MesShiftExt shiftExtDb = shiftExtRepository.getByProperty(packBean);
        if (null != shiftExtDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("区域代码[%s]生产线代码[%s]班次代码[%s]记录已存在",
                            shiftExt.getAreaCode(), shiftExt.getWorkCenterCode(), shiftExt.getShiftCode())
                    .build();
        }
        checkWorkerQty(shiftExt.getWorkerQty());

        shiftExt.setWorkTimes(this.getShiftWorkTimes(shiftExt.getStartTime(), shiftExt.getEndTime()));
        ConvertBean.serviceModelInitialize(shiftExt, shiftExt.getCreateUser());
        new ConvertBeanExt(shiftExt).convertBean(shiftExt);
        return shiftExtRepository.insert(shiftExt);
    }

    @Override
    public MesShiftExt updateShift(MesShiftExt shiftExt) {
        //对id做有效性校验
        MesShiftExt shiftExtDb = shiftExtRepository.getById(shiftExt.getId());
        if (shiftExtDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("区域代码[%s]生产线代码[%s]班次代码[%s]记录不存在",
                            shiftExt.getAreaCode(), shiftExt.getWorkCenterCode(), shiftExt.getShiftCode())
                    .build();
        }
        checkWorkerQty(shiftExt.getWorkerQty());

        shiftExtDb.setShiftName(shiftExt.getShiftName());
        shiftExtDb.setStartTime(shiftExt.getStartTime());
        shiftExtDb.setEndTime(shiftExt.getEndTime());
        shiftExtDb.setWorkTimes(this.getShiftWorkTimes(shiftExt.getStartTime(), shiftExt.getEndTime()));
        shiftExtDb.setWorkerQty(shiftExt.getWorkerQty());
        shiftExtDb.setShiftSeq(shiftExt.getShiftSeq());
        shiftExtDb.setAtHomeNum(shiftExt.getAtHomeNum());
        ConvertBean.serviceModelUpdate(shiftExtDb, shiftExt.getModifyUser());
        new ConvertBeanExt(shiftExtDb).convertBean(shiftExtDb);
        return shiftExtRepository.save(shiftExtDb);
    }

    private void checkWorkerQty(Double workerQty) {
        if (MathOperation.compareTo(workerQty, new Double(0)) <= 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("作业人数需大于0")
                    .build();
        }
    }

    @Override
    public void updateShiftValidById(Long id, Integer status, String userName) {
        if (status != CommonEnumUtil.IS_VAILD.INVAILD.getValue() && status != CommonEnumUtil.IS_VAILD.VAILD.getValue()) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("启用，禁用枚举状态值【%s】未被定义", status)
                    .build();
        }
        MesShiftExt shiftExtDb = shiftExtRepository.getById(id);
        if (null == shiftExtDb || shiftExtDb.getIsValid() == status) return;
        shiftExtDb.setIsValid(status);
        ConvertBean.serviceModelUpdate(shiftExtDb, userName);
        new ConvertBeanExt(shiftExtDb).convertBean(shiftExtDb);
        shiftExtRepository.save(shiftExtDb);
    }

    /**
     * 获取班次时长
     *
     * @param startTimeStr HH:mm:ss
     * @param endTimeStr   HH:mm:ss
     * @return
     */
    @Override
    public Double getShiftWorkTimes(String startTimeStr, String endTimeStr) {
        if (StringUtils.isEmpty(startTimeStr) || StringUtils.isEmpty(endTimeStr)) {
            return null;
        }
        Date startTime;
        Date endTime;
        if (TimeTool.stringParseToDate(startTimeStr).compareTo(TimeTool.stringParseToDate(endTimeStr)) >= 0) {
            startTime = TimeTool.stringParseToDate(TimeTool.getToday() + " " + startTimeStr);
            endTime = TimeTool.stringParseToDate(TimeTool.getToday(TimeTool.getDateAfter(startTime, 1)) + " " + endTimeStr);
        } else {
            startTime = TimeTool.stringParseToDate(TimeTool.getToday() + " " + startTimeStr);
            endTime = TimeTool.stringParseToDate(TimeTool.getToday() + " " + endTimeStr);
        }
        //获取时间差(小时，保留2位小数，四舍五入)
        double timeDifference = (endTime.getTime() - startTime.getTime()) / 3600000d;
        String timeDifferenceStr = String.format("%.2f", timeDifference);
        return Double.valueOf(timeDifferenceStr);
    }

    @Override
    public List<MesShift> queryShiftList(String organizeCode) {
        if (StringUtils.isEmpty(organizeCode)) {
            return null;
        }
        return shiftRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue()});
    }

    @Override
    public Map<String, MesShift> queryShiftMap(String organizeCode) {
        List<MesShift> mesShifts = queryShiftList(organizeCode);
        return mesShifts.stream().collect(Collectors.toMap(o->new StringJoiner(MesExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getShiftCode()).toString(), Function.identity(), (x,y) -> y));
    }

    @Override
    public Map<String, String> queryShiftNameMapByWorkCenterCode(String organizeCode, String workCenterCode) {

        List<MesShift> shiftList = shiftRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.WORK_CENTER_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID},
                new Object[]{organizeCode, workCenterCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue()});

        if (CollectionUtils.isEmpty(shiftList)) return new HashMap<>();
        return shiftList.stream().collect(Collectors.toMap(MesShift::getShiftCode, MesShift::getShiftName));
    }
}
