package com.jeeplus.modules.supply.projectInformation.service;

import com.google.common.collect.Lists;
import com.jeeplus.common.config.Global;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.core.persistence.Page;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.modules.supply.materialLibrary.service.MaterialLibraryService;
import com.jeeplus.modules.supply.projectInformation.entity.ProjectInformation;
import com.jeeplus.modules.supply.projectInformation.mapper.ProjectInformationMapper;
import com.jeeplus.modules.supply.stockOut.entity.SupplyStockOut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 项目信息Service
 * @author: 黄俊杰
 * @create: 2022-02-28 16:00
 */
@Service
@Transactional(readOnly = true)
public class ProjectInformationService extends CrudService<ProjectInformationMapper, ProjectInformation> {

    /** 主机 */
    private final static String host = Global.getConfig("remoteServer.host");
    private static Logger logger = LoggerFactory.getLogger(MaterialLibraryService.class);

    @Autowired
    private ProjectInformationMapper projectInformationMapper;


    //页面显示
    @Override
    public Page<ProjectInformation> findPage(Page<ProjectInformation> page, ProjectInformation projectInformation){
        return super.findPage(page,projectInformation);
    }

    /**
     * 数据验证
     * @param file
     * @return
     * @throws Exception
     */
    public LinkedHashMap dataVerification(MultipartFile file) throws Exception{
        LinkedHashMap returnMap = new LinkedHashMap();
        //查询项目数据量
        Integer projectCount= projectInformationMapper.getProjectCount();
        if(projectCount>0){
            File multipartFile = transformMultipartFile(file);
            try{
                //将文件存到服务器
                String filePath = saveFile(multipartFile);
                returnMap.keySet().removeIf(key -> key == "repeat");
                returnMap.put("repeat","3");
                returnMap.put("success",true);
                returnMap.put("filePath",filePath);
                returnMap.keySet().removeIf(key -> key == "msg");
                returnMap.put("msg","已存在项目数据，是否覆盖？");
            }catch (Exception e){
                e.getMessage();
            }finally {
                multipartFile.delete();
            }
        }else{
            returnMap.put("success",false);
        }
        return returnMap;
    }

    /**
     * 项目信息导入处理
     * @param list
     * @return
     */
    @Transactional(readOnly = false)
    public LinkedHashMap disposeImportProjectInformation(List<ProjectInformation> list, MultipartFile file, String repeat) throws Exception{
        LinkedHashMap returnMap = new LinkedHashMap();
        Integer index = 2;
        Iterator<ProjectInformation> its = list.iterator();
        Set<String> submissionFormIdSet = new HashSet<>();
        while(its.hasNext()){
            index ++ ;
            ProjectInformation info = its.next();
            if(StringUtils.isBlank(info.getSubmissionFormId())){
                returnMap.put("success",false);
                returnMap.put("msg","第" + index + "行，存在审定单id为空的数据，请确认后重新提交！");
                return returnMap;
            }else if(StringUtils.isBlank(info.getProjectDefinitionNumber())){
                returnMap.put("success",false);
                returnMap.put("msg","第" + index + "行，存在项目定义号为空的数据，请确认后重新提交！");
                return returnMap;
            }
            //将审定单id放入set中
            submissionFormIdSet.add(info.getSubmissionFormId());
        }

        //将去重后的set转换为list  方便比较
        List<String> submissionFormIdList = new ArrayList<>(submissionFormIdSet);

        //判断审定单idlist长度和导入数据的list长度是否一样，不一样则说明导入数据中项目名存在重复数据
        if(submissionFormIdList.size() != list.size()){
            returnMap.keySet().removeIf(key -> key == "msg");
            returnMap.put("success",false);
            returnMap.put("msg","存在审定单id重复的数据，请确认后重新提交!");
        }


        //将项目信息的内容去重  遍历
        List<ProjectInformation> projectInformationList = groupDistinctProjectInformation(list);

        if(repeat.equals("1")){  //覆盖 则删除数据库中的重复数据
            if(list.size()>0){
                //提前保存读取的list的长度
                int size = list.size();
                //删除项目数据
                projectInformationMapper.deleteAllProject();
                //删除工程信息
                projectInformationMapper.deleteAllSubmissionForm();

                //批量新增  分批次新增
                modifyHandmadeVindicateList(list);
                modifyHandmadeVindicateList2(projectInformationList);

                returnMap.keySet().removeIf(key -> key == "msg");
                returnMap.put("success",true);
                returnMap.put("msg","已成功导入 "+size+" 条项目信息记录");
            }
            returnMap.keySet().removeIf(key -> key == "msg");
            returnMap.put("success",false);
            returnMap.put("msg","导入表数据量为0条，不进行替换");
        }

        return returnMap;
    }

