package io.renren.modules.dataSet.upload;


import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import io.renren.common.exception.RRException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvMapReader;
import org.supercsv.io.ICsvMapReader;
import org.supercsv.prefs.CsvPreference;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UpLoadService {
    public Map upload(MultipartFile file) throws IOException {
        Map<String, Object> map = new HashMap<>();
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        //获取上传的文件的文件名
        String fileName = file.getOriginalFilename();
        map.put("fileName", fileName);
        //处理文件重名问题
//        String hzName = fileName.substring(fileName.lastIndexOf("."));
//        fileName = UUID.randomUUID().toString() + hzName;
        //获取服务器中photo目录的路径
//        ServletContext servletContext = session.getServletContext();
//        String photoPath = servletContext.getRealPath("file");
        String newfileName = System.getProperty("user.dir") + File.separator + "aupload" + File.separator + fileName;
        File newfile = new File(newfileName);
        file.transferTo(newfile);
        map.put("upUrl", newfileName);

        NoModelDataListener noModelDataListener1 = new NoModelDataListener();
        // 读取全部sheet
        // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
        EasyExcel.read(newfileName, noModelDataListener1).doReadAll();

        // 获取表头
        List<String> headList = noModelDataListener1.getHeadList();
//        final List<String> needList = noModelDataListener1.getNeedList();
        map.put("columns", headList);
        // 获取excel 内容
        List<Map<String, String>> allDataList = noModelDataListener1.getAllDataList();
        map.put("excelData", allDataList);

        return map;
    }

    public List getstaticprecontent(Map map) {
        List<Map<String, Object>> locals = (List<Map<String, Object>>) map.get("loacl");
        List<Map<String, Object>> needLists = new LinkedList<>();
        List<Map<String, Object>> tempLists = new LinkedList<>();

        for (Map<String, Object> local : locals) {
            final String id = local.get("id").toString();
            final String userID = local.get("userID").toString();

            final String[] sqls = local.get("sql").toString().replaceAll("\\[|\\]", "").split(", ");//time, string_title
            String upUrl = local.get("upUrl").toString(); // E:\test\615\renren-fast\aupload\demo 1.xlsx
            String type = local.get("type").toString();
            List<Map<String, Object>> allNeedLists = null;
            if ("excel".equals(type)) {
                NoModelDataListener_pre noModelDataListener_pre = new NoModelDataListener_pre(sqls, id);
                // 读取全部sheet
                // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
                EasyExcel.read(upUrl, noModelDataListener_pre).doReadAll();
                allNeedLists = noModelDataListener_pre.getNeedList();
            } else if ("word".equals(type)) {
                allNeedLists = readWithCsvMapReaderColumns(upUrl,id,sqls,true);
            } else {
                allNeedLists = new ArrayList<>();
            }

            Integer needNumber = 1;
            for (Map<String, Object> allNeedList : allNeedLists) {
                if (needNumber <= 10) {
                    allNeedList.put("id", needNumber);
                    tempLists.add(allNeedList);
                    needNumber++;
                }

            }
            // 利用临时遍历 tempLists 存储每次遍历获取到了数据
            if (needLists.isEmpty()) {
                needLists = tempLists;
            } else {
                needLists.addAll(tempLists);
                needLists = subListMap(needLists);
            }
//            needLists.forEach(System.out::println);
        }

        List<Map<String, Object>> datas = (List<Map<String, Object>>) map.get("data");
        Integer data_i = 1;
        for (Map data : datas) {
            data.put("id", data_i);
            data_i++;
//            System.out.println(data);
        }
        datas.addAll(needLists);
        return subListMap(datas);
    }

    private List subListMap(List<Map<String, Object>> datas) {
        List<Map<String, Object>> combine = datas.stream()
                .collect(Collectors.groupingBy(group -> group.get("id").toString())) // 根据map中id的value值进行分组, 这一步的返回结果Map<String,List<Map<String, Object>>>，目的是将相同id下的value归类到一个value下
                .entrySet() // 得到Set<Map.Entry<String, List<Map<String, Object>>>
                .stream() // 使用Java8的流
                .map(m -> { // 进入映射环境
                    // m.getValue()的结果是 List<Map<String, Object>>
                    Map<String, Object> collect = m.getValue().stream()
                            // 核心重点！o.entrySet() 的结果是 Set<Map.Entry<String, Object>>，通过flatMap将value合并成一个stream
                            .flatMap(o -> o.entrySet().stream())
                            // (m1, m2) -> m2 的意思是如果 m1 == m2 则使用m2
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (m1, m2) -> m2));
                    return collect;
                }).collect(Collectors.toList());
        return combine;
    }

    public Map uploadCSV(MultipartFile file) throws Exception {
        Map<String, Object> map = new HashMap<>();


        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        //获取上传的文件的文件名
        String fileName = file.getOriginalFilename();
        map.put("fileName", fileName);
        String dirtory = System.getProperty("user.dir") + File.separator + "aupload";

        // 判断上传路径是否存在
        if (!FileUtil.exist(dirtory)){
            FileUtil.mkdir(dirtory);
        }
        String newfileName = dirtory+ File.separator + fileName;
        File newfile = new File(newfileName);
        file.transferTo(newfile);
        map.put("upUrl", newfileName);
        return readWithCsvMapReader(newfileName, map, false);
    }

    public Map readWithCsvMapReader(String fileName, Map map, boolean isPre) throws Exception {

        ICsvMapReader mapReader = null;
        try {
            mapReader = new CsvMapReader(new FileReader(fileName), CsvPreference.STANDARD_PREFERENCE);

            // the header columns are used as the keys to the Map
            final String[] header = mapReader.getHeader(true);
            map.put("columns", header);
            final CellProcessor[] processors = new CellProcessor[mapReader.length()];

            Map<String, Object> customerMap;
            ArrayList<Map<String, Object>> allDataList = new ArrayList<>();
            int limit = 10;
            while (limit > 0 && (customerMap = mapReader.read(header, processors)) != null) {
                allDataList.add(customerMap);
                if (isPre) {
                    limit--;
                }
            }
            map.put("excelData", allDataList);
        } finally {
            if (mapReader != null) {
                mapReader.close();
            }
        }
        return map;
    }

    public ArrayList<Map<String, Object>> readWithCsvMapReaderColumns(String fileName, String id,String[] columns, boolean isPre) {
        HashMap<String, ArrayList> map = new HashMap<>();
        try {
            readWithCsvMapReader(fileName, map, isPre);
            ArrayList<Map<String, String>> allDataList = map.get("excelData");
            ArrayList<Map<String, Object>> dataList = new ArrayList<>();
            HashMap<String, String> hashMap = new HashMap<>(columns.length);
            for (Map<String, String> oneColumn : allDataList) {
                for (String column : columns) {
                    hashMap.put(id + "_" +column,oneColumn.get(column));
                }
                dataList.add(new HashMap<>(hashMap));
            }
            return dataList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }
    public ArrayList<Map<String, Object>> readWithCsvMapReaderColumns(String fileName,String[] columns, boolean isPre) {
        HashMap<String, ArrayList> map = new HashMap<>();
        try {
            readWithCsvMapReader(fileName, map, isPre);
            ArrayList<Map<String, String>> allDataList = map.get("excelData");
            ArrayList<Map<String, Object>> dataList = new ArrayList<>();
            HashMap<String, String> hashMap = new HashMap<>(columns.length);
            for (Map<String, String> oneColumn : allDataList) {
                for (String column : columns) {
                    hashMap.put(column,oneColumn.get(column));
                }
                dataList.add(new HashMap<>(hashMap));
            }
            return dataList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }
}

