package com.ruoyi.ems.controller;

import com.huashe.common.domain.AjaxResult;
import com.huashe.common.utils.ListUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.page.PageDomain;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.core.web.page.TableSupport;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.ems.domain.ElecMeterH;
import com.ruoyi.ems.domain.EnergyMeter;
import com.ruoyi.ems.domain.WaterMeterH;
import com.ruoyi.ems.model.ElecConsumptionExportVO;
import com.ruoyi.ems.model.ElecConsumptionVO;
import com.ruoyi.ems.model.QueryMeter;
import com.ruoyi.ems.model.WaterConsumptionExportVO;
import com.ruoyi.ems.model.WaterConsumptionVO;
import com.ruoyi.ems.service.IElecConsumptionService;
import com.ruoyi.ems.service.IWaterConsumptionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 用能统计分析Controller - 重构版本
 *
 * @author ruoyi
 * @date 2024-12-20
 */
@RestController
@RequestMapping("/consumption")
@Api(value = "EnergyConsumptionController", description = "用能统计分析")
public class EnergyConsumptionController extends BaseController {

    @Autowired
    private IElecConsumptionService elecConsumptionService;

    @Autowired
    private IWaterConsumptionService waterConsumptionService;

    /**
     * 查询用电小时计量类型列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/elec/hourTypes")
    @ApiOperation("查询区域用电统计列表")
    public AjaxResult getElecHourTypes(@ApiParam("查询参数") QueryMeter queryMeter) {
        List<String> list = elecConsumptionService.getElecHourTypes(queryMeter);
        return success(list);
    }

    // ==================== 电表计抄表查询 ====================

    /**
     * 查询电表计小时抄表列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/mdev/elec/hour/list")
    @ApiOperation("查询电表小时抄表列表")
    public TableDataInfo getMDevElecList(@ApiParam("查询参数") QueryMeter queryMeter) {
        startPage();
        List<ElecMeterH> list = elecConsumptionService.selectMDevElecConsumptionList(queryMeter);
        return getDataTable(list);
    }

    /**
     * 查询表计小时抄表列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/mdev/elec/hour/summary")
    @ApiOperation("查询电表小时抄表统计")
    public AjaxResult getMDevElecConsumptionSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
        ElecConsumptionVO summary  = elecConsumptionService.selectMDevElecConsumptionSummary(queryMeter);
        return success(summary);
    }

    /**
     * 导出区域用电统计数据
     */
    @RequiresPermissions("ems:consumption:export")
    @Log(title = "区域用电统计", businessType = BusinessType.EXPORT)
    @PostMapping("/mdev/elec/hour/export")
    @ApiOperation("导出区域用电统计数据")
    public void exportMDevElecList(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
        List<ElecMeterH> list = elecConsumptionService.selectMDevElecConsumptionList(queryMeter);
        ExcelUtil<ElecMeterH> util = new ExcelUtil<>(ElecMeterH.class);
        String fileName = String.format("电表抄表_%s_%s.xlsx", queryMeter.getTimeDimension(),
            System.currentTimeMillis());
        util.exportExcel(response, list, fileName);
    }

    // ==================== 区域用电统计 ====================

    /**
     * 查询区域用电统计列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/area/elec/list")
    @ApiOperation("查询区域用电统计列表")
    public TableDataInfo getAreaElecConsumptionList(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(1);

        List<ElecConsumptionVO> list = elecConsumptionService.selectAreaElecConsumptionList(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (queryMeter.getPageNum() - 1) * queryMeter.getPageSize(),
            queryMeter.getPageNum() * queryMeter.getPageSize() - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询区域用电统计汇总
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/area/elec/summary")
    @ApiOperation("查询区域用电统计汇总")
    public AjaxResult getAreaElecConsumptionSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(1);

        ElecConsumptionVO summary = elecConsumptionService.selectAreaElecConsumptionSummary(queryMeter);
        return success(summary);
    }

    /**
     * 导出区域用电统计数据
     */
    @RequiresPermissions("ems:consumption:export")
    @Log(title = "区域用电统计", businessType = BusinessType.EXPORT)
    @PostMapping("/area/elec/export")
    @ApiOperation("导出区域用电统计数据")
    public void exportAreaElecConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(1);

        List<ElecConsumptionVO> list = elecConsumptionService.exportAreaElecConsumptionList(queryMeter);
        // 转换为导出VO
        List<ElecConsumptionExportVO> exportList = elecConsumptionService.convertToElecExportVOList(list,
            queryMeter.getTimeDimension());