    /**
     * 根据项目定义号对项目信息进行去重
     * @param projectInformationList
     * @return
     */
    public List<ProjectInformation> groupDistinctProjectInformation (List<ProjectInformation> projectInformationList){
        List<ProjectInformation> list = Lists.newArrayList();
        Map<String, ProjectInformation> map = new HashMap<>();
        for(ProjectInformation project : projectInformationList){
            if(!map.containsKey(project.getProjectDefinitionNumber())){//map中不存在此id，将数据存放当前key的map中
                map.put(project.getProjectDefinitionNumber(), project);
                list.add(project);
            }
        }
        return list;
    }

    /**
     * 批量新增审定单信息表数据
     * @param projectBasicsList
     * @return
     */
    @Transactional(readOnly = false)
    public String modifyHandmadeVindicateList(List<ProjectInformation> projectBasicsList){
        //分批处理
        if(null!=projectBasicsList && projectBasicsList.size()>0){
            int pointsDataLimit = 5000;//限制条数
            Integer size = projectBasicsList.size();
            //判断是否有必要分批
            if(pointsDataLimit<size){
                int part = size/pointsDataLimit;//分批数
                //
                for (int i = 0; i < part; i++) {
                    //100条
                    List<ProjectInformation> listPage = projectBasicsList.subList(0, pointsDataLimit);
                    for(ProjectInformation info:listPage){
                        info.preInsert();
                    }
                    projectInformationMapper.insertSubmissionFormList(listPage);
                    //剔除
                    projectBasicsList.subList(0, pointsDataLimit).clear();
                }
                if(!projectBasicsList.isEmpty()){
                    for(ProjectInformation info:projectBasicsList){
                        info.preInsert();
                    }
                    projectInformationMapper.insertSubmissionFormList(projectBasicsList);
                }
            }else{
                for(ProjectInformation info:projectBasicsList){
                    info.preInsert();
                }
                projectInformationMapper.insertSubmissionFormList(projectBasicsList);
            }
        }
        return null;
    }

    /**
     * 批量项目信息表数据
     * @param projectBasicsList
     * @return
     */
    @Transactional(readOnly = false)
    public String modifyHandmadeVindicateList2(List<ProjectInformation> projectBasicsList){
        //分批处理
        if(null!=projectBasicsList && projectBasicsList.size()>0){
            int pointsDataLimit = 5000;//限制条数
            Integer size = projectBasicsList.size();
            //判断是否有必要分批
            if(pointsDataLimit<size){
                int part = size/pointsDataLimit;//分批数
                //
                for (int i = 0; i < part; i++) {
                    //100条
                    List<ProjectInformation> listPage = projectBasicsList.subList(0, pointsDataLimit);
                    for(ProjectInformation info:listPage){
                        info.preInsert();
                    }
                    projectInformationMapper.insertProjectInformationList(listPage);
                    //剔除
                    projectBasicsList.subList(0, pointsDataLimit).clear();
                }
                if(!projectBasicsList.isEmpty()){
                    for(ProjectInformation info:projectBasicsList){
                        info.preInsert();
                    }
                    projectInformationMapper.insertProjectInformationList(projectBasicsList);
                }
            }else{
                for(ProjectInformation info:projectBasicsList){
                    info.preInsert();
                }
                projectInformationMapper.insertProjectInformationList(projectBasicsList);
            }
        }
        return null;
    }

