package com.cftech.showroom.appform.model;

import com.alibaba.fastjson.JSONObject;
import com.cftech.core.util.StringUtils;
import com.cftech.showroom.appform.service.AppFormService;
import org.apache.commons.collections.map.HashedMap;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.Month;
import java.util.*;
import java.util.stream.IntStream;

public class ExportExcelData {
    public static void exportData(List<ShowRoomRecord> showRoomRecords, String year, List<String> perType, List<String> dept, List<String> persons, HttpServletResponse response) throws FileNotFoundException {
        // 文件名
        String fileName = "Showroom Booking Record.xls";
        // 创建excel文件对象
        HSSFWorkbook wb = new HSSFWorkbook();
        // 创建sheet
        Sheet sheet = wb.createSheet("Reporting data");
        //sheet.setDefaultColumnWidth(9 * 256);
        sheet.setDefaultRowHeight((short) 800);
        sheet.setColumnWidth(0, 89 * 256);//89个字符
        sheet.setColumnWidth(1, 46 * 256);//46个字符
        IntStream.range(2, 14).forEach(i -> sheet.setColumnWidth(i, 9 * 256));
        sheet.setColumnWidth(14, 16 * 256);//16个字符
        //表头字体
        Font headerFont = wb.createFont();
        headerFont.setFontHeightInPoints((short) 11);
        //headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
        headerFont.setBold(true);
        headerFont.setColor(HSSFColor.BLACK.index);
        //表头样式，左右居左，上下居中
        CellStyle headerStyle = wb.createCellStyle();
        headerStyle.setFont(headerFont);
        headerStyle.setAlignment(HorizontalAlignment.LEFT);// 居左
        headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 上下居中
        headerStyle.setLocked(true);
        headerStyle.setWrapText(false);// 自动换行
        headerStyle.setBorderBottom(BorderStyle.DOUBLE);

        //正文字体
        Font commonFont = wb.createFont();
        commonFont.setFontHeightInPoints((short) 11);
        //下边框实现样式
        CellStyle headerBottomStyle = wb.createCellStyle();
        headerBottomStyle.setAlignment(HorizontalAlignment.LEFT);// 居左
        headerBottomStyle.setBorderBottom(BorderStyle.THIN);
        headerBottomStyle.setFont(commonFont);
        headerBottomStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 上下居中
        //无边框样式
        CellStyle headerDefaultStyle = wb.createCellStyle();
        headerDefaultStyle.setAlignment(HorizontalAlignment.LEFT);// 居左
        headerDefaultStyle.setFont(commonFont);
        headerDefaultStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 上下居中
        // 行号org.apache.poi.ss.usermodel.Font.setBold
        int rowNum = 0;
        //列头
        String[] headers = {"Criteria assessed统计类别", "Details 统计项", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "TOTAL" + year};

        //填充申请数所有类别数据
        Map<String, Map> guests = new HashMap<String, Map>();
        //填充来访者人数所有类别
        Map<String, Map> NumberGuestsType = new HashMap<String, Map>();
        for (String str : perType) {
            Map<Integer, String> guestsAndMonthMap = new HashMap<Integer, String>();
            guests.put(str, guestsAndMonthMap);
            Map<Integer, String> obj = new HashMap<Integer, String>();
            NumberGuestsType.put(str, obj);
        }
        //填充按部门申请数量
        Map<String, Map> MonthGuestsDept = new HashMap<String, Map>();
        for (String str : dept) {
            Map<Integer, String> obj = new HashMap<Integer, String>();
            MonthGuestsDept.put(str, obj);
        }
        //填充按品牌大使申请数量
        Map<String, Map> MonthGuestsPersons = new HashMap<String, Map>();
        for (String str : persons) {
            if (StringUtils.isBlank(str)) {
                continue;
            }
            Map<Integer, String> obj = new HashMap<Integer, String>();
            MonthGuestsPersons.put(str, obj);
        }
        //单月所有申请数Map
        Map<Integer, String> guestsAndMonthCount0 = new HashMap<Integer, String>();
        //单月来访者人数
        Map<Integer, String> TotalNumberOfVisitors = new HashMap<Integer, String>();
        //有品牌大使的申请数量
        Map<Integer, String> GuidedTours = new HashMap<Integer, String>();
        //每月接单最多的品牌大使
        Map<Integer, String> maxGuidedToursMaps = new HashMap<Integer, String>();
        Map<String, Map> columnsObject = new LinkedHashMap<>();
        for (ShowRoomRecord showRoomRecord : showRoomRecords) {
            //填充单月所有申请数Map
            int m = showRoomRecord.getReservationDate().getMonth();//月份
            if (guestsAndMonthCount0.containsKey(m)) {
                int count = Integer.valueOf(guestsAndMonthCount0.get(m));
                count++;
                guestsAndMonthCount0.put(m, String.valueOf(count));
            } else {
                guestsAndMonthCount0.put(m, "1");
            }
            //填充单月按类别统计申请数
            Map<Integer, String> countMap = guests.get(showRoomRecord.getType());
            if (countMap.containsKey(m)) {
                int count = Integer.valueOf(countMap.get(m));
                count++;
                countMap.put(m, String.valueOf(count));
            } else {
                countMap.put(m, "1");
            }

            guests.put(showRoomRecord.getType(), countMap);

            //填充单月来访者人数Map
            if (TotalNumberOfVisitors.containsKey(m)) {
                int count = Integer.valueOf(TotalNumberOfVisitors.get(m));
                count += Integer.valueOf(showRoomRecord.getPersonNum());
                TotalNumberOfVisitors.put(m, String.valueOf(count));
            } else {
                TotalNumberOfVisitors.put(m, showRoomRecord.getPersonNum());
            }
            //填充单月按类别统计来访人数
            Map<Integer, String> countVisitorsMap = NumberGuestsType.get(showRoomRecord.getType());
            if (countVisitorsMap.containsKey(m)) {
                int count = Integer.valueOf(countVisitorsMap.get(m));
                count += Integer.valueOf(showRoomRecord.getPersonNum());
                countVisitorsMap.put(m, String.valueOf(count));
            } else {
                countVisitorsMap.put(m, showRoomRecord.getPersonNum());
            }
            NumberGuestsType.put(showRoomRecord.getType(), countVisitorsMap);

            //填充单月按部门统计来访人数
            Map<Integer, String> countDeptsMap = MonthGuestsDept.get(showRoomRecord.getDept());
            if (countDeptsMap.containsKey(m)) {
                int count = Integer.valueOf(countDeptsMap.get(m));
                count++;
                countDeptsMap.put(m, String.valueOf(count));
            } else {
                countDeptsMap.put(m, "1");
            }
            MonthGuestsDept.put(showRoomRecord.getDept(), countDeptsMap);
            //填充单月统计有品牌大使的申请数量
            if (StringUtils.isNotBlank(showRoomRecord.getPersonName())) {
                if (GuidedTours.containsKey(m)) {
                    int count = Integer.valueOf(GuidedTours.get(m));
                    count++;
                    GuidedTours.put(m, String.valueOf(count));
                } else {
                    GuidedTours.put(m, "1");
                }


                //填充单月统计品牌大使接单数
                Map<Integer, String> countPersonsMap = MonthGuestsPersons.get(showRoomRecord.getPersonName());
                if (countPersonsMap.containsKey(m)) {
                    int count = Integer.valueOf(countPersonsMap.get(m));
                    count++;
                    countPersonsMap.put(m, String.valueOf(count));
                } else {
                    countPersonsMap.put(m, "1");
                }
                MonthGuestsPersons.put(showRoomRecord.getPersonName(), countPersonsMap);
            }
        }
        Map<Integer, Integer> tempPerson = new HashMap<>();
        //填充每月接单最多的品牌大使
        for (Map.Entry<String, Map> entry : MonthGuestsPersons.entrySet()) {
            String perSonkey = entry.getKey();//品牌大使名字
            Map<Integer, String> perMap = entry.getValue(); //此品牌大使每月的数据
            for (Map.Entry<Integer, String> obj : perMap.entrySet()) {
                if (tempPerson.containsKey(obj.getKey())) {
                    int v = Integer.valueOf(obj.getValue());//目前这个人此月的单数
                    int temp = tempPerson.get(obj.getKey());//之前这个月最高的人
                    if (v > temp) {//比对，单高者入Map
                        tempPerson.put(obj.getKey(), v);
                        maxGuidedToursMaps.put(obj.getKey(), perSonkey);
                    } else if (v == temp) {
                        maxGuidedToursMaps.put(obj.getKey(), maxGuidedToursMaps.get(obj.getKey()) + "," + perSonkey);
                    }
                } else {
                    if (Integer.valueOf(obj.getValue()) > 0) {
                        tempPerson.put(obj.getKey(), Integer.valueOf(obj.getValue()));
                        maxGuidedToursMaps.put(obj.getKey(), perSonkey);
                    }
                }
            }

        }

        Map<String, Map> guestsAndMonthCountMap = new HashMap<String, Map>();
        guestsAndMonthCountMap.put("-", guestsAndMonthCount0);
        columnsObject.put("Total number of visits per month 单月所有申请数", guestsAndMonthCountMap);
        columnsObject.put("Number of visits per Type of guests 单月按类别统计申请数", guests);
        Map<String, Map> TotalNumberOfVisitorsMap = new HashMap<String, Map>();
        TotalNumberOfVisitorsMap.put("-", TotalNumberOfVisitors);
        columnsObject.put("Total number of visitors 单月来访者人数", TotalNumberOfVisitorsMap);
        columnsObject.put("Number of visitors per Type of guests 单月按类别统计来访者人数", NumberGuestsType);
        columnsObject.put("Number of visits by Organizing Division/Department 单月按事业部/部门统计申请数量", MonthGuestsDept);
        Map<String, Map> GuidedToursMap = new HashMap<String, Map>();
        GuidedToursMap.put("-", GuidedTours);
        columnsObject.put("Guided tours 单月统计有品牌大使的申请数量", GuidedToursMap);
        Map<String, Map> maxGuidedToursMap = new HashMap<String, Map>();
        maxGuidedToursMap.put("-", maxGuidedToursMaps);
        columnsObject.put("Most required brand ambassador per month 每月接单最多的品牌大使", maxGuidedToursMap);
        columnsObject.put("Brand ambassador monthly activity 单月统计品牌大使接单数", MonthGuestsPersons);
        //第一行表头创建
        Row r0 = sheet.createRow(rowNum);
        r0.setHeight((short) 800);
        for (int i = 0; i < headers.length; i++) {
            Cell c00 = r0.createCell(i);
            c00.setCellValue(headers[i]);
            c00.setCellStyle(headerStyle);
        }
        int startNum = rowNum;//记录起始行，合并单元格时使用
        //填充数据
        for (Map.Entry<String, Map> entry : columnsObject.entrySet()) {//第一列Map
            startNum = rowNum + 1;
            String mapKey = entry.getKey();
            Map<String, Map> obj = entry.getValue();
            int rows = 0;
            for (Map.Entry<String, Map> o : obj.entrySet()) {//第二列Map
                rowNum++;//行索引
                rows++;//记录二级分类，也就是第二列是否已遍历完毕，遍历完毕的最后一行需要加下边框
                String oKey = o.getKey();
                Map<Integer, String> v = o.getValue();
                Row r1 = sheet.createRow(rowNum);
                r1.setHeight((short) 800);
                int countNum = 0;//合计值
                for (int i = 0; i < headers.length; i++) {
                    Cell c00 = r1.createCell(i);
                    if (obj.size() == rows) {//如果二级分类已遍历到最后一行，则加上下边框
                        c00.setCellStyle(headerBottomStyle);
                    } else {
                        c00.setCellStyle(headerDefaultStyle);
                    }
                    if (i == 0) {
                        c00.setCellValue(mapKey);
                        c00.setCellStyle(headerBottomStyle);
                    } else if (i == 1) {
                        c00.setCellValue(StringUtils.equals(oKey, "-") ? "" : oKey);
                    } else if (i >= 2 && i <= headers.length - 2) {//第二行第二个单元格空着，故从第三个到导出第二啊，为每月的值
                        if (v.get(i - 2) != null) {
                            c00.setCellValue(v.get(i - 2).toString());
                            if (isNumeric(v.get(i - 2).toString())) {
                                countNum += Integer.valueOf(v.get(i - 2));
                            }
                        } else {
                            c00.setCellValue("");
                        }
                    } else if (i == headers.length - 1) {//最后一个为合计
                        if (countNum > 0) {
                            c00.setCellValue(countNum);
                        }
                    } else {
                        continue;
                    }
                }
            }

//            if (startNum <= rowNum) {
            if (startNum < rowNum) {
                CellRangeAddress region = new CellRangeAddress(startNum, rowNum, 0, 0);
                sheet.addMergedRegion(region);
            }
        }
        try {
            OutputStream output = response.getOutputStream();
            //清空缓存
            response.reset();
//定义浏览器响应表头，顺带定义下载名，比如students(中文名需要转义)
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");
//定义下载的类型，标明是excel文件
            response.setContentType("application/vnd.ms-excel");
//这时候把创建好的excel写入到输出流
            wb.write(output);
//养成好习惯，出门记得随手关门
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean isNumeric(String str) {
        for (int i = 0; i < str.length(); i++) {
            //System.out.println(str.charAt(i));
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }
}
