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

import cn.estsh.i3plus.ext.mes.api.busi.IProcedureOnSiteService;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesPartExt;
import cn.estsh.i3plus.ext.mes.pojo.model.SxDefectModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesPartExtRepository;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.mes.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.*;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description :
 * @Reference :
 * @Author : dominic
 * @CreateDate : 2022/5/26 16:30
 * @Modify:
 **/
@Service
public class ProcedureOnSiteService implements IProcedureOnSiteService {

    @Autowired
    private MesAreaRepository areaRepository;

    @Autowired
    private MesWorkCenterRepository workCenterRepository;

    @Autowired
    private MesWorkOrderRepository workOrderRepository;

    @Autowired
    private MesPartExtRepository partExtRepository;

    @Autowired
    private MesDefectRepository defectRepository;

    @Autowired
    private MesTypeCfgRepository typeCfgRepository;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Override
    public List<MesArea> findArea(String organizeCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        return areaRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<MesWorkCenter> findWorkCenter(String organizeCode, String areaCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(areaCode, "areaCode", packBean);
        return workCenterRepository.findByHqlWhere(packBean);
    }

    @Override
    public List<MesWorkOrder> findWorkOrderByStatus(String organizeCode, String workCenterCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", packBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue(), "workOrderStatus", packBean);
        return workOrderRepository.findByHqlWhere(packBean);
    }

    @Override
    public String getPartName(String organizeCode, String partNo) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(partNo)) {
            return null;
        }
        MesPartExt partExt = partExtRepository.getByProperty(
                new String[]{"organizeCode", "isDeleted", "isValid", "partNo"},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), partNo});
        if (null != partExt) {
            return partExt.getPartName();
        }
        if (partNo.contains("-") || partNo.contains(")") || partNo.contains("(")) {
            DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getStringLikerPack(partNo, "partNo", packBean);
            List<MesPartExt> partExtList = partExtRepository.findByHqlWhere(packBean);
            if (!CollectionUtils.isEmpty(partExtList)) {
                if (partExtList.size() == 1) {
                    return partExtList.get(0).getPartName();
                } else {
                    Optional<MesPartExt> partExtOp = partExtList.stream().filter(o -> (null != o && o.getPartNo().length() == partNo.length())).findFirst();
                    if (null != partExtOp && partExtOp.isPresent()) {
                        return partExtOp.get().getPartName();
                    }
                }
            }
        }
        return null;
    }

    @Override
    public List<SxDefectModel> queryMesDefectByPager(String organizeCode) {
        List<SxDefectModel> resultList = new ArrayList<>();

        DdlPackBean hqlPack = DdlPackBean.getDdlPackBean(organizeCode);
        List<MesDefect> defectList = defectRepository.findByHqlWhere(hqlPack);
        List<MesTypeCfg> typeCfgList = typeCfgRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, "typeCode"},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(),
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(), MesExtEnumUtil.MES_TYPE_CFG_EXT.BAD.getValue()});
        Map<String, List<MesTypeCfg>> typeCfgMap = CollectionUtils.isEmpty(typeCfgList) ? null :
                typeCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getTypeCode()))).collect(Collectors.groupingBy(MesTypeCfg::getBusinessTypeCode));
        if (!CollectionUtils.isEmpty(defectList)) {
            for (MesDefect defectDb : defectList) {
                if (null != defectDb) {
                    SxDefectModel result = new SxDefectModel();
                    BeanUtils.copyProperties(defectDb, result);
                    List<MesTypeCfg> typeCfgs = CollectionUtils.isEmpty(typeCfgMap) ? null : typeCfgMap.get(defectDb.getDefectType());
                    result.setDefectTypeName(CollectionUtils.isEmpty(typeCfgs) ? null : typeCfgs.get(0).getBusinessTypeName());
                    resultList.add(result);
                }
            }
        }
        return resultList;
    }

    @Override
    public String generateSerialNumber(String organizeCode, String userName, String ruleCode) {
        GenSerialNoModel genSerialNoModel = new GenSerialNoModel();
        genSerialNoModel.setRuleCode(ruleCode);
        BaseResultBean<String> serialNumberBean = syncFuncService.syncSerialNo(genSerialNoModel, userName, organizeCode, 1);
        if (serialNumberBean != null && serialNumberBean.isSuccess()) {
            return serialNumberBean.getResultList().get(0);
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.QMS.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                    .setErrorDetail("单号未生成成功")
                    .build();
        }
    }
}
