
package com.jeelowcode.framework.excel.write;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.jeelowcode.framework.excel.handler.CustomSheetWriteHandler;
import com.jeelowcode.framework.excel.handler.RowFormatSetTextHandler;
import com.jeelowcode.framework.excel.model.ExcelTitleModel;
import com.jeelowcode.framework.excel.model.MoreSheetConfig;
import com.jeelowcode.framework.exception.JeeLowCodeException;
import com.jeelowcode.framework.utils.utils.FuncBase;
import com.alibaba.excel.EasyExcel;
import org.apache.commons.collections4.map.LinkedMap;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;

public class ExcelExportUtils {

    /**
     * 封装表头信息
     * @param headMap {name:姓名}  {age:年龄}
     * @return
     */
    private static List<List<String>> getExcelHeaderList(LinkedMap<String, ExcelTitleModel> headMap){
        //处理头部
        List<List<String>> head = new ArrayList<>();
        headMap.forEach((code, model) -> {
            List<String> headList = new ArrayList<>();
            headList.add(model.getTitle());
            head.add(headList);
        });
        return head;
    }

    /**
     * 封装表数据
     * @param headMap
     * @param dataList ｛name:张三｝｛age:18｝
     * @return
     */
    private static  List<List<Object>> getExcelDataList(LinkedMap<String, ExcelTitleModel> headMap, List<Map<String, Object>> dataList){
        List<List<Object>> data=new ArrayList<>();
        //处理数据
        dataList.stream().forEach(dataMap->{
            List<Object> tmpList=new ArrayList<>();
            headMap.forEach((code,title)->{
                Object tmpVal = dataMap.get(code);
                try{
                    tmpList.add(FuncBase.json2Str(tmpVal));
                }catch (Exception e){
                    tmpList.add(tmpVal);
                }
            });
            data.add(tmpList);
        });
        return data;
    }


    /**
     * 动态表头导出
     * @param response
     * @param sheetName
     * @param headMap
     * @param dataList
     */
    public static void exportExcel(HttpServletResponse response, String sheetName, LinkedMap<String, ExcelTitleModel> headMap, List<Map<String, Object>> dataList) {
        try {
             if(FuncBase.isEmpty(headMap)){
                 throw new JeeLowCodeException("表头不允许为空");
             }


            //设置mime类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            //设置编码
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String outFileName = URLEncoder.encode(sheetName, "UTF-8");
            //设置响应头信息 Content-disposition
            response.setHeader("Content-disposition", "attachment;filename=" + outFileName + ".xlsx");

            //处理头部
            List<List<String>> head =getExcelHeaderList(headMap);
             //处理表数据
            List<List<Object>> data=getExcelDataList(headMap,dataList);
            //处理下拉内容
            Map<Integer, List<String>> dropdownOptionsMap=getDropdownOptionsMap(headMap);

            RowFormatSetTextHandler rowFormatSetTextHandler = new RowFormatSetTextHandler();
            rowFormatSetTextHandler.setDropdownOptionsMap(dropdownOptionsMap);
            EasyExcel.write(response.getOutputStream())
                    .registerWriteHandler(rowFormatSetTextHandler)
                    .registerWriteHandler(new CustomSheetWriteHandler(dropdownOptionsMap))// 初始化单元格为文本格式
                    .registerWriteHandler(new CustomColumnWidthStyleStrategy())// 单元格宽度
                    .registerWriteHandler(CellStyleUtils.getCellStyleStrategy())// 单元格样式
                    .head(head)
                    .sheet(sheetName).doWrite(data);
        } catch (Exception e) {
            throw new JeeLowCodeException(e.getMessage());
        }
    }

    public static void exportExcel(HttpServletResponse response, String fileName,List<MoreSheetConfig> sheetConfigList) {
        try {
            if (FuncBase.isEmpty(sheetConfigList)) {
                throw new JeeLowCodeException("sheets数据不允许为空");
            }

            // 设置mime类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置编码
            response.setCharacterEncoding("utf-8");
            // 防止中文乱码
            String outFileName = URLEncoder.encode(fileName, "UTF-8");
            // 设置响应头信息 Content-disposition
            response.setHeader("Content-disposition", "attachment;filename=" + outFileName + ".xlsx");

            // 创建ExcelWriter
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

            // 遍历每个sheet
            for(MoreSheetConfig moreSheetConfig:sheetConfigList){
                List<Map<String, Object>> dataList = moreSheetConfig.getDataList();
                LinkedMap<String, ExcelTitleModel> headMap = moreSheetConfig.getHeadMap();
                String sheetName = moreSheetConfig.getSheetName();

                if (FuncBase.isEmpty(headMap)) {
                    continue; // 跳过空表头的sheet
                }

                // 处理头部
                List<List<String>> head = getExcelHeaderList(headMap);
                // 处理表数据
                List<List<Object>> data = getExcelDataList(headMap, dataList);
                // 处理下拉内容
                Map<Integer, List<String>> dropdownOptionsMap = getDropdownOptionsMap(headMap);

                RowFormatSetTextHandler rowFormatSetTextHandler = new RowFormatSetTextHandler();
                rowFormatSetTextHandler.setDropdownOptionsMap(dropdownOptionsMap);

                // 创建WriteSheet
                WriteSheet writeSheet = EasyExcel.writerSheet(sheetName)
                        .head(head)
                        .registerWriteHandler(rowFormatSetTextHandler)
                        .registerWriteHandler(new CustomSheetWriteHandler(dropdownOptionsMap))
                        .registerWriteHandler(new CustomColumnWidthStyleStrategy())
                        .registerWriteHandler(CellStyleUtils.getCellStyleStrategy())
                        .build();
                // 写入数据
                excelWriter.write(data, writeSheet);
            }

            // 关闭ExcelWriter
            excelWriter.finish();
        } catch (Exception e) {
            throw new JeeLowCodeException(e.getMessage());
        }
    }

    /**
     * 处理下拉列表
     * @param headMap
     * @return
     */
    private static Map<Integer, List<String>> getDropdownOptionsMap(LinkedMap<String, ExcelTitleModel> headMap){
        Map<Integer, List<String>> dropdownOptionsMap=new HashMap<>();

        int index = 0; // 初始化序号变量
        Iterator<Map.Entry<String, ExcelTitleModel>> iterator = headMap.entrySet().iterator();
        while (iterator.hasNext()) {

            Map.Entry<String, ExcelTitleModel> entry = iterator.next();
            ExcelTitleModel model = entry.getValue();
            List<String> dropdownOptionList = model.getDropdownOptionList();
            if(FuncBase.isNotEmpty(dropdownOptionList)){
                dropdownOptionsMap.put(index,dropdownOptionList);
            }
            ++index;
        }
        return dropdownOptionsMap;
    }

}