package jnpf.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.Header;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import jnpf.handler.CustomCellStyleHandler;
import jnpf.handler.CustomCellWriteHandler;
import jnpf.handler.CustomRowHeightHandler;
import jnpf.model.cultivate.vo.teaching.SkillCountVo;
import jnpf.model.cultivate.vo.teaching.SummaryPageListVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

/**
 * easyExcel导入导出工具类
 * @author yier
 */
public class EasyExcelUtil {

    private static final Logger logger = LoggerFactory.getLogger(EasyExcelUtil.class);

    public static <T> void simpleWrite(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) throws IOException {
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        OutputStream outputStream = response.getOutputStream();
        try (outputStream) {
            String fileName = URLEncoder.encode(sheetName, StandardCharsets.UTF_8);
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(outputStream, clazz).sheet(sheetName).doWrite(list);
        }
    }

    /**
     * Excel导出功能
     *
     * @param response  相应数据
     * @param fileName  文件名
     * @param sheetName sheet名
     * @param cls       对象属性名的值
     */
    public static <T> void export(HttpServletResponse response, String fileName, String sheetName, Class<T> cls, List<T> list) throws Exception {
        ServletOutputStream outputStream = response.getOutputStream();
        response.setCharacterEncoding("utf-8");
        response.setHeader(Header.CONTENT_DISPOSITION.toString(), "attachment; filename=".concat(URLEncoder.encode(fileName, StandardCharsets.UTF_8)));
        response.setContentType("application/octet-stream");
        EasyExcel.write(outputStream, cls).sheet(sheetName).doWrite(list);
    }

    /**
     * 动态表头导出
     * @param headList 表头
     * @param dataList 导出数据
     * @param filename 文件名
     * @param sheetName sheet名称
     */
    public static void dynamicTableExport(List<List<String>> headList, List<List<String>> dataList, String filename, String sheetName) {
        ExcelWriter excelWriter = null;
        HttpServletResponse response = ServletUtil.getResponse();
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/octet-stream");

            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));
            excelWriter = EasyExcel.write()
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .file(response.getOutputStream())
                    .inMemory(true).build();

            WriteSheet writeSheet = EasyExcel.writerSheet(0, sheetName)
                    .head(headList).build();
            excelWriter.write(dataList, writeSheet);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }

    /**
     * 获取动态表头
     * @param dataList 数据集合
     * @param list 已存在的动态表头
     * @return 返回动态表头
     */
    public static List<List<String>> getHeaders(List<SummaryPageListVo> dataList, List<List<String>> list) {
        //获取最长的技能点集合
        List<SkillCountVo> skillList = dataList.stream().map(SummaryPageListVo::getSkillList).max(Comparator.comparingInt(List::size)).orElse(new LinkedList<>());
        if (CollUtil.isNotEmpty(dataList) && CollUtil.isNotEmpty(skillList)) {
            for (SkillCountVo skillCountVo : skillList) {
                List<String> head = new ArrayList<>();
                head.add(skillCountVo.getName());
                list.add(head);
            }
        }
        return list;
    }

    /**
     * 获取表内容数据
     * @param dataList 数据集合
     * @return 表内容数据
     */
    public static List<List<Object>> getDataList(List<SummaryPageListVo> dataList) {
        List<List<Object>> list = ListUtils.newArrayList();
        if (CollUtil.isNotEmpty(dataList)) {
            for (SummaryPageListVo rankingDTO : dataList) {
                List<Object> data = ListUtils.newArrayList();
                data.add(rankingDTO.getStoreName());
                data.add(rankingDTO.getUserName());
                data.add(rankingDTO.getPostName());
                data.add(rankingDTO.getTotalCount());
                if (CollUtil.isNotEmpty(rankingDTO.getSkillList())) {
                    for (SkillCountVo skillCountVo : rankingDTO.getSkillList()) {
                        data.add(skillCountVo.getCount());
                    }
                }
                list.add(data);
            }
        }
        return list;
    }

    /**
     * 导出排行榜数据
     *
     * @param list      导出数据
     * @param headers   表头
     * @param fileName  导出文件名称
     * @param sheetName sheet名称
     * @param response  响应对象
     * @throws Exception 抛出异常
     */
    public static void rankingExportData(List<List<Object>> list, List<List<String>> headers, String fileName,
                                         String sheetName, HttpServletResponse response) throws Exception {
        EasyExcelUtil.export(response, fileName + ".xlsx", sheetName + "排行", list, headers);
    }

    /**
     * Excel导出功能(根据自定义表头)
     *
     * @param response  响应数据
     * @param fileName  文件名
     * @param sheetName sheet名
     * @param list      数据列表
     * @param headers   表头集合
     */
    public static void export(HttpServletResponse response, String fileName, String sheetName,
                              List<List<Object>> list, List<List<String>> headers) throws Exception {
        ServletOutputStream outputStream = response.getOutputStream();
        response.setCharacterEncoding("utf-8");
        response.setHeader(Header.CONTENT_DISPOSITION.toString(), "attachment; filename=".concat(URLEncoder.encode(fileName, StandardCharsets.UTF_8)));
        response.setContentType("application/octet-stream");
        EasyExcel.write(outputStream)
                .head(headers)
                .sheet(sheetName)
                .registerWriteHandler(new CustomRowHeightHandler())
                .registerWriteHandler(new CustomCellStyleHandler())
                .registerWriteHandler(new CustomCellWriteHandler())
                .doWrite(list);
    }
}
