package com.handong.smartservice.component;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.net.URLEncoder;

import java.util.List;
import java.util.Map;



public class CtExcelMaker {
    static private final Logger logger = LoggerFactory.getLogger(CtExcelMaker.class);

    static public String getBrowser(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        if (header.indexOf("MSIE") > -1) {
            return "MSIE";
        } else if (header.indexOf("Trident") > -1) {
            return "Trident";
        } else if (header.indexOf("Chrome") > -1) {
            return "Chrome";
        } else if (header.indexOf("Opera") > -1) {
            return "Opera";
        }
        return "Firefox";
    }

    static public void makeExcelResponse(HttpServletRequest request, HttpServletResponse response,
                                         String strFileName, String[] arrHeader, String[] arrColumn, List<Map<String, String>> listContents, String strPassword) {
        logger.info("ExcelLeader, makeExcelResponse, file name = " + strFileName);

        try {
            XSSFRow row = null;
            XSSFCell cell = null;
            int nRowIndex = 0;

            XSSFWorkbook workBook = new XSSFWorkbook();

            XSSFSheet sheet = workBook.createSheet("sheet");

            row = sheet.createRow(nRowIndex++);

            // header
            int i = 0;
            for (; i < arrHeader.length; i++) {
                cell = row.createCell(i);
                cell.setCellValue(new XSSFRichTextString(arrHeader[i]));
            }

            for (i = 0; i < listContents.size(); i++) {
                Map<String, String> col = listContents.get(i);

                row = sheet.createRow(nRowIndex++);
                Object cellData;
                for (int j = 0; j < arrColumn.length; j++) {
                    cell = row.createCell(j);
                    cellData = col.get(arrColumn[j]);
                    if (cellData == null)
                        cell.setCellValue(new XSSFRichTextString(""));
                    else
                        cell.setCellValue(new XSSFRichTextString(cellData.toString()));
                }
            }

            String strTmp = strFileName + ".xlsx";
            String browser = getBrowser(request);
            if (browser.contains("MSIE") || browser.contains("Trident")) {
                String strDownloadName = URLEncoder.encode(strTmp, "UTF-8").replaceAll("\\+", "%20");
                response.addHeader("Content-Disposition", "attachment;filename=" + strDownloadName + ";");
            } else {
                //val strDownloadName = String(strTmp.toByteArray(Charsets.UTF_8), Charsets.ISO_8859_1)
                String strDownloadName = URLEncoder.encode(strTmp, "UTF-8");
                response.addHeader("Content-Disposition", "attachment;filename=\"" + strDownloadName + "\"");
            }
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");

            //fuck!!! not working over poi 4
            if (strPassword != null && strPassword.isEmpty() == false) {
                EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
                Encryptor encryptor = info.getEncryptor();
                encryptor.confirmPassword(strPassword);

                ByteArrayOutputStream osByteArray = new ByteArrayOutputStream();
                workBook.write(osByteArray);
                InputStream isTmp = new ByteArrayInputStream(osByteArray.toByteArray());
                OPCPackage opc = OPCPackage.open(isTmp);
                POIFSFileSystem poifs = new POIFSFileSystem();
                OutputStream osTemp = encryptor.getDataStream(poifs);
                opc.save(osTemp);
                opc.close();

                OutputStream osResponse = response.getOutputStream();
                poifs.writeFilesystem(osResponse);
                osResponse.close();
                osByteArray.close();
                return;
            }

            OutputStream osResponse = response.getOutputStream();
            workBook.write(osResponse);
            osResponse.close();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}