        ExcelUtil<ElecConsumptionExportVO> util = new ExcelUtil<>(ElecConsumptionExportVO.class);
        String fileName = String.format("区域用电统计_%s_%s.xlsx", queryMeter.getTimeDimension(),
            System.currentTimeMillis());
        util.exportExcel(response, exportList, fileName);
    }

    /**
     * 查询区域用能统计数据
     *
     * @param queryMeter 查询条件
     * @return
     */
    @GetMapping("/area/elec/hour/list")
    public TableDataInfo getAreaElecHourMeter(QueryMeter queryMeter) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        List<ElecMeterH> list = elecConsumptionService.getAreaElecHourMeter(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (pageNum - 1) * pageSize, pageNum * pageSize - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询区域小时用电明细（按时间序列）
     */
    @GetMapping("/area/elec/hour/byTimeIndex")
    @ApiOperation("查询按时间序列的区域用电统计")
    public AjaxResult getAreaElecByTimeIndex(QueryMeter queryMeter) {
        if (StringUtils.isBlank(queryMeter.getOrderFlag())) {
            queryMeter.setOrderFlag("asc");
        }
        List<ElecMeterH> list = elecConsumptionService.getAreaElecHourMeter(queryMeter);
        return success(list);
    }

    /**
     * 计算时间范围内日平均用电
     *
     * @param queryMeter 支持areaCode、deviceCode、date范围筛选
     * @return EnergyMeter
     */
    @GetMapping("/elec/day/avg")
    @ApiOperation("计算时间范围内日平均用电")
    public AjaxResult getElecDayAvg(@ApiParam("查询参数") QueryMeter queryMeter) {
        EnergyMeter result = elecConsumptionService.selectElecDayAvg(queryMeter);
        return success(result);
    }

    /**
     * 按设备类型查询日用电
     *
     * @param queryMeter 查询条件（startRecTime、areaCode）
     * @return 设备用电列表
     */
    @GetMapping("/elec/sum/device/day")
    @ApiOperation("按设备类型查询日用电")
    public AjaxResult qryDeviceElecByDay(QueryMeter queryMeter) {
        List<EnergyMeter> result = elecConsumptionService.qryDeviceElecByDay(queryMeter);
        return success(result);
    }

    // ==================== 设施用电统计 ====================

    /**
     * 查询设施用电统计列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/facs/elec/list")
    @ApiOperation("查询设施用电统计列表")
    public TableDataInfo getFacsElecConsumptionList(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(2);
        if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
            queryMeter.setFacsCategory("Z");
        }

        List<ElecConsumptionVO> list = elecConsumptionService.selectFacsElecConsumptionList(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (queryMeter.getPageNum() - 1) * queryMeter.getPageSize(),
            queryMeter.getPageNum() * queryMeter.getPageSize() - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询设施用电统计汇总
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/facs/elec/summary")
    @ApiOperation("查询设施用电统计汇总")
    public AjaxResult getFacsElecConsumptionSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(2);
        if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
            queryMeter.setFacsCategory("Z");
        }

        ElecConsumptionVO summary = elecConsumptionService.selectFacsElecConsumptionSummary(queryMeter);
        return success(summary);
    }

    /**
     * 导出设施用电统计数据
     */
    @RequiresPermissions("ems:consumption:export")
    @Log(title = "设施用电统计", businessType = BusinessType.EXPORT)
    @PostMapping("/facs/elec/export")
    @ApiOperation("导出设施用电统计数据")
    public void exportFacsElecConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(2);
        if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
            queryMeter.setFacsCategory("Z");
        }

        List<ElecConsumptionVO> list = elecConsumptionService.exportFacsElecConsumptionList(queryMeter);
        // 转换为导出VO
        List<ElecConsumptionExportVO> exportList = elecConsumptionService.convertToElecExportVOList(list,
            queryMeter.getTimeDimension());

        ExcelUtil<ElecConsumptionExportVO> util = new ExcelUtil<>(ElecConsumptionExportVO.class);
        String fileName = String.format("设施用电统计_%s_%s.xlsx", queryMeter.getTimeDimension(),
            System.currentTimeMillis());
        util.exportExcel(response, exportList, fileName);
    }

    /**
     * 查询设施用能统计数据
     *
     * @param queryMeter 查询条件
     * @return
     */
    @GetMapping("/facs/elec/listFacsMeterHourSta")
    public AjaxResult listFacsMeterHourSta(QueryMeter queryMeter) {
        queryMeter.setMeterCls(45);
        List<ElecConsumptionVO> list = elecConsumptionService.getFacsMeterHourSta(queryMeter);
        return success(list);
    }

    /**
     * 查询设施用能统计数据
     *
     * @param queryMeter 查询条件
     * @return
     */
    @GetMapping("/facs/elec/hour/list")
    public TableDataInfo getFacsElecHourMeter(QueryMeter queryMeter) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        queryMeter.setMeterCls(45);
        List<ElecMeterH> list = elecConsumptionService.getFacsElecHourMeter(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (pageNum - 1) * pageSize, pageNum * pageSize - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    // ==================== 水表计抄表查询 ====================

    /**
     * 查询电表计小时抄表列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/mdev/water/hour/list")
    @ApiOperation("查询水表计小时抄表列表")
    public TableDataInfo getMDevWaterList(@ApiParam("查询参数") QueryMeter queryMeter) {
        startPage();
        List<WaterMeterH> list = waterConsumptionService.selectMDevWaterConsumptionList(queryMeter);
        return getDataTable(list);
    }

    /**
     * 查询表计小时抄表列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/mdev/water/hour/summary")
    @ApiOperation("查询水表计小时抄表统计")
    public AjaxResult getMDevWaterConsumptionSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
        WaterConsumptionVO summary  = waterConsumptionService.selectMDevWaterConsumptionSummary(queryMeter);
        return success(summary);
    }

    /**
     * 导出区域用电统计数据
     */
    @RequiresPermissions("ems:consumption:export")
    @Log(title = "区域用水统计", businessType = BusinessType.EXPORT)
    @PostMapping("/mdev/water/hour/export")
    @ApiOperation("导出区域用水统计数据")
    public void exportMDevWaterList(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
        List<WaterMeterH> list = waterConsumptionService.selectMDevWaterConsumptionList(queryMeter);
        ExcelUtil<WaterMeterH> util = new ExcelUtil<>(WaterMeterH.class);
        String fileName = String.format("水表抄表_%s_%s.xlsx", queryMeter.getTimeDimension(),
            System.currentTimeMillis());
        util.exportExcel(response, list, fileName);
    }

    // ==================== 区域用水统计 ====================

    /**
     * 查询区域小时用水明细
     */
    @GetMapping("/area/water/hour/list")
    @ApiOperation("查询区域小时用水明细")
    public TableDataInfo getAreaWaterHourMeter(QueryMeter queryMeter) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();

        List<WaterMeterH> list = waterConsumptionService.getAreaWaterHourMeter(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (pageNum - 1) * pageSize, pageNum * pageSize - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询设施小时用水明细
     */
    @GetMapping("/facs/water/hour/list")
    @ApiOperation("查询设施小时用水明细")
    public TableDataInfo getFacsWaterHourMeter(QueryMeter queryMeter) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();

        queryMeter.setMeterCls(70);
        List<WaterMeterH> list = waterConsumptionService.getFacsWaterHourMeter(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (pageNum - 1) * pageSize, pageNum * pageSize - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询设施小时用水汇总统计
     */
    @GetMapping("/facs/water/listFacsMeterHourSta")
    @ApiOperation("查询设施小时用水汇总")
    public AjaxResult listFacsWaterMeterHourSta(QueryMeter queryMeter) {
        queryMeter.setMeterCls(70);
        List<WaterConsumptionVO> list = waterConsumptionService.getFacsWaterHourSta(queryMeter);
        return success(list);
    }

    /**
     * 查询区域用水统计列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/area/water/list")
    @ApiOperation("查询区域用水统计列表")
    public TableDataInfo getAreaWaterConsumptionList(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(1);

        List<WaterConsumptionVO> list = waterConsumptionService.selectAreaWaterConsumptionList(queryMeter);
        int total = list.size();
        list = ListUtils.subList(list, (queryMeter.getPageNum() - 1) * queryMeter.getPageSize(),
            queryMeter.getPageNum() * queryMeter.getPageSize() - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询区域用水统计汇总
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/area/water/summary")
    @ApiOperation("查询区域用水统计汇总")
    public AjaxResult getAreaWaterConsumptionSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(1);

        WaterConsumptionVO summary = waterConsumptionService.selectAreaWaterConsumptionSummary(queryMeter);
        return success(summary);
    }

    /**
     * 导出区域用水统计数据
     */
    @RequiresPermissions("ems:consumption:export")
    @Log(title = "区域用水统计", businessType = BusinessType.EXPORT)
    @PostMapping("/area/water/export")
    @ApiOperation("导出区域用水统计数据")
    public void exportAreaWaterConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(1);

        List<WaterConsumptionVO> list = waterConsumptionService.exportAreaWaterConsumptionList(queryMeter);
        // 转换为导出VO
        List<WaterConsumptionExportVO> exportList = waterConsumptionService.convertToWaterExportVOList(list,
            queryMeter.getTimeDimension());

        ExcelUtil<WaterConsumptionExportVO> util = new ExcelUtil<>(WaterConsumptionExportVO.class);
        String fileName = String.format("区域用水统计_%s_%s.xlsx", queryMeter.getTimeDimension(),
            System.currentTimeMillis());
        util.exportExcel(response, exportList, fileName);
    }

    /**
     * 查询按时间序列(小时)的用水统计
     */
    @GetMapping("/area/water/hour/byTimeIndex")
    @ApiOperation("查询按时间序列的用水统计")
    public AjaxResult getAreaWaterByTimeIndex(
        @RequestParam(name = "startRecTime") String startRecTime,
        @RequestParam(name = "endRecTime", required = false) String endRecTime,
        @RequestParam(name = "areaCode", required = false) String areaCode) {

        QueryMeter queryMeter = new QueryMeter();
        queryMeter.setStartRecTime(startRecTime);
        queryMeter.setEndRecTime(endRecTime != null ? endRecTime : startRecTime + " 23:59:59");
        queryMeter.setAreaCode(areaCode);
        queryMeter.setObjCode(areaCode);

        List<WaterMeterH> list = waterConsumptionService.getAreaWaterHourMeter(queryMeter);
        return success(list);
    }

    // ==================== 设施用水统计 ====================

    /**
     * 查询设施用水统计列表
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/facs/water/list")
    @ApiOperation("查询设施用水统计列表")
    public TableDataInfo getFacsWaterConsumptionList(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(2);
        if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
            queryMeter.setFacsCategory("Z");
        }

        List<WaterConsumptionVO> list = waterConsumptionService.selectFacsWaterConsumptionList(queryMeter);

        int total = list.size();
        list = ListUtils.subList(list, (queryMeter.getPageNum() - 1) * queryMeter.getPageSize(),
            queryMeter.getPageNum() * queryMeter.getPageSize() - 1);

        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(200);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(total);

        return rspData;
    }

    /**
     * 查询设施用水统计汇总
     */
    @RequiresPermissions("ems:consumption:list")
    @GetMapping("/facs/water/summary")
    @ApiOperation("查询设施用水统计汇总")
    public AjaxResult getFacsWaterConsumptionSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(2);
        if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
            queryMeter.setFacsCategory("Z");
        }

        WaterConsumptionVO summary = waterConsumptionService.selectFacsWaterConsumptionSummary(queryMeter);
        return success(summary);
    }

    /**
     * 导出设施用水统计数据
     */
    @RequiresPermissions("ems:consumption:export")
    @Log(title = "设施用水统计", businessType = BusinessType.EXPORT)
    @PostMapping("/facs/water/export")
    @ApiOperation("导出设施用水统计数据")
    public void exportFacsWaterConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
        validateAndSetDefaults(queryMeter);
        queryMeter.setObjType(2);
        if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
            queryMeter.setFacsCategory("Z");
        }

        List<WaterConsumptionVO> list = waterConsumptionService.exportFacsWaterConsumptionList(queryMeter);
        // 转换为导出VO
        List<WaterConsumptionExportVO> exportList = waterConsumptionService.convertToWaterExportVOList(list,
            queryMeter.getTimeDimension());

        ExcelUtil<WaterConsumptionExportVO> util = new ExcelUtil<>(WaterConsumptionExportVO.class);
        String fileName = String.format("设施用水统计_%s_%s.xlsx", queryMeter.getTimeDimension(),
            System.currentTimeMillis());
        util.exportExcel(response, exportList, fileName);
    }

    // ==================== 参数校验方法 ====================

    /**
     * 校验并设置默认参数
     */
    private void validateAndSetDefaults(QueryMeter queryMeter) {
        if (queryMeter == null) {
            throw new IllegalArgumentException("查询参数不能为空");
        }

        // 设置默认时间维度
        if (StringUtils.isBlank(queryMeter.getTimeDimension())) {
            queryMeter.setTimeDimension("month");
        }

        // 设置默认排序
        if (StringUtils.isBlank(queryMeter.getOrderFlag())) {
            queryMeter.setOrderFlag("desc");
        }
    }
}