package com.jjt.biz.controller;

import com.jjt.calc.domain.TwinCalcDay;
import com.jjt.calc.service.ITwinCalcDayService;
import com.jjt.common.core.controller.BaseController;
import com.jjt.common.utils.DateUtils;
import com.jjt.ws.domain.TwinWorkshop;
import com.jjt.ws.domain.TwinWorkshopCalc;
import com.jjt.ws.service.ITwinWorkshopCalcService;
import com.jjt.ws.service.ITwinWorkshopService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * Excel导出控制类
 *
 * @author ruoyi
 */
@Api(tags = "数据导出接口--能耗")
@RestController
@Slf4j
public class ApiEnergyExportController extends BaseController {
    @Resource
    private ITwinWorkshopService wsService;
    @Resource
    private ITwinWorkshopCalcService calcService;
    @Resource
    private ITwinCalcDayService twinCalcDayService;

    @ApiOperation("导出能耗日报")
    @RequestMapping("/api/export/energy-day")
    @CrossOrigin(origins = "*")
    public void energyDayExport(String date, HttpServletResponse response) {
        LocalDate localDate = LocalDate.parse(date);
        TwinWorkshop workshop = wsService.selectTwinWorkshopByWsCode("WS_01");
        List<TwinWorkshopCalc> calcs = calcService.selectTwinWorkshopCalcListByDate(workshop.getWsId(), DateUtils.parseDate(date));
        if (calcs.size() == 0) {
            return;
        }
        TwinWorkshopCalc calc = calcs.get(0);
        List<TwinCalcDay> calcDayList = twinCalcDayService.selectTwinCalcDayListByTime(DateUtils.toDate(localDate), DateUtils.toDate(localDate));

        double kwhA = calcDayList.stream().mapToDouble(d -> d.getKwhA().doubleValue()).sum();
        double kwhB = calcDayList.stream().mapToDouble(d -> d.getKwhB().doubleValue()).sum();
        double kwh = kwhA + kwhB;
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("tpl/energy-day.xlsx"); XSSFWorkbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
            CreationHelper creationHelper = wb.getCreationHelper();
            CellStyle percentStyle = wb.createCellStyle();
            percentStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00%"));
            percentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            CellStyle p2 = wb.createCellStyle();
            p2.setDataFormat(wb.createDataFormat().getFormat("0.00"));
            XSSFCellStyle bk = wb.createCellStyle();
            bk.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
            bk.setFillPattern(FillPatternType.SOLID_FOREGROUND);

            Sheet sheet = wb.getSheetAt(0);
            Cell title = sheet.getRow(0).getCell(0);
            title.setCellValue("经编车间能耗日报（" + date + "）");
            Cell cell2 = sheet.getRow(1).getCell(1);
            cell2.setCellValue(calc.getAValue().add(calc.getBValue()).doubleValue());
            Cell cell3 = sheet.getRow(2).getCell(1);
            cell3.setCellValue(calc.getAValue().doubleValue());
            Cell cell4 = sheet.getRow(3).getCell(1);
            cell4.setCellValue(calc.getBValue().doubleValue());
            Cell cell5 = sheet.getRow(4).getCell(1);
            cell5.setCellValue(kwh);
            Cell cell6 = sheet.getRow(5).getCell(1);
            cell6.setCellValue(kwhA);
            Cell cell7 = sheet.getRow(6).getCell(1);
            cell7.setCellValue(kwhB);
            Sheet bSheet = wb.getSheetAt(1);
            AtomicInteger rowNum = new AtomicInteger(2);
            calcDayList.stream().sorted(Comparator.comparing(TwinCalcDay::getKwh).reversed()).forEach(d -> {
                Row row = bSheet.createRow(rowNum.get());
                Cell[] cells = new Cell[4];
                for (int i = 0; i < cells.length; i++) {
                    cells[i] = row.createCell(i);
                }

                cells[0].setCellValue(d.getDeviceId());
                cells[1].setCellValue(d.getKwh().doubleValue());
                cells[2].setCellValue(d.getKwhA().doubleValue());
                cells[3].setCellValue(d.getKwhB().doubleValue());

                rowNum.getAndIncrement();
            });

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("车间能耗日报" + localDate + ".xlsx", "UTF-8"));
            response.setContentType("application/octet-stream");
            wb.write(outputStream);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @ApiOperation("导出能耗月报")
    @RequestMapping("/api/export/energy-month")
    @CrossOrigin(origins = "*")
    public void energyMonthExport(String date, HttpServletResponse response) {
        date = date.substring(0, 7);
        TwinWorkshop workshop = wsService.selectTwinWorkshopByWsCode("WS_01");
        List<TwinWorkshopCalc> shopList = calcService.selectTwinWorkshopCalcListByMonth(workshop.getWsId(), date);
        Map<Date, TwinWorkshopCalc> shopMap = shopList.stream().collect(Collectors.toMap(TwinWorkshopCalc::getDataDate, o -> o));
        List<TwinCalcDay> dayList = twinCalcDayService.selectTwinCalcDayListByMonth(date);
        Map<Date, List<TwinCalcDay>> dayMap = dayList.stream().collect(Collectors.groupingBy(o -> o.getTime(), LinkedHashMap::new, Collectors.toList()));
        Set<Date> allSet = new TreeSet<>();
        allSet.addAll(shopMap.keySet());
        allSet.addAll(dayMap.keySet());
        double allA = shopList.stream().mapToDouble(d -> d.getAValue().doubleValue()).sum();
        double allB = shopList.stream().mapToDouble(d -> d.getBValue().doubleValue()).sum();
        double all = allA + allB;
        double kwhA = dayList.stream().mapToDouble(d -> d.getKwhA().doubleValue()).sum();
        double kwhB = dayList.stream().mapToDouble(d -> d.getKwhB().doubleValue()).sum();
        double kwh = kwhA + kwhB;

        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("tpl/energy-month.xlsx"); XSSFWorkbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
            CreationHelper creationHelper = wb.getCreationHelper();
            CellStyle percentStyle = wb.createCellStyle();
            percentStyle.setDataFormat(creationHelper.createDataFormat().getFormat("0.00%"));
            percentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            CellStyle p2 = wb.createCellStyle();
            p2.setDataFormat(wb.createDataFormat().getFormat("0.00"));
            XSSFCellStyle bk = wb.createCellStyle();
            bk.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
            bk.setFillPattern(FillPatternType.SOLID_FOREGROUND);

            Sheet sheet = wb.getSheetAt(0);
            Cell title = sheet.getRow(0).getCell(0);
            title.setCellValue("经编车间能耗月报（" + date + "）");
            Cell cell2 = sheet.getRow(1).getCell(1);
            cell2.setCellValue(all);
            Cell cell3 = sheet.getRow(2).getCell(1);
            cell3.setCellValue(allA);
            Cell cell4 = sheet.getRow(3).getCell(1);
            cell4.setCellValue(allB);
            Cell cell5 = sheet.getRow(4).getCell(1);
            cell5.setCellValue(kwh);
            Cell cell6 = sheet.getRow(5).getCell(1);
            cell6.setCellValue(kwhA);
            Cell cell7 = sheet.getRow(6).getCell(1);
            cell7.setCellValue(kwhB);
            Sheet bSheet = wb.getSheetAt(1);
            Cell bTitle = sheet.getRow(0).getCell(0);
            bTitle.setCellValue("月度能耗趋势（" + date + "）");
            AtomicInteger rowNum = new AtomicInteger(3);

            for (Date day : allSet) {
                TwinWorkshopCalc shopCalc = shopMap.get(day);
                List<TwinCalcDay> calcDayList = dayMap.get(day);
                Row row = bSheet.createRow(rowNum.get());
                Cell[] cells = new Cell[7];
                for (int i = 0; i < cells.length; i++) {
                    cells[i] = row.createCell(i);
                }
                double aaa = calcDayList.stream().mapToDouble(d -> d.getKwhA().doubleValue()).sum();
                double bbb = calcDayList.stream().mapToDouble(d -> d.getKwhB().doubleValue()).sum();
                double ttt = aaa + bbb;
                cells[0].setCellValue(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, day));
                if (shopCalc != null) {
                    cells[1].setCellValue(shopCalc.getAValue().add(shopCalc.getBValue()).doubleValue());
                    cells[2].setCellValue(shopCalc.getAValue().doubleValue());
                    cells[3].setCellValue(shopCalc.getBValue().doubleValue());
                }
                cells[4].setCellValue(ttt);
                cells[5].setCellValue(aaa);
                cells[6].setCellValue(bbb);

                rowNum.getAndIncrement();
            }
            dayList.stream().sorted(Comparator.comparing(TwinCalcDay::getKwh).reversed()).forEach(d -> {
            });

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("车间能耗月报" + date + ".xlsx", "UTF-8"));
            response.setContentType("application/octet-stream");
            wb.write(outputStream);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @ApiOperation("能耗统计报表")
    @RequestMapping("/api/export/tmp")
    @CrossOrigin(origins = "*")
    public void tmp(HttpServletResponse response) {
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("tpl/tmp.xlsx"); XSSFWorkbook wb = new XSSFWorkbook(inputStream); OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("能耗统计报表" + DateUtils.dateTimeNow() + ".xlsx", "UTF-8"));
            response.setContentType("application/octet-stream");
            wb.write(outputStream);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