    /**
     * 批量删除（项目信息表+审定单信息表）
     * @param projectBasicsList
     * @return
     */
    @Transactional(readOnly = false)
    public String modifyHandmadeVindicateListTwo(List<String> projectBasicsList){
        //分批处理
        if(null!=projectBasicsList && projectBasicsList.size()>0){
            int pointsDataLimit = 5000;//限制条数
            Integer size = projectBasicsList.size();
            //判断是否有必要分批
            if(pointsDataLimit<size){
                int part = size/pointsDataLimit;//分批数
                //
                for (int i = 0; i < part; i++) {
                    //100条
                    List<String> listPage = projectBasicsList.subList(0, pointsDataLimit);
                    projectInformationMapper.deleteAllByCodList(listPage);
                    //剔除
                    projectBasicsList.subList(0, pointsDataLimit).clear();
                }
                if(!projectBasicsList.isEmpty()){
                    projectInformationMapper.deleteAllByCodList(projectBasicsList);
                }
            }else{
                projectInformationMapper.deleteAllByCodList(projectBasicsList);
            }
        }
        return null;
    }

    /**
     * 文件的操作
     * @param file
     * @return
     */
    public String saveFile(File file){
        String filePath = "";//最终文件存放路径
        try {
            if(StringUtils.isNotBlank(host) && ("127.0.0.1".equals(host) || "localhost".equals(host))){
                String path = null;
                if(System.getProperty("os.name").toLowerCase().contains("win")){
                    path = Global.getConfig("remoteServer.winDirectory");
                }else{
                    path = Global.getConfig("remoteServer.directory");
                }
                Calendar date = Calendar.getInstance();
                date.add(Calendar.DAY_OF_MONTH,0);
                String nowTime = new SimpleDateFormat("yyyy_MM_dd").format(date.getTime());
                String uploadPath = "/"+nowTime+System.currentTimeMillis();
                //检查该路径对应的目录是否存在. 如果不存在则创建目录
                File dir=new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                filePath = path  + uploadPath + file.getName();  //存到服务武器的路径名
                //File转MultipartFile文件
                MultipartFile multipartFile = transformFile(file);
                //保存文件
                File dest = new File(filePath);
                if (!(dest.exists())) {
                    multipartFile.transferTo(dest);
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            logger.error("Exception e:"+e);
        }
        return filePath;
    }

    /**
     * 文件的删除操作
     * @param file
     * @throws IOException
     */
    public void deleteFileContent(File file) throws IOException {
        String filePath = file.getAbsolutePath();
        File deleteFile = new File(filePath);
        if(deleteFile.exists()){
            deleteFile.delete();
        }
    }

    /**
     * MultipartFile转File
     * @param file
     * @return
     * @throws IOException
     */
    public File transformMultipartFile( MultipartFile file) throws IOException {
        File srcFile = null;
        //MultipartFile转File
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            srcFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, srcFile);
            ins.close();
        }
        return srcFile;
    }

    /**
     * 获取流文件
     * @param ins
     * @param file
     */
    public void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * File转MultipartFile
     * @param file
     * @return
     */
    public MultipartFile transformFile(File file){
        InputStream inputStream = null;
        MultipartFile multipartFile = null;
        try {
            inputStream = new FileInputStream(file);
            multipartFile = new MockMultipartFile(file.getName(), inputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return multipartFile;
    }

    /**
     * 查询审定单信息表中项目定义号的count
     * @param projectInformation
     * @return
     */
    @Transactional(readOnly = false)
    public int getProjectDefinitionNumberCountBySubmissionId(ProjectInformation projectInformation){
        int count = projectInformationMapper.getProjectDefinitionNumberCountBySubmissionId(projectInformation);
        return count;
    }

    //关联删除项目信息表和审定单信息表
    @Transactional(readOnly = false)
    public void deleteAllById(ProjectInformation projectInformation){
        projectInformationMapper.deleteAllById(projectInformation);
    }
}
