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

import cn.estsh.i3plus.ext.mes.api.base.IProdOrgExtService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesAreaExt;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesWorkCenterExt;
import cn.estsh.i3plus.ext.mes.pojo.model.SxProdOrgModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesAreaExtRepository;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesWorkCenterExtRepository;
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.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.enumutil.MesEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkCellRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkCenterRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 ProdOrgExtService implements IProdOrgExtService {

    @Autowired
    private MesAreaExtRepository areaExtRepository;

    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;

    @Autowired
    private MesWorkCenterRepository workCenterRepository;

    @Autowired
    private MesWorkCellRepository workCellRepository;

    @Override
    public Object insertProdOrg(SxProdOrgModel prodOrgModel) {
        if (MesEnumUtil.PROD_ORG_LEVEL.LEVEL_ONE.getValue() == prodOrgModel.getLevel()) {
            MesAreaExt area = new MesAreaExt();
            BeanUtils.copyProperties(prodOrgModel, area);

            MesAreaExt areaExtDb = areaExtRepository.getByProperty(
                    new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.AREA_CODE},
                    new Object[]{area.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), area.getAreaCode()});
            if (null != areaExtDb) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("区域代码为[%s]的记录已存在", area.getAreaCode())
                        .build();
            }
            new ConvertBeanExt(area).convertBean(area);
            return areaExtRepository.insert(area);
        }
        if (MesEnumUtil.PROD_ORG_LEVEL.LEVEL_TWO.getValue() == prodOrgModel.getLevel()) {
            MesWorkCenterExt workCenterExt = new MesWorkCenterExt();
            BeanUtils.copyProperties(prodOrgModel, workCenterExt);

            MesWorkCenterExt workCenterExtDb = workCenterExtRepository.getByProperty(
                    new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.WORK_CENTER_CODE},
                    new Object[]{workCenterExt.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), workCenterExt.getWorkCenterCode()});
            if (null != workCenterExtDb) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("生产线代码为[%s]的记录已存在", workCenterExt.getWorkCenterCode())
                        .build();
            }
            workCenterExt.setRunningStatus(MesEnumUtil.WORK_CENTER_RUNNING_STATUS.STOPPED.getValue());
            new ConvertBeanExt(workCenterExt).convertBean(workCenterExt);
            return workCenterExtRepository.insert(workCenterExt);
        }
        if (MesEnumUtil.PROD_ORG_LEVEL.LEVEL_THREE.getValue() == prodOrgModel.getLevel()) {
            MesWorkCell workCell = new MesWorkCell();
            BeanUtils.copyProperties(prodOrgModel, workCell);

            MesWorkCell workCellDb = workCellRepository.getByProperty(
                    new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.WORK_CELL_CODE, MesExtConstWords.WORK_CENTER_CODE},
                    new Object[]{workCell.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), workCell.getWorkCellCode(), workCell.getWorkCenterCode()});
            if (null != workCellDb) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                        .setErrorDetail("生产线代码为[%s]工位代码为[%s]的记录已存在", workCell.getWorkCenterCode(), workCell.getWorkCellCode())
                        .build();
            }
            workCell.setGrade(prodOrgModel.getGrade());
            return workCellRepository.insert(workCell);
        }
        return null;
    }

    @Override
    public MesAreaExt updateAreaExt(MesAreaExt areaExt) {
        //对id做有效性校验
        MesAreaExt areaExtDb = areaExtRepository.getById(areaExt.getId());
        if (areaExtDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("区域代码[%s]的记录不存在", areaExt.getAreaCode())
                    .build();
        }

        areaExtDb.setAreaName(areaExt.getAreaName());
        areaExtDb.setCategoryCode3(areaExt.getCategoryCode3());
        ConvertBean.serviceModelUpdate(areaExtDb, areaExt.getModifyUser());
        new ConvertBeanExt(areaExtDb).convertBean(areaExtDb);
        return areaExtRepository.save(areaExtDb);
    }

    @Override
    public MesWorkCenterExt updateWorkCenterExt(MesWorkCenterExt workCenterExt) {
        //对id做有效性校验
        MesWorkCenterExt workCenterExtDb = workCenterExtRepository.getById(workCenterExt.getId());
        if (workCenterExtDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("区域代码为[%s]，生产线代码为[%s]的记录不存在", workCenterExt.getAreaCode(), workCenterExt.getWorkCenterCode())
                    .build();
        }

        workCenterExtDb.setWorkCenterName(workCenterExt.getWorkCenterName());
        workCenterExtDb.setErpWorkCenter(workCenterExt.getErpWorkCenter());
        workCenterExtDb.setWorkVer(workCenterExt.getWorkVer());
        workCenterExtDb.setProductionCapacity(workCenterExt.getProductionCapacity());
        workCenterExtDb.setGenerateType(workCenterExt.getGenerateType());
        workCenterExtDb.setPlanTakt(workCenterExt.getPlanTakt());
        workCenterExtDb.setMonitorType(workCenterExt.getMonitorType());
        workCenterExtDb.setLineType(workCenterExt.getLineType());
        workCenterExtDb.setIsDont(workCenterExt.getIsDont());
        workCenterExtDb.setDontClass(workCenterExt.getDontClass());
        workCenterExtDb.setNoWorkTarget(workCenterExt.getNoWorkTarget());
        workCenterExtDb.setWorkCenterDesc(workCenterExt.getWorkCenterDesc());
        workCenterExtDb.setPersonnelCost(workCenterExt.getPersonnelCost());
        workCenterExtDb.setCategoryCode(workCenterExt.getCategoryCode());
        workCenterExtDb.setCareerCode(workCenterExt.getCareerCode());
        ConvertBean.serviceModelUpdate(workCenterExtDb, workCenterExt.getModifyUser());
        new ConvertBeanExt(workCenterExtDb).convertBean(workCenterExtDb);
        return workCenterExtRepository.save(workCenterExtDb);
    }

    @Override
    public List<MesWorkCenterExt> queryWorkCenterExtList(String organizeCode) {
        if (StringUtils.isEmpty(organizeCode)) {
            return null;
        }
        return workCenterExtRepository.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 List<MesWorkCenter> queryWorkCenterList(String organizeCode) {
        if (StringUtils.isEmpty(organizeCode)) {
            return null;
        }
        return workCenterRepository.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, MesWorkCenter> queryWorkCenterMap(String organizeCode) {
        List<MesWorkCenter> mesWorkCenters = queryWorkCenterList(organizeCode);
        if (CollectionUtils.isEmpty(mesWorkCenters)) return null;
        return mesWorkCenters.stream().collect(Collectors.toMap(MesWorkCenter::getWorkCenterCode, Function.identity()));
    }

    @Override
    public MesWorkCenterExt getWorkCenterExt(String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null;
        return workCenterExtRepository.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.WORK_CENTER_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode});
    }

    @Override
    public List<String> queryWorkCenterIsDontList(String organizeCode) {
       List<MesWorkCenterExt> workCenterExtList = queryWorkCenterExtList(organizeCode);
       return CollectionUtils.isEmpty(workCenterExtList) ? null :
               (workCenterExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsDont())))
                       .map(MesWorkCenterExt::getIsDont).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
    }

    @Override
    public List<String> queryWorkCenterDontClassList(String organizeCode) {
        List<MesWorkCenterExt> workCenterExtList = queryWorkCenterExtList(organizeCode);
        return CollectionUtils.isEmpty(workCenterExtList) ? null :
                (workCenterExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getDontClass())))
                        .map(MesWorkCenterExt::getDontClass).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
    }

    @Override
    public List<MesWorkCell> queryWorkCellList(String organizeCode) {
        if (StringUtils.isEmpty(organizeCode)) {
            return null;
        }
        return workCellRepository.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 ListPager<MesWorkCell> queryWorkCellByPager(MesWorkCell workCell, Pager pager) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(workCell.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(workCell.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringLikerPack(workCell.getWorkCellCode(), MesExtConstWords.WORK_CELL_CODE, packBean);
        DdlPreparedPack.getStringLikerPack(workCell.getWorkCellName(), MesExtConstWords.WORK_CELL_NAME, packBean);
        pager = PagerHelper.getPager(pager, workCellRepository.findByHqlWhereCount(packBean));
        return new ListPager(workCellRepository.findByHqlWherePage(packBean, pager), pager);
    }

    @Override
    public Map<String, String> getCareerPersonnelCostMap(String organizeCode) {
        List<MesWorkCenterExt> workCenterExtList = queryWorkCenterExtList(organizeCode);
        Map<String, List<MesWorkCenterExt>> careerMap = CollectionUtils.isEmpty(workCenterExtList) ? null :
                workCenterExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getCareerCode()) && !StringUtils.isEmpty(o.getPersonnelCost()))).collect(Collectors.groupingBy(MesWorkCenterExt::getCareerCode));
        if (CollectionUtils.isEmpty(careerMap)) return null;
        Map<String, String> careerPersonnelCostMap = new HashMap<>();
        for (Map.Entry<String, List<MesWorkCenterExt>> entry : careerMap.entrySet()) {
            if (null == entry) continue;
            careerPersonnelCostMap.put(entry.getKey(), getCareerPersonnelCost(entry.getValue()));
        }
        return careerPersonnelCostMap;
    }

    private String getCareerPersonnelCost(List<MesWorkCenterExt> workCenterExtList) {
        workCenterExtList = workCenterExtList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesWorkCenterExt::getModifyDatetime).reversed()).collect(Collectors.toList());
        return workCenterExtList.get(0).getPersonnelCost();
    }
}
