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

import cn.estsh.i3plus.ext.mes.api.base.IExteriorScratchProofCellService;
import cn.estsh.i3plus.ext.mes.api.base.IFileManageService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.IExteriorScratchProofCellDao;
import cn.estsh.i3plus.ext.mes.pojo.bean.MesExteriorScratchProofCell;
import cn.estsh.i3plus.ext.mes.pojo.model.MesExteriorScratchProofCellModel;
import cn.estsh.i3plus.ext.mes.pojo.model.SxBatchUploadFileModel;
import cn.estsh.i3plus.ext.mes.pojo.repository.MesExteriorScratchProofCellRepository;
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.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.HqlPack;
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.auth.AuthUtil;
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;

@Slf4j
@Service
public class ExteriorScratchProofCellService implements IExteriorScratchProofCellService {
    @Autowired
    private IFileManageService fileManageService;
    @Autowired
    private MesFileRepository fileRepository;
    @Autowired
    private MesExteriorScratchProofCellRepository exteriorScratchProofCellRDao;
    @Autowired
    private IExteriorScratchProofCellDao exteriorScratchProofCellDao;

    @Override
    public ListPager<MesExteriorScratchProofCellModel> queryMesExteriorScratchProofCellByPager(MesExteriorScratchProofCell exteriorScratchProofCell, Pager pager) {
        pager = PagerHelper.getPager(pager, exteriorScratchProofCellDao.queryExteriorScratchProofCellByPagerCount(exteriorScratchProofCell));
        List<MesExteriorScratchProofCellModel> exteriorScratchProofDetailList = exteriorScratchProofCellDao.queryExteriorScratchProofCellByPager(exteriorScratchProofCell, pager);
        return new ListPager(exteriorScratchProofDetailList, pager);
    }

    @Override
    public MesExteriorScratchProofCell insertMesExteriorScratchProofCell(MultipartFile file, MesExteriorScratchProofCell exteriorScratchProofCell) {
        //唯一性校验
        MesExteriorScratchProofCell exteriorScratchProofCellDb = exteriorScratchProofCellRDao.getByProperty(
                new String[]{MesExtConstWords.WORK_CENTER_CODE, MesExtConstWords.WORK_CELL_CODE, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED},
                new Object[]{exteriorScratchProofCell.getWorkCenterCode(), exteriorScratchProofCell.getWorkCellCode(), exteriorScratchProofCell.getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()});
        if (null != exteriorScratchProofCellDb) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("产线【%s】、工位【%s】的记录已存在,请更换参数", exteriorScratchProofCell.getWorkCenterCode(), exteriorScratchProofCell.getWorkCellCode())
                    .build();
        }

        if (file != null) {
            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(exteriorScratchProofCell.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, exteriorScratchProofCell.getCreateUser());

            exteriorScratchProofCell.setFileId(fileRepository.insert(f).getId());
            exteriorScratchProofCell.setFileOriginName(file.getOriginalFilename());
            exteriorScratchProofCell.setUploadDatetime(exteriorScratchProofCell.getCreateDatetime());
        }
        return exteriorScratchProofCellRDao.insert(exteriorScratchProofCell);
    }

    @Override
    public MesExteriorScratchProofCell updateMesExteriorScratchProofCell(MultipartFile file, MesExteriorScratchProofCell exteriorScratchProofCell) {
        MesExteriorScratchProofCell exteriorScratchProofCellDb = exteriorScratchProofCellRDao.getById(exteriorScratchProofCell.getId());
        if (exteriorScratchProofCellDb == null) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                    .setErrorDetail("该条记录不存在")
                    .build();
        }

        if (file != null) {
            SysFile sysFile = fileManageService.uploadFile(file);
            MesFile f = new MesFile();
            f.setOrganizeCode(exteriorScratchProofCell.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, exteriorScratchProofCell.getModifyUser());

            exteriorScratchProofCellDb.setFileId(fileRepository.insert(f).getId());
            exteriorScratchProofCellDb.setFileOriginName(sysFile.getFileOriginalName());
            exteriorScratchProofCellDb.setUploadDatetime(f.getCreateDatetime());
        }

        exteriorScratchProofCellDb.setWorkCenterCode(exteriorScratchProofCell.getWorkCenterCode());
        exteriorScratchProofCellDb.setWorkCellCode(exteriorScratchProofCell.getWorkCellCode());
        ConvertBean.serviceModelUpdate(exteriorScratchProofCellDb, exteriorScratchProofCell.getModifyUser());
        return exteriorScratchProofCellRDao.save(exteriorScratchProofCellDb);
    }

    @Override
    public int updateMesExteriorScratchProofCellStatusById(Long id, int status, String userName) {
        return exteriorScratchProofCellRDao.updateByProperties(new String[]{MesExtConstWords.ID}, new Object[]{id},
                new String[]{MesExtConstWords.IS_VALID, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME},
                new Object[]{status, userName, TimeTool.getNowTime(true)});
    }

    @Override
    public int updateMesExteriorScratchProofCellValidByIds(String[] ids, Integer status) {
        StringBuffer wheres = new StringBuffer();
        HqlPack.getInPack(String.join(",", ids), "id", wheres);

        int num = exteriorScratchProofCellRDao.updateByHqlWhere(
                wheres.toString(),
                new String[]{MesExtConstWords.IS_VALID, MesExtConstWords.MODIFY_USER, MesExtConstWords.MODIFY_DATE_TIME},
                new Object[]{status, AuthUtil.getSessionUser().getUserName(), TimeTool.getNowTime(true)}
        );
        return num;
    }

    @Override
    public SxBatchUploadFileModel doBatchUploadExteriorScratchProofCellFile(MultipartFile[] files, String lotNo, String organizeCode, String userName) {
        List<MesExteriorScratchProofCell> exteriorScratchProofCellList = exteriorScratchProofCellRDao.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(exteriorScratchProofCellList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("未查询到关联导入批次号[%s]的外观防划伤工位信息", lotNo)
                    .build();
        }
        Map<String, List<MesExteriorScratchProofCell>> fileNameMap = exteriorScratchProofCellList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getFileOriginName())))
                .collect(Collectors.groupingBy(MesExteriorScratchProofCell::getFileOriginName));
        if (CollectionUtils.isEmpty(fileNameMap)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("关联导入批次号[%s]的外观防划伤工位信息均未维护文件名称", 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 (MesExteriorScratchProofCell exteriorScratchProofCell : fileNameMap.get(file.getOriginalFilename())) {
                if (null == exteriorScratchProofCell) {
                    continue;
                }
                exteriorScratchProofCell.setFileId(fileId);
                exteriorScratchProofCell.setUploadDatetime(f.getCreateDatetime());
                ConvertBean.serviceModelUpdate(exteriorScratchProofCell, userName);
                exteriorScratchProofCellRDao.save(exteriorScratchProofCell);
            }
            successCount ++;
        }
        if (successCount.compareTo(0) == 0) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("关联导入批次号[%s]的外观防划伤工位信息的文件名称均未与此次批量上传的文件匹配", lotNo)
                    .build();
        }

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