package com.nantian.cloud.jljc.controller;

import cn.hutool.poi.excel.ExcelBase;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nantian.cloud.jljc.entity.*;
import com.nantian.cloud.jljc.service.*;
import com.nantian.cloud.jljc.vo.dischargeEnergy.DischargeEnergyConstructionVo;
import com.nantian.cloud.jljc.vo.dischargeEnergy.DischargeEnergyPlanVo;
import com.nantian.cloud.jljc.vo.dischargeEnergy.DischargeEnergyStockVo;
import com.nantian.sc.cloud.common.core.util.R;
import com.nantian.sc.cloud.common.log.annotation.SysLog;
import com.nantian.sc.cloud.common.minio.MinioProperties;
import com.nantian.sc.cloud.common.minio.service.MinioTemplate;
import com.nantian.sc.cloud.common.security.annotation.Inner;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import io.minio.MinioClient;
import io.minio.errors.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.xmlpull.v1.XmlPullParserException;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;


/**
 * 两高项目存量
 *
 * @date 2022-02-15
 */
@CrossOrigin
@RestController
@AllArgsConstructor
@RequestMapping("/dischargeEnergyStock")
public class DischargeEnergyStockController {
    private final DischargeEnergyStockService dischargeEnergyStockService;
    @Autowired
    private DischargeEnergyConstructionService dischargeEnergyConstructionService;
    @Autowired
    private DischargeEnergyPlanService dischargeEnergyPlanService;
    @Autowired
    private MinioTemplate minioTemplate;
    @Autowired
    private DischargeEnergyProductService dischargeEnergyProductService;
    @Autowired
    private DischargeEnergyIndexService dischargeEnergyIndexService;

    /**
     * 分页查询
     *
     * @param
     * @return
     */
    @GetMapping("/getByEpc")
    @SysLog("按企业查询两高项目存量")
    public R getByEpc(DischargeEnergyStock dischargeEnergyStock) {
        QueryWrapper<DischargeEnergyStock> queryWrapper = new QueryWrapper<DischargeEnergyStock>();
        queryWrapper.eq("enterprise_code",dischargeEnergyStock.getEnterpriseCode());
        queryWrapper.eq("year",dischargeEnergyStock.getYear());
        queryWrapper.eq("quarter",dischargeEnergyStock.getQuarter());
        List<DischargeEnergyStock> list = dischargeEnergyStockService.list(queryWrapper);
        return R.ok(list);
    }

    /**
     * 根据两高项目存量社会信用代码查询
     *
     * @param page      分页对象
     * @return
     */
    @GetMapping("/page")
    @SysLog("分页查询两高项目存量")
    public R getStockPage(Page page, DischargeEnergyStock dischargeEnergyStock) {
        dischargeEnergyStock.setDelFlag("1");  //筛选未删除项
        return R.ok(dischargeEnergyStockService.getPageData(page,dischargeEnergyStock));
    }

    /**
     * 查询项目、产品、指标
     *
     * @param page      分页对象
     * @return
     */
    @GetMapping("/getStockProductIndex")
    @SysLog("查询项目、产品、指标")
    public R getStockProductIndex(Page page, DischargeEnergyStock dischargeEnergyStock) {
        dischargeEnergyStock.setDelFlag("1");  //筛选未删除项
        return R.ok(dischargeEnergyStockService.getStockProductIndex(page,dischargeEnergyStock));
    }

    /**
     * 分页查询
     *
     * @param
     * @return
     */
    @GetMapping("/getById")
    @SysLog("根据id查询两高项目存量")
    public R getById(String id) {
        return R.ok(dischargeEnergyStockService.getById(id));
    }

    /**
     * 两高项目存量添加
     */
    @PostMapping("/save")
    @SysLog("新增两高项目存量")
    public R save(@RequestBody String s){
//        ScUser u= SecurityUtils.getUser();
//        if(u.getId()!=null){
//            dischargeEnergyStock.setUserid(u.getId());
//        }
//        if (dischargeEnergyStock.getItemLocation() != null) {
//            dischargeEnergyStock.setDeptId(Integer.parseInt(dischargeEnergyStock.getItemLocation()));
//        }
//        dischargeEnergyStock.setDelFlag("1");
//        dischargeEnergyStock.setUpdateTime(new Date());
//        dischargeEnergyStockService.save(dischargeEnergyStock)
        return R.ok(dischargeEnergyStockService.addStock(s));
    }

    /**
     * 两高项目存量修改
     */
    @PostMapping("/edit")
    @SysLog("修改两高项目存量")
    public R edit(@RequestBody DischargeEnergyStock dischargeEnergyStock){
        return R.ok(dischargeEnergyStockService.updateById(dischargeEnergyStock));
    }

    /**
     * 按照州市统计数据
     */
    @PostMapping("/statisticsCity")
    @SysLog("按照州市统计两高项目存量")
    public R statistics(@RequestBody DischargeEnergyStock dischargeEnergyStock){
        List<DischargeEnergyStockVo> data = dischargeEnergyStockService.getData(dischargeEnergyStock);
        return R.ok(data);
    }

