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

import cn.estsh.i3plus.ext.mes.api.base.IEsopExtService;
import cn.estsh.i3plus.ext.mes.api.base.IFileManageService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.IEsopExtDao;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesEsopExt;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesEsopReadRecord;
import cn.estsh.i3plus.ext.mes.pojo.model.EsopExtModel;
import cn.estsh.i3plus.ext.mes.pojo.model.SxBatchUploadFileModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesEsopExtRepository;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesEsopReadRecordRepository;
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.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.mes.bean.MesFile;
import cn.estsh.i3plus.pojo.mes.repository.MesFileRepository;
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;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @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 MesEsopExtRepository esopExtRepository;

    @Autowired
    private MesFileRepository fileRepository;

    @Autowired
    private MesEsopReadRecordRepository esopReadRecordRepository;

    @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.getPartNo()) && StringUtils.isEmpty(esopExt.getProcessCode()) &&
                StringUtils.isEmpty(esopExt.getWorkCenterCode()) && StringUtils.isEmpty(esopExt.getWorkCellCode())) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("新增SOP缺少入参")
                    .build();
        }
        //物料号+工序 / 生产线代码+工位代码 必填 且 而二选其一
        if ((!StringUtils.isEmpty(esopExt.getPartNo()) && (StringUtils.isEmpty(esopExt.getProcessCode()) || !StringUtils.isEmpty(esopExt.getWorkCenterCode()) || !StringUtils.isEmpty(esopExt.getWorkCellCode()))) ||
                (!StringUtils.isEmpty(esopExt.getProcessCode()) && (StringUtils.isEmpty(esopExt.getPartNo()) || !StringUtils.isEmpty(esopExt.getWorkCenterCode()) || !StringUtils.isEmpty(esopExt.getWorkCellCode()))) ||
                (!StringUtils.isEmpty(esopExt.getWorkCenterCode()) && (StringUtils.isEmpty(esopExt.getWorkCellCode()) || !StringUtils.isEmpty(esopExt.getPartNo()) || !StringUtils.isEmpty(esopExt.getProcessCode()))) ||
                (!StringUtils.isEmpty(esopExt.getWorkCellCode()) && (StringUtils.isEmpty(esopExt.getWorkCenterCode()) || !StringUtils.isEmpty(esopExt.getPartNo()) || !StringUtils.isEmpty(esopExt.getProcessCode())))) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("新增SOP入参错误")
                    .build();
        }

        SysFile sysFile = fileManageService.uploadFile(file);
        if (sysFile.getFileTypeId() == null) {
            log.error("FastDFS上传文件出错：{}", "未在字典中定义该文件类型，无法上传成功，请先添加file_type字典");
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail("未在字典中定义该文件类型，无法上传成功，请先添加file_type字典")
                    .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(f, esopExt.getCreateUser());
        esopExt.setFileId(fileRepository.insert(f).getId());
        esopExt.setFileOriginName(file.getOriginalFilename());
        ConvertBean.serviceModelInitialize(esopExt, esopExt.getCreateUser());
        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.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("ID[%s]记录不存在", esopExt.getId())
                    .build();
        }

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

        //改变文件时清除fileUrl
        if (StringUtils.isEmpty(esopExt.getFileUrl())) {
            SysFile sysFile = fileManageService.uploadFile(file);
            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 updateBatchEsopValidById(String[] ids, 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();
        }
        for (String id : ids) {
            if (StringUtils.isEmpty(id)) {
                continue;
            }
            esopExtRepository.updateByProperties(new String[]{MesExtConstWords.ID}, new Object[]{Long.parseLong(id)},
                    new String[]{MesExtConstWords.IS_VALID, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME},
                    new Object[]{status, userName, TimeTool.getNowTime(true)});

            MesEsopExt esopExtDb = esopExtRepository.getById(Long.parseLong(id));
            if (null == esopExtDb || esopExtDb.getIsValid() == status) continue;
            esopExtDb.setIsValid(status);
            ConvertBean.serviceModelUpdate(esopExtDb, userName);
            new ConvertBeanExt(esopExtDb).convertBean(esopExtDb);
            esopExtRepository.save(esopExtDb);
        }
    }

    @Override
    public ListPager<MesEsopReadRecord> queryEsopReadRecordByPager(MesEsopReadRecord esopReadRecord, Pager pager) {
        DdlPackBean hqlPack = MesExtHqlPack.getEsopReadRecord(esopReadRecord);
        pager = PagerHelper.getPager(pager, esopReadRecordRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(esopReadRecord.orderBy());
        return new ListPager(esopReadRecordRepository.findByHqlWherePage(hqlPack, pager), pager);
    }

    @Override
    public SxBatchUploadFileModel doBatchUploadEsopFile(MultipartFile[] files, String lotNo, String organizeCode, String userName) {
        List<MesEsopExt> esopExtList = esopExtRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.LOT_NO},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), lotNo});
        if (CollectionUtils.isEmpty(esopExtList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("未查询到关联导入批次号[%s]的ESOP信息", lotNo)
                    .build();
        }
        Map<String, List<MesEsopExt>> fileNameMap = esopExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getFileOriginName())))
                .collect(Collectors.groupingBy(MesEsopExt::getFileOriginName));
        if (CollectionUtils.isEmpty(fileNameMap)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("关联导入批次号[%s]的ESOP信息均未维护文件名称", lotNo)
                    .build();
        }
        Integer successCount = 0;
        Integer failureCount = 0;
        List<String> unUploadFileList = null;
        for (MultipartFile file : files) {
            if (null == file) {
                continue;
            }
            if (!fileNameMap.containsKey(file.getOriginalFilename())) {
                if (CollectionUtils.isEmpty(unUploadFileList)) {
                    unUploadFileList = new ArrayList<>();
                }
                unUploadFileList.add(file.getOriginalFilename());
                failureCount ++;
                continue;
            }

            SysFile sysFile = fileManageService.uploadFile(file);
            if (sysFile.getFileTypeId() == null) {
                log.error("FastDFS上传文件出错：{}", "未在字典中定义该文件类型，无法上传成功，请先添加file_type字典");
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                        .setErrorDetail("未在字典中定义该文件类型，无法上传成功，请先添加file_type字典")
                        .build();
            }

            MesFile f = new MesFile();
            f.setOrganizeCode(organizeCode);
            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, userName);
            Long fileId = fileRepository.insert(f).getId();
            for (MesEsopExt esopExt : fileNameMap.get(file.getOriginalFilename())) {
                if (null == esopExt) {
                    continue;
                }
                esopExt.setFileId(fileId);
                esopExt.setUploadDatetime(f.getCreateDatetime());
                ConvertBean.serviceModelUpdate(esopExt, userName);
                new ConvertBeanExt(esopExt).convertBean(esopExt);
                esopExtRepository.save(esopExt);
            }
            successCount ++;
        }
        if (successCount.compareTo(0) == 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("关联导入批次号[%s]的ESOP信息的文件名称均未与此次批量上传的文件匹配", lotNo)
                    .build();
        }

        SxBatchUploadFileModel model = new SxBatchUploadFileModel();
        model.setSuccessCount(successCount);
        model.setFailureCount(failureCount);
        model.setUnUploadFileList(unUploadFileList);
        return model;
    }
}
