package com.ho.business.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.ho.business.entity.Station;
import com.ho.business.service.ReportFormService;
import com.ho.business.service.StationService;
import com.ho.business.util.AdaptiveWidthUtils;
import com.ho.business.vo.req.reduceemissions.ReduceEmissionsReqVO;
import com.ho.business.vo.req.report.ReportReqVO;
import com.ho.business.vo.resp.ReportFromReqVo;
import com.ho.business.vo.resp.report.CurrentMonthReportRespVO;
import com.ho.business.vo.resp.report.HistoryReportRespVO;
import com.ho.common.tools.annotation.LogAnnotation;
import com.ho.common.tools.constant.ContextConstant;
import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.BigDecimalUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author gyan
 * @desc: 报表
 * @DateTime: 2022/11/9 8:49
 */
@RestController
@RequestMapping(ContextConstant.BUSINESS + "report")
@Api(tags = "报表模块")
@Slf4j
public class ReportFormController {

    @Autowired
    ReportFormService reportFormService;

    @Autowired
    RedisService redisService;

    @Autowired
    StationService stationService;

    @Autowired
    BigDecimalUtil bigDecimalUtil;


    @PostMapping("report")
    @ApiOperation(value = "报表查询")
    public DataResult<List<ReportFromReqVo>> getReportForm(@RequestBody @Valid ReduceEmissionsReqVO vo, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = redisService.getSimpleUserByToken(token);
        //如果 stationId没传 要查所辖电站的数据
        if (StringUtils.isEmpty(vo.getStationId())) {
            vo.setStationIds(simpleUser.getStationIds());
        }

        List<ReportFromReqVo> ReportFromReqVo = reportFormService.getReportForm(vo);
        return DataResult.success(ReportFromReqVo);
    }


    @PostMapping("exportStationReport")
    @ApiOperation(value = "电站电量报表下载")
    @LogAnnotation(title = "报表模块", action = "电站电量报表下载")
    public void exportStationReport(@RequestBody @Valid ReduceEmissionsReqVO vo, HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = redisService.getSimpleUserByToken(token);
        //如果 stationId没传 要查所辖电站的数据
        if (StringUtils.isEmpty(vo.getStationId())) {
            vo.setStationIds(simpleUser.getStationIds());
        }
        //查询数据
        List<ReportFromReqVo> list = reportFormService.getReportForm(vo);
        //在内存操作，写到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);

        //自定义标题别名
        writer.addHeaderAlias("day", "日期");
        writer.addHeaderAlias("totalDischargeCapacity", "总放电量");
        writer.addHeaderAlias("totalChargeCapacity", "总充电量");
        writer.addHeaderAlias("tipCharge", "尖充电量");
        writer.addHeaderAlias("peakCharge", "峰充电量");
        writer.addHeaderAlias("dailyCharge", "平充电量");
        writer.addHeaderAlias("valleyCharge", "谷充电量");
        writer.addHeaderAlias("tipDischarge", "尖放电量");
        writer.addHeaderAlias("peakDischarge", "峰放电量");
        writer.addHeaderAlias("dailyDischarge", "平放电量");
        writer.addHeaderAlias("valleyDischarge", "谷放电量");
        writer.addHeaderAlias("totalProfit", "收益(元)");

        //默认配置
        writer.write(list, true);
        //自适应宽度
        AdaptiveWidthUtils.setSizeColumn(writer.getSheet(), 4);
        //设置content—type
        //response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset:utf-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        response.addHeader("Access-Control-Expose-Headers", "Content-disposition");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        //设置标题
        String fileName = null;
        ServletOutputStream outputStream = null;
        try {
            fileName = "stationReport_" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
            //fileName = "站级充电量统计报表.xlsx";
            //Content-disposition是MIME协议的扩展，MIME协议指示MIME用户代理如何显示附加的文件。
            //response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
            outputStream = response.getOutputStream();

            //将Writer刷新到OutPut
            writer.flush(outputStream, true);

        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            writer.close();
        }
    }


    @PostMapping("currentMonthReport")
    @ApiOperation("当月报表数据")
    public DataResult<List<CurrentMonthReportRespVO>> getCurrentMonthReport(@RequestBody @Valid ReportReqVO vo) {
        List<CurrentMonthReportRespVO> currentMonthReportRespVOList = new ArrayList<>();
        if (vo.getStationId() != null) {
            //查询电站的装机容量
            Station station = stationService.selectById(vo.getStationId());
            if (station != null) {
                currentMonthReportRespVOList = reportFormService.getCurrentMonthReport(station.getCapacity(), vo);
                for (CurrentMonthReportRespVO reportRespVO : currentMonthReportRespVOList) {
                    bigDecimalUtil.ifIsNUll(reportRespVO);
                    bigDecimalUtil.keepTwoDecimalPlaces(reportRespVO);
                }
            }
        }
        return DataResult.success(currentMonthReportRespVOList);
    }


