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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IEsopExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IFileManageService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.IEsopExtDao;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.EsopExtModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.WorkOrderEsopReadModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.ConvertBeanExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
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.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.pojo.mes.bean.MesFile;
import cn.estsh.i3plus.pojo.mes.bean.MesProcess;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
import cn.estsh.i3plus.pojo.mes.repository.MesFileRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesProcessRepository;
import cn.estsh.i3plus.pojo.platform.bean.SysFile;
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 org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

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

    @Autowired
    private IEsopExtDao esopExtDao;

    @Autowired
    private IFileManageService fileManageService;

    @Autowired
    private MesFileRepository fileRepository;

    @Autowired
    private MesEsopExtRepository esopExtRepository;

    @Autowired
    private MesEsopReadRecordRepository esopReadRecordRepository;

    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;

    @Autowired
    private MesProcessCellRepository processCellRepository;

    @Autowired
    private MesProcessRepository processRepository;

    @Autowired
    private IConfigService configService;

    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;

    @Override
    public ListPager<EsopExtModel> queryEsopByPager(MesEsopExt esopExt, Pager pager) {
        pager = PagerHelper.getPager(pager, esopExtDao.queryEsopByPagerCount(esopExt));
        List<EsopExtModel> esopExtList = esopExtDao.queryEsopByPager(esopExt , pager);
        return new ListPager(esopExtList, pager);
    }

    @Override
    public void insertEsop(MultipartFile file, MesEsopExt esopExt) {
        if (!StringUtils.isEmpty(esopExt.getWorkCenterCode()) || !StringUtils.isEmpty(esopExt.getWorkCellCode())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("新增工单SOP入参错误")
                    .build();
        }

        SysFile sysFile = fileManageService.uploadFile(file, esopExt.getOrganizeCode());
        if (null == sysFile) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("新增工单SOP上传文件失败")
                    .build();
        }

        MesFile f = new MesFile();
        f.setOrganizeCode(esopExt.getOrganizeCode());
        f.setFileName(sysFile.getDfsFileName());
        f.setFileUrl(sysFile.getFilePath());
        f.setFileSize(String.valueOf(sysFile.getFileSize()));
        f.setFileType(String.valueOf(sysFile.getFileTypeName()));
        f.setFileOriginName(sysFile.getFileOriginalName());
        f.setGroupName(sysFile.getDfsGroupName());
        f.setSyncTag(0);
        ConvertBean.serviceModelInitialize(esopExt, esopExt.getModifyUser());
        ConvertBean.serviceModelInitialize(f, esopExt.getModifyUser());
        esopExt.setFileId(fileRepository.insert(f).getId());
        esopExt.setFileOriginName(file.getOriginalFilename());
        esopExt.setUploadDatetime(esopExt.getCreateDatetime());
        new ConvertBeanExt(esopExt).convertBean(esopExt);
        esopExtRepository.insert(esopExt);
    }

    @Override
    public void updateEsop(MultipartFile file, MesEsopExt esopExt) {
        MesEsopExt esopExtDb = esopExtRepository.getById(esopExt.getId());
        if (esopExtDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("未查到有效记录")
                    .build();
        }

        if (file == null && StringUtils.isEmpty(esopExtDb.getFileId())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("上传的文件为null，后台未能接收到")
                    .build();
        }

        //改变文件时清除fileUrl
        if (StringUtils.isEmpty(esopExt.getFileUrl())) {
            SysFile sysFile = fileManageService.uploadFile(file, esopExt.getOrganizeCode());
            MesFile f = new MesFile();
            f.setOrganizeCode(esopExt.getOrganizeCode());
            f.setFileName(sysFile.getDfsFileName());
            f.setFileUrl(sysFile.getFilePath());
            f.setFileSize(String.valueOf(sysFile.getFileSize()));
            f.setFileType(String.valueOf(sysFile.getFileTypeName()));
            f.setFileOriginName(sysFile.getFileOriginalName());
            f.setGroupName(sysFile.getDfsGroupName());
            f.setSyncTag(0);
            ConvertBean.serviceModelInitialize(f, esopExt.getModifyUser());
            esopExtDb.setFileId(fileRepository.insert(f).getId());
            esopExtDb.setFileOriginName(file.getOriginalFilename());
            esopExtDb.setUploadDatetime(f.getCreateDatetime());
        }
        esopExtDb.setBcSeq(esopExt.getBcSeq());
        esopExtDb.setBcTimes(esopExt.getBcTimes());
        ConvertBean.serviceModelUpdate(esopExtDb, esopExt.getModifyUser());
        new ConvertBeanExt(esopExtDb).convertBean(esopExtDb);
        esopExtRepository.save(esopExtDb);
    }

    @Override
    public void deleteEsopById(Long id, String modifyUser) {
        MesEsopExt esopExtDb = esopExtRepository.getById(id);
        if (null == esopExtDb || esopExtDb.getIsDeleted() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) return;
        esopExtDb.setIsDeleted(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
        ConvertBean.serviceModelUpdate(esopExtDb, modifyUser);
        new ConvertBeanExt(esopExtDb).convertBean(esopExtDb);
        esopExtRepository.save(esopExtDb);
    }

    @Override
    public WorkOrderEsopReadModel queryBcEsop(MesWorkCell workCell) {
        WorkOrderEsopReadModel workOrderEsopReadModel = new WorkOrderEsopReadModel();
        workOrderEsopReadModel.setWorkCenterCode(workCell.getWorkCenterCode());
        workOrderEsopReadModel.setWorkCellCode(workCell.getWorkCellCode());

        //根据生产线 工位 查询 工序工位信息MES_PROCESS_CELL获取工序代码
        MesProcessCell processCellDb = getProcessCell(workCell);
        if (null != processCellDb) {
            MesProcess processDb = getProcess(workCell.getOrganizeCode(), processCellDb.getProcessCode());
            if (null != processDb) {
                workOrderEsopReadModel.setProcessCode(processDb.getProcessCode());
                workOrderEsopReadModel.setProcessName(processDb.getProcessName());
            }
        }

        //选择区域、产线,获取当前产线中状态为启动状态SEQ最小的工单
        MesWorkOrderExt workOrderExt = getFirstOpenWorkOrderByCenter(workCell);
        if (null == workOrderExt) {
            return workOrderEsopReadModel;
        }

        workOrderEsopReadModel.setWorkOrderNo(workOrderExt.getOrderNo());
        workOrderEsopReadModel.setPartNo(workOrderExt.getPartNo());
        workOrderEsopReadModel.setPartName(workOrderExt.getPartNameRdd());

        List<MesEsopExt> sopList;
        if (null == processCellDb) {
            sopList = getSopListByCenterAndCell(workCell);
        } else {
            sopList = getSopList(workOrderExt.getOrderNo(), workOrderExt.getPartNo(), processCellDb.getProcessCode(), workCell);
        }
        if (!CollectionUtils.isEmpty(sopList)) {
            workOrderEsopReadModel.setEsopExtList(packSopListByFile(sopList, workCell.getOrganizeCode()));
        }
        return workOrderEsopReadModel;
    }

    private MesWorkOrderExt getFirstOpenWorkOrderByCenter(MesWorkCell workCell) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(workCell.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(workCell.getAreaCode(), MesPcnExtConstWords.AREA_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(workCell.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue(), MesPcnExtConstWords.WORK_ORDER_STATUS, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.SEQ}, packBean);
        return workOrderExtRepository.getByProperty(packBean);
    }

    private MesProcess getProcess(String organizeCode, String processCode) {
        return processRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.PROCESS_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), processCode});
    }

    private MesProcessCell getProcessCell(MesWorkCell workCell) {
        return processCellRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID,
                        MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE},
                new Object[]{workCell.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        workCell.getWorkCenterCode(), workCell.getWorkCellCode()});
    }

    private List<MesEsopExt> packSopListByFile(List<MesEsopExt> sopList, String organizeCode) {
        List<MesEsopExt> result = null;
        MesConfig config = configService.getMesConfigByCfgCode(MesPcnEnumUtil.CONFIG_TYPE.FASTDFS_SAVE_PATH.getCode(), organizeCode);
        for (MesEsopExt esopExt : sopList) {
            if (null == esopExt || StringUtils.isEmpty(esopExt.getFileId())) {
                continue;
            }
            MesFile fileDb = fileRepository.getById(esopExt.getFileId());
            if (null == fileDb || (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == fileDb.getIsDeleted() || CommonEnumUtil.IS_VAILD.INVAILD.getValue() == fileDb.getIsValid())) {
                continue;
            }
            if (StringUtils.isEmpty(fileDb.getFileUrl()) || StringUtils.isEmpty(fileDb.getGroupName()) || StringUtils.isEmpty(fileDb.getFileName())) {
                continue;
            }

            String fileUrl = fileManageService.getFileUrl(config, fileDb);
            if (StringUtils.isEmpty(fileUrl)) {
                continue;
            }

            esopExt.setFileUrl(fileUrl);
            esopExt.setFileName(fileDb.getFileName());
            esopExt.setFileOriginName(fileDb.getFileOriginName());
            esopExt.setFileSize(fileDb.getFileSize());
            esopExt.setFileType(fileDb.getFileType());
            esopExt.setGroupName(fileDb.getGroupName());

            if (CollectionUtils.isEmpty(result)) {
                result = new ArrayList<>();
            }

            result.add(esopExt);
        }

        return result;
    }



    private List<MesEsopExt> getSopList(String workOrderNo, String partNo, String processCode, MesWorkCell workCell) {
        List<MesEsopExt> sopList = getSopListIsByOrderNo(workCell.getOrganizeCode(), partNo, processCode, workOrderNo);
        if (!CollectionUtils.isEmpty(sopList)) {
            return sopList;
        }
        sopList = getSopListIsByOrderNo(workCell.getOrganizeCode(), partNo, processCode, null);
        if (!CollectionUtils.isEmpty(sopList)) {
            return sopList;
        }
        return getSopListByCenterAndCell(workCell);
    }

    private List<MesEsopExt> getSopListIsByOrderNo(String organizeCode, String partNo, String processCode, String workOrderNo) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (!StringUtils.isEmpty(workOrderNo)) {
            DdlPreparedPack.getStringEqualPack(workOrderNo, MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        }
        DdlPreparedPack.getStringEqualPack(partNo, MesPcnExtConstWords.PART_NO, packBean);
        DdlPreparedPack.getStringEqualPack(processCode, MesPcnExtConstWords.PROCESS_CODE, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.BC_SEQ}, packBean);
        return esopExtRepository.findByHqlWhere(packBean);
    }

    private List<MesEsopExt> getSopListByCenterAndCell(MesWorkCell workCell) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(workCell.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(workCell.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(workCell.getWorkCellCode(), MesPcnExtConstWords.WORK_CELL_CODE, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.BC_SEQ}, packBean);
        return esopExtRepository.findByHqlWhere(packBean);
    }

    @Override
    public Boolean checkIsExistEsopReadRecord(MesEsopExt esopExt) {
        MesEsopReadRecord esopReadRecord = esopReadRecordRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID,
                        MesPcnExtConstWords.WORK_ORDER_NO, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE, MesPcnExtConstWords.PROCESS_CODE},
                new Object[]{esopExt.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        esopExt.getWorkOrderNo(), esopExt.getWorkCenterCode(), esopExt.getWorkCellCode(), esopExt.getProcessCode()});
        return null != esopReadRecord ? true : false;
    }

    @Override
    public void insertEsopReadRecord(MesEsopReadRecord esopReadRecord) {
        MesWorkCenterExt workCenterExt = workCenterExtRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE},
                new Object[]{esopReadRecord.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), esopReadRecord.getWorkCenterCode()});
        if (null == workCenterExt) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("生产线代码[%s]无效", esopReadRecord.getWorkCenterCode())
                    .build();
        }
        esopReadRecord.setShiftCode(workCenterExt.getShiftCode());
        ConvertBean.serviceModelInitialize(esopReadRecord, esopReadRecord.getModifyUser());
        esopReadRecordRepository.insert(esopReadRecord);
    }
}
