package com.bweb.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.AbstractCellWriteHandler;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.bweb.excel.ExcelUtil;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.ResponseMsgUtil;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.BsMerchant;
import com.hfkj.model.ResponseData;
import com.hfkj.service.gas.BsGasOrderCountService;
import com.hfkj.service.merchant.BsMerchantService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping(value = "/gasOrderCount")
@Api(value = "加油订单统计")
public class BsGasOrderCountController {
    private static Logger log = LoggerFactory.getLogger(BsGasOrderCountController.class);
    @Resource
    private BsGasOrderCountService gasOrderCountService;
    @Resource
    private BsMerchantService merchantService;

    @RequestMapping(value="/countOilData",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "统计加油数据")
    public ResponseData exportOilOrder(@RequestParam(name = "channelType", required = false) Integer channelType,
                                       @RequestParam(name = "startTime", required = true) Long startTime) {
        try {
            // 获取统计数据
            Calendar startDate = Calendar.getInstance();
            startDate.setTime(new Date(startTime));
            startDate.set(Calendar.HOUR_OF_DAY, 0);
            startDate.set(Calendar.MINUTE, 0);
            startDate.set(Calendar.SECOND, 0);

            List<HashMap<String,Object>> dataList = new LinkedList<>();

            int day = 1; // 当天
            // 当天数据
            List<HashMap<String, Object>> mapList = gasOrderCountService.countOrderRatio(channelType, DateUtil.date2String(startDate.getTime(), DateUtil.Y_M_D_HMS), day-1);
            // 利用当天数据比例进行倒序排序
            List<HashMap<String, Object>> merList = new LinkedList<>();
            for (HashMap<String, Object> data : mapList) {
                HashMap<String,Object> mer = new HashMap<>();
                mer.put("merNo", data.get("merNo"));
                mer.put("merName", data.get("merName"));
                mer.put("merStatus", data.get("merStatus"));
                merList.add(mer);
            }

            // 当天
            HashMap<String,Object> dataMap = new HashMap<>();
            dataMap.put("day", day);
            dataMap.put("data", mapList);
            dataList.add(dataMap);

            // 前3天
            HashMap<String,Object> dataMap3 = new HashMap<>();
            day = 3;
            dataMap3.put("day", day);
            dataMap3.put("data", gasOrderCountService.countOrderRatio(channelType, DateUtil.date2String(startDate.getTime(), DateUtil.Y_M_D_HMS), day-1));
            dataList.add(dataMap3);

            // 前10天
            HashMap<String,Object> dataMap10 = new HashMap<>();
            day = 10;
            dataMap10.put("day", day);
            dataMap10.put("data", gasOrderCountService.countOrderRatio(channelType, DateUtil.date2String(startDate.getTime(), DateUtil.Y_M_D_HMS), day-1));
            dataList.add(dataMap10);

            // 前30天
            HashMap<String,Object> dataMap30 = new HashMap<>();
            day = 30;
            dataMap30.put("day", day);
            dataMap30.put("data", gasOrderCountService.countOrderRatio(channelType, DateUtil.date2String(startDate.getTime(), DateUtil.Y_M_D_HMS), day-1));
            dataList.add(dataMap30);

            // 前60天
            HashMap<String,Object> dataMap60 = new HashMap<>();
            day = 60;
            dataMap60.put("day", day);
            dataMap60.put("data", gasOrderCountService.countOrderRatio(channelType, DateUtil.date2String(startDate.getTime(), DateUtil.Y_M_D_HMS), day-1));
            dataList.add(dataMap60);

            List<List<Object>> excelDataList = new ArrayList<>();
            for (HashMap<String,Object> merchant : merList) {
                List<Object> excelData = new ArrayList<>();
                excelData.add(merchant.get("merNo"));
                excelData.add(merchant.get("merName"));

                for (HashMap<String,Object> data : dataList) {
                    List<HashMap<String, Object>> totalCountCollect = ((List<HashMap<String,Object>>) data.get("data")).stream()
                            .filter(o -> o.get("merNo").equals(merchant.get("merNo"))).collect(Collectors.toList());
                    if (!totalCountCollect.isEmpty()) {
                        excelData.add(totalCountCollect.get(0).get("totalPrice"));
                        excelData.add(totalCountCollect.get(0).get("totalPriceRatio")+"%");
                        excelData.add(totalCountCollect.get(0).get("totalCount"));
                        excelData.add(totalCountCollect.get(0).get("totalCountRatio")+"%");
                    } else {
                        excelData.add(0);
                        excelData.add(0+"%");
                        excelData.add(0);
                        excelData.add(0+"%");
                    }
                }
                excelDataList.add(excelData);
            }

            List<Object> footData = new ArrayList<>();
            footData.add("合计");
            footData.add(merList.size()+"家油站");
            footData.add(countPrice((List<HashMap<String, Object>>) dataMap.get("data")));
            footData.add("");
            footData.add(countOilNumber((List<HashMap<String, Object>>) dataMap.get("data")));
            footData.add("");
            footData.add(countPrice((List<HashMap<String, Object>>) dataMap3.get("data")));
            footData.add("");
            footData.add(countOilNumber((List<HashMap<String, Object>>) dataMap3.get("data")));
            footData.add("");
            footData.add(countPrice((List<HashMap<String, Object>>) dataMap10.get("data")));
            footData.add("");
            footData.add(countOilNumber((List<HashMap<String, Object>>) dataMap10.get("data")));
            footData.add("");
            footData.add(countPrice((List<HashMap<String, Object>>) dataMap30.get("data")));
            footData.add("");
            footData.add(countOilNumber((List<HashMap<String, Object>>) dataMap30.get("data")));
            footData.add("");
            footData.add(countPrice((List<HashMap<String, Object>>) dataMap60.get("data")));
            footData.add("");
            footData.add(countOilNumber((List<HashMap<String, Object>>) dataMap60.get("data")));
            footData.add("");
            excelDataList.add(footData);

            // 设置内容的策略
            WriteCellStyle contentWriteCellStyle = ExcelUtil.getWriteCellStyle();

            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            // 设置头部水平居中对齐
            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            // 设置头部垂直居中对齐
            headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            String path = "/temporary/"+System.currentTimeMillis()+".xlsx";
            EasyExcel.write( CommonSysConst.getSysConfig().getFilesystem() + path)
                    .head(getSaleSheetHeadList(startTime, dataList))
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                    .registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle))
                    .registerWriteHandler(new CellWriteHandler() {
                        @Override
                        public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {

                        }

                        @Override
                        public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {

                        }

                        @Override
                        public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {

                        }

                        @Override
                        public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
                            int rowIndex = cell.getRowIndex();
                            int columnIndex = cell.getColumnIndex();
                            Workbook workbook = writeSheetHolder.getSheet().getWorkbook();

                            if (rowIndex > 1) {
                                if (rowIndex <= merList.size()) {
                                    HashMap<String, Object> map = merList.get(rowIndex - 2);
                                    if (!map.isEmpty() && !map.get("merStatus").toString().equals("1")) {
                                        CellStyle oldCellStyle = cell.getCellStyle();
                                        CellStyle newCellStyle = workbook.createCellStyle();
                                        newCellStyle.cloneStyleFrom(oldCellStyle);
                                        newCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
                                        newCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                                        cell.setCellStyle(newCellStyle);
                                    }
                                }
                            }

                            if (rowIndex > 1 && (columnIndex == 2 || columnIndex == 6 || columnIndex == 10 || columnIndex == 14 || columnIndex == 18)) {
                                CellStyle oldCellStyle = cell.getCellStyle();
                                CellStyle newCellStyle = workbook.createCellStyle();
                                newCellStyle.cloneStyleFrom(oldCellStyle);

                                Font font = workbook.createFont();
                                font.setColor(IndexedColors.RED.index);
                                newCellStyle.setFont(font);
                                cell.setCellStyle(newCellStyle);
                            }
                        }
                    })
                    .sheet("统计")
                    .doWrite(excelDataList);
            return ResponseMsgUtil.success(path);

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    public static BigDecimal countPrice(List<HashMap<String, Object>> mapList) {
        BigDecimal totalprice = new BigDecimal("0");
        for (HashMap<String, Object> map : mapList) {
            if (StringUtils.isNotBlank(MapUtils.getString(map, "totalPrice"))) {
                totalprice = totalprice.add(new BigDecimal(MapUtils.getString(map, "totalPrice")));
            }
        }
        return totalprice;
    }

    public static BigDecimal countOilNumber(List<HashMap<String, Object>> mapList) {
        BigDecimal totalprice = new BigDecimal("0");
        for (HashMap<String, Object> map : mapList) {
            if (StringUtils.isNotBlank(MapUtils.getString(map, "totalCount"))) {
                totalprice = totalprice.add(new BigDecimal(MapUtils.getString(map, "totalCount")));
            }
        }
        return totalprice;
    }

    private static List<List<String>> getSaleSheetHeadList(Long startTime, List<HashMap<String,Object>> dataList) {
        List<List<String>> list = new ArrayList<List<String>>();

        List<String> merNo = new ArrayList<String>();
        merNo.add("油站编码");
        list.add(merNo);

        List<String> merName = new ArrayList<String>();
        merName.add("油站名称");
        list.add(merName);

        for (HashMap<String,Object> data : dataList) {

            // 获取时间
            Calendar date = Calendar.getInstance();
            date.setTime(new Date(startTime));
            date.add(Calendar.DAY_OF_MONTH, 1 - Integer.parseInt(data.get("day").toString()));

            List<String> daysHead = new ArrayList<String>();
            daysHead.add(DateUtil.date2String(date.getTime(), DateUtil.Y_M_D));
            daysHead.add("加油金额");
            list.add(daysHead);

            List<String> daysHead2 = new ArrayList<String>();
            daysHead2.add(DateUtil.date2String(date.getTime(), DateUtil.Y_M_D));
            daysHead2.add("占比");
            list.add(daysHead2);

            List<String> daysHead3 = new ArrayList<String>();
            daysHead3.add(DateUtil.date2String(date.getTime(), DateUtil.Y_M_D));
            daysHead3.add("加油订单");
            list.add(daysHead3);

            List<String> daysHead4 = new ArrayList<String>();
            daysHead4.add(DateUtil.date2String(date.getTime(), DateUtil.Y_M_D));
            daysHead4.add("占比");
            list.add(daysHead4);
        }
        return list;
    }
}