    @PostMapping("exportCurrentMonthReport")
    @ApiOperation(value = "当月报表下载")
    @LogAnnotation(title = "报表模块", action = "当月报表下载")
    public void exportCurrentMonthReport(@RequestBody @Valid ReportReqVO vo, HttpServletResponse response) {
        List<CurrentMonthReportRespVO> list = new ArrayList<>();
        if (vo.getStationId() != null) {
            //查询电站的装机容量
            Station station = stationService.selectById(vo.getStationId());
            if (station != null) {
                list = reportFormService.getCurrentMonthReport(station.getCapacity(), vo);
                for (CurrentMonthReportRespVO reportRespVO : list) {
                    bigDecimalUtil.ifIsNUll(reportRespVO);
                    bigDecimalUtil.keepTwoDecimalPlaces(reportRespVO);
                }
            }
            //在内存操作，写到浏览器
            ExcelWriter writer = ExcelUtil.getBigWriter();

            //自定义标题别名
            writer.addHeaderAlias("date", "日期");
            writer.addHeaderAlias("powerGeneration", "日发电量");
            writer.addHeaderAlias("income", "上网电量");
            writer.addHeaderAlias("ele", "企业用电量");
            writer.addHeaderAlias("equivalentHours", "等效小时");

            writer.write(list, true);

            if (vo.getBytes() != null) {
                //图片位置放在list数据下2行
                int y = list.size() + 2;
                //写图片字节流
                String[] split = vo.getBytes().split(",");
                byte[] decode = Base64.decode(split[1]);
                writePic(writer, 0, y, decode, HSSFWorkbook.PICTURE_TYPE_PNG);
                //自适应宽度
                AdaptiveWidthUtils.setSizeColumn(writer.getSheet(), 4);
            }
            String excelName = "excel.xls";
            ServletOutputStream out = null;
            try {
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                response.setHeader("content-disposition", "attachment;filename=" + new String(excelName.getBytes("gb2312"), "ISO8859-1"));
                out = response.getOutputStream();
            } catch (Exception e) {
                log.info(e.getMessage());
            } finally {
                writer.flush(out, true);
                // 关闭writer，释放内存
                writer.close();
                //此处记得关闭输出Servlet流
                IoUtil.close(out);
            }
        }
    }

    @PostMapping("historyReport")
    @ApiOperation("历史报表数据")
    public DataResult<List<HistoryReportRespVO>> getHistoryReport(@RequestBody @Valid ReportReqVO vo, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = redisService.getSimpleUserByToken(token);
        //如果 stationId没传 要查所辖电站的数据
        if (StringUtils.isEmpty(vo.getStationId())) {
            vo.setGroupId(simpleUser.getGroupId());
        }
        List<HistoryReportRespVO> list = reportFormService.getHistoryReport(vo);
        for (HistoryReportRespVO reportRespVO : list) {
            bigDecimalUtil.ifIsNUll(reportRespVO);
            bigDecimalUtil.keepTwoDecimalPlaces(reportRespVO);
        }
        return DataResult.success(list);
    }

    @PostMapping("exportHistoryReport")
    @ApiOperation(value = "历史报表下载")
    @LogAnnotation(title = "报表模块", action = "历史报表下载")
    public void exportHistoryReport(@RequestBody @Valid ReportReqVO vo, HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = redisService.getSimpleUserByToken(token);
        //如果 stationId没传 要查所辖电站的数据
        if (StringUtils.isEmpty(vo.getStationId())) {
            vo.setStationId(simpleUser.getGroupId());
        }
        List<HistoryReportRespVO> list = reportFormService.getHistoryReport(vo);
        for (HistoryReportRespVO reportRespVO : list) {
            bigDecimalUtil.ifIsNUll(reportRespVO);
            bigDecimalUtil.keepTwoDecimalPlaces(reportRespVO);
        }
        //在内存操作，写到浏览器
        ExcelWriter writer = ExcelUtil.getBigWriter();
        //自定义标题别名
        writer.addHeaderAlias("date", "日期");
        writer.addHeaderAlias("powerGeneration", "发电量");
        writer.addHeaderAlias("eleTotalFee", "企业用电收益");
        writer.addHeaderAlias("incomeFee", "余电上网收益");
        writer.addHeaderAlias("totalFee", "总收益/元");

        writer.write(list, true);

        if (vo.getBytes() != null && !vo.getBytes().equals("")) {
            //图片位置放在list数据下2行
            int y = list.size() + 2;
            //写图片字节流
            String[] split = vo.getBytes().split(",");
            byte[] decode = Base64.decode(split[1]);
            writePic(writer, 0, y, decode, HSSFWorkbook.PICTURE_TYPE_PNG);
            //自适应宽度
            AdaptiveWidthUtils.setSizeColumn(writer.getSheet(), 4);
        }
        String excelName = "excel.xls";
        ServletOutputStream out = null;
        try {
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("content-disposition", "attachment;filename=" + new String(excelName.getBytes("gb2312"), "ISO8859-1"));
            out = response.getOutputStream();
        } catch (Exception e) {
            log.info(e.getMessage());
        } finally {
            writer.flush(out, true);
            // 关闭writer，释放内存
            writer.close();
            //此处记得关闭输出Servlet流
            IoUtil.close(out);
        }
    }

    public void writePic(ExcelWriter writer, int x, int y, byte[] pictureData, int picType) {

        Sheet sheet = writer.getSheet();
        Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();

        //设置图片单元格位置
        ClientAnchor anchor = drawingPatriarch.createAnchor(0, 0, 255, 255, x, y, x + 1, y + 1);

        //随单元格改变位置和大小
        anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);

        //添加图片
        int pictureIndex = sheet.getWorkbook().addPicture(pictureData, picType);
        Picture picture = drawingPatriarch.createPicture(anchor, pictureIndex);

        //按比例调整图像大小
        picture.resize(0.6);
    }

}