    /**
     * 按照州市统计数量能耗
     */
    @PostMapping("/statisticsNumAndTce")
    @SysLog("按照州市统计两高项目存量-数量能耗")
    public R statisticsNumAndTce(@RequestBody DischargeEnergyStock dischargeEnergyStock){
        List<Map<String, Object>> data = dischargeEnergyStockService.getNumAndTceData(dischargeEnergyStock);
        return R.ok(data);
    }

    /**
     * 按照行业统计数量能耗
     */
    @PostMapping("/industryNumAndTce")
    @SysLog("按照行业统计两高项目存量")
    public R industryNumAndTce(@RequestBody DischargeEnergyStock dischargeEnergyStock){
        List<Map<String, Object>> data = dischargeEnergyStockService.getindustryNumAndTce(dischargeEnergyStock);
        return R.ok(data);
    }

    /**
     * 导出Excel
     */
    @GetMapping("/excel")
    @SysLog("导出两高项目存量")
    @ResponseBody
    public R excel (DischargeEnergyStock dischargeEnergyStock,HttpServletResponse response) throws IOException {

        try {
            List<DischargeEnergyStockVo> data1 = dischargeEnergyStockService.getData(dischargeEnergyStock);
            writeExcel(response, data1);
        } catch (Exception e) {
            System.out.println(e);
        }
        return null;
    }

    private void writeExcel(HttpServletResponse response, List<DischargeEnergyStockVo> data1) throws InvalidPortException, InvalidEndpointException, IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidArgumentException, InternalException, NoResponseException, InvalidBucketNameException, XmlPullParserException, ErrorResponseException {
        File newFile = new File("F:\\能耗数据处理\\附件1：云南省“两高”清单模板.xlsx");
        InputStream is = minioTemplate.getObject("jljc", "云南省存量“两高”清单模板.xlsx");
//        InputStream is = null;
        XSSFWorkbook xSSFWorkbook = null;
        XSSFSheet xSSFSheet = null;

        //组装合并单元格数据
//        int[] spanArr = {};
        List<Integer> list1 = new ArrayList<Integer>();
        int pos = 0;
        for (int i = 0; i < data1.size(); i++) {
            if (i == 0) {
                list1.add(1);
                pos = 0;
            } else {
                if (Objects.equals(data1.get(i).getId(),data1.get(i-1).getId())) {
                    list1.set(pos,list1.get(pos) + 1);
                    list1.add(0);
                } else {
                    // 不相等push 1
                    list1.add(1);
                    pos = i;
                }
            }
        }
        try {
//            is = new FileInputStream(newFile);
            xSSFWorkbook = new XSSFWorkbook(is);
            //获取第一个sheet
            xSSFSheet = xSSFWorkbook.getSheetAt(0);

        } catch (Exception e1) {
            e1.printStackTrace();
        }

        if (xSSFSheet != null) {
            try {
                //写数据
//                FileOutputStream fos = new FileOutputStream(newFile);
                XSSFFont font = xSSFWorkbook.createFont();
                XSSFFont font1 = xSSFWorkbook.createFont();
                CellStyle style = xSSFWorkbook.createCellStyle();
                CellStyle style1 = xSSFWorkbook.createCellStyle();
                font.setFontName("方正仿宋_GBK");
                font1.setFontName("Times New Roman");
                style.setFont(font);
                style1.setFont(font1);
                style.setWrapText(true);//自動換行
                style1.setWrapText(true);//自動換行
                style.setVerticalAlignment(style.getVerticalAlignmentEnum().CENTER);//设置居中
                style.setAlignment(HorizontalAlignment.CENTER);
                style1.setVerticalAlignment(style.getVerticalAlignmentEnum().CENTER);//设置居中
                style1.setAlignment(HorizontalAlignment.CENTER);
                style.setBorderBottom(BorderStyle.THIN);//边框
                style.setBorderLeft(BorderStyle.THIN);
                style.setBorderRight(BorderStyle.THIN);
                style.setBorderTop(BorderStyle.THIN);
                style1.setBorderBottom(BorderStyle.THIN);
                style1.setBorderLeft(BorderStyle.THIN);
                style1.setBorderRight(BorderStyle.THIN);
                style1.setBorderTop(BorderStyle.THIN);

                //构建每行的数据内容
                int rowNum = 4;
                for (DischargeEnergyStockVo data : data1) {
                    if (data == null) {
                        continue;
                    }
                    //输出行数据
                    Row row = xSSFSheet.createRow(rowNum++);

//                    if (list1.get(rowNum-4)>0){
//                        CellRangeAddress region = new CellRangeAddress(list1.get(rowNum-4), 2, 0, 0);
//                    }else {
//                        CellRangeAddress region = new CellRangeAddress(0, 0, 0, 0);
//                    }
                    if (list1.get(rowNum-5)>1 && rowNum<=data1.size()+4){
                        int a = (rowNum+list1.get(rowNum-5))-2;
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 0, 0));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 1, 1));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 2, 2));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 3, 3));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 4, 4));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 5, 5));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 6, 6));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 7, 7));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 12, 12));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 13, 13));
//                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 23, 23));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 24, 24));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 25, 25));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 26, 26));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 27, 27));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 28, 28));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 29, 29));
                        xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, 30, 30));
                    }


                    int cellNum = 0;
                    Cell cell;
                    // 序号
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getIndex() ? "" : data.getIndex());
                    cell.setCellStyle(style1);
                    // 组织机构代码
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnterpriseCode() ? "" : data.getEnterpriseCode());
                    cell.setCellStyle(style1);
                    // 两高项目存量名称
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnterpriseName() ? "" : data.getEnterpriseName());
                    cell.setCellStyle(style);
                    // 所在州市
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getMeaning2() ? "" : data.getMeaning2());
                    cell.setCellStyle(style);
                    // 行业类别
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getIndustryClassName() ? "" : data.getIndustryClassName());
                    cell.setCellStyle(style);
                    // 大类代码
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getIndustryTypeCode() ? "" : data.getIndustryTypeCode());
                    cell.setCellStyle(style1);
                    // 小类代码
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getIndustrySubclassCode() ? "" : data.getIndustrySubclassCode());
                    cell.setCellStyle(style1);
                    // 两高项目存量运行状态
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnterpriseState() ? "" : data.getEnterpriseState());
                    cell.setCellStyle(style);
                    // 节能审查机关
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyOffice() ? "" : data.getEnergyOffice());
                    cell.setCellStyle(style);
                    // 审查完成时间
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyTime() ? "" : data.getEnergyTime());
                    cell.setCellStyle(style);
                    // 节能审查批复文号
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyNumber() ? "" : data.getEnergyNumber());
                    cell.setCellStyle(style);
                    // 工业总产值(当年价)(万元)
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductionValue() ? "" : data.getProductionValue());
                    cell.setCellStyle(style1);
                    // 是否存在原料用能（是/否）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyRaw() ? "" : data.getEnergyRaw());
                    cell.setCellStyle(style1);
                    // 原料用能（万吨标准煤）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyRawValue() ? "" : data.getEnergyRawValue());
                    cell.setCellStyle(style1);
                    // 产品
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductName() ? "" : data.getProductName());
                    cell.setCellStyle(style);
                    // 设计产能（吨/千瓦时/重量箱等）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getCapacityDesign() ? "" : data.getCapacityDesign());
                    cell.setCellStyle(style1);
                    // 2021年实际产量（吨/千瓦时/重量箱等）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductOutput1() ? "" : data.getProductOutput1());
                    cell.setCellStyle(style1);
                    // 2022年预计实际产量（吨/千瓦时/重量箱等）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductOutput2() ? "" : data.getProductOutput2());
                    cell.setCellStyle(style1);
                    // 2023年预计实际产量（吨/千瓦时/重量箱等）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductOutput3() ? "" : data.getProductOutput3());
                    cell.setCellStyle(style1);
                    // 2024年预计实际产量（吨/千瓦时/重量箱等）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductOutput4() ? "" : data.getProductOutput4());
                    cell.setCellStyle(style1);
                    // 2025年预计实际产量（吨/千瓦时/重量箱等）
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductOutput5() ? "" : data.getProductOutput5());
                    cell.setCellStyle(style1);
                    // 指标名称
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getIndexName() ? "" : data.getIndexName());
                    cell.setCellStyle(style1);
                    // 指标值
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductEnergy() ? "" : data.getProductEnergy());
                    cell.setCellStyle(style1);
                    // 指标单位
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getIndexUnit() ? "" : data.getIndexUnit());
                    cell.setCellStyle(style1);
                    // 2020年综合能源消费量当量值
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyConsumptionLastTwoDl() ? "" : data.getEnergyConsumptionLastTwoDl());
                    cell.setCellStyle(style1);
                    // 2020年综合能源消费量等价值
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyConsumptionLastTwoDj() ? "" : data.getEnergyConsumptionLastTwoDj());
                    cell.setCellStyle(style1);
                    // 2021年综合能源消费量当量值
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyConsumptionLastDl() ? "" : data.getEnergyConsumptionLastDl());
                    cell.setCellStyle(style1);
                    // 2021年综合能源消费量等价值
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergyConsumptionLastDj() ? "" : data.getEnergyConsumptionLastDj());
                    cell.setCellStyle(style1);
                    // 工业和信息化厅确认是/否属于高耗能项目
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getMinistryState() ? "" : data.getMinistryState());
                    cell.setCellStyle(style);
                    // 生态环境厅确认是/否属于高排放项目
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEcologyState() ? "" : data.getEcologyState());
                    cell.setCellStyle(style);
                    // 备注
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getRemark() ? "" : data.getRemark());
                    cell.setCellStyle(style);
                }

                OutputStream output = response.getOutputStream(); // 读取的文件路径
//                response.reset();
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("云南省“两高”清单.xlsx", "UTF-8"));
                response.setCharacterEncoding("UTF-8");
//                response.setContentType("application/x-msdownload");
                response.setContentType("charset=GBK");
//                OutputStream output = response.getOutputStream(); // 读取的文件路径
                xSSFWorkbook.write(output);
                //output.flush();
                output.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != is) {
                        is.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }






}
