package com.evobms.project.system.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
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.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.evobms.framework.aspectj.lang.annotation.Log;
import com.evobms.framework.aspectj.lang.enums.BusinessType;
import com.evobms.project.system.domain.BmsDevices;
import com.evobms.project.system.service.IBmsDevicesService;
import com.evobms.framework.web.controller.BaseController;
import com.evobms.framework.web.domain.AjaxResult;
import com.evobms.common.utils.poi.ExcelUtil;
import com.evobms.framework.web.page.TableDataInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.evobms.project.vehicledata.dto.DeviceRealtimeDTO;
import com.evobms.project.vehicledata.dto.NameValueDTO;
import com.evobms.project.vehicledata.dto.DeviceRealtimeDTO.SystemStatusSection;
import com.evobms.project.vehicledata.dto.DeviceRealtimeDTO.RunStatusSection;
import com.evobms.project.vehicledata.dto.DeviceRealtimeDTO.ChargeSection;
import com.evobms.project.vehicledata.dto.DeviceRealtimeDTO.StatisticsSection;
import com.evobms.project.vehicledata.dto.LineSeriesDTO;
import com.evobms.project.vehicledata.dto.TimePointDTO;
import com.evobms.project.vehicledata.service.IVehicleDataService;
import com.evobms.project.vehicledata.domain.VehicleData;
import com.evobms.project.battery.service.IExtremeValuesService;
import com.evobms.project.battery.domain.ExtremeValues;
import com.evobms.project.bms.service.*;
import com.evobms.project.bms.domain.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.stream.Collectors;

/**
 * BBOX管理Controller
 *
 * @author 田志阳
 * @date 2025-11-15
 */
@RestController
@RequestMapping("/devices/devices")
@Api(tags = "BBOX设备管理")
public class BmsDevicesController extends BaseController
{
    @Autowired
    private IBmsDevicesService bmsDevicesService;

    /**
     * 查询BBOX管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:devices:list')")
    @GetMapping("/list")
    @ApiOperation("查询BBOX设备列表")
    public TableDataInfo list(BmsDevices bmsDevices)
    {
        startPage();
        List<BmsDevices> list = bmsDevicesService.selectBmsDevicesList(bmsDevices);
        return getDataTable(list);
    }

    /**
     * 导出BBOX管理列表
     */
    @PreAuthorize("@ss.hasPermi('system:devices:export')")
    @Log(title = "BBOX管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation("导出BBOX设备列表")
    public void export(HttpServletResponse response, BmsDevices bmsDevices)
    {
        List<BmsDevices> list = bmsDevicesService.selectBmsDevicesList(bmsDevices);
        ExcelUtil<BmsDevices> util = new ExcelUtil<BmsDevices>(BmsDevices.class);
        util.exportExcel(response, list, "BBOX管理数据");
    }

    /**
     * 获取BBOX管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:devices:query')")
    @GetMapping(value = "/{id}")
    @ApiOperation("获取BBOX设备详细信息")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return success(bmsDevicesService.selectBmsDevicesById(id));
    }

    @Autowired private IVehicleDataService vehicleDataService;
    @Autowired private IExtremeValuesService extremeValuesService;
    @Autowired private IBmsSystemStatusService bmsSystemStatusService;
    @Autowired private IBmsChargeDetailService bmsChargeDetailService;
    @Autowired private IBmsChargeTemperatureService bmsChargeTemperatureService;
    @Autowired private IBmsVoltageChannelDataService bmsVoltageChannelDataService;
    @Autowired private IBmsSopDataService bmsSopDataService;

    @GetMapping("/realtime/{deviceId}")
    @ApiOperation("设备实时数据")
    public AjaxResult realtime(@PathVariable("deviceId") String deviceId) {
        DeviceRealtimeDTO dto = new DeviceRealtimeDTO();
        dto.setDeviceId(deviceId);
        VehicleData vd = vehicleDataService.selectLatestByDeviceId(deviceId);
        ExtremeValues ev = extremeValuesService.selectLatestByDeviceId(deviceId);
        SystemStatusSection sys = new SystemStatusSection();
        if (vd != null) {
            sys.setTotalVoltage(vd.getTotalVoltage());
            sys.setTotalCurrent(vd.getTotalCurrent());
            sys.setSoc(vd.getSoc());
        }
        if (ev != null) {
            sys.setMaxCellVoltage(ev.getMaxVoltageValue());
            sys.setMaxCellPos(ev.getMaxVoltageSubsystemNo() == null || ev.getMaxVoltageBatteryNo() == null ? null :
                    ev.getMaxVoltageSubsystemNo() + "-" + ev.getMaxVoltageBatteryNo());
            sys.setMinCellVoltage(ev.getMinVoltageValue());
            sys.setMinCellPos(ev.getMinVoltageSubsystemNo() == null || ev.getMinVoltageBatteryNo() == null ? null :
                    ev.getMinVoltageSubsystemNo() + "-" + ev.getMinVoltageBatteryNo());
            sys.setMaxTemp(ev.getMaxTempValue());
            sys.setMaxTempPos(ev.getMaxTempSubsystemNo() == null || ev.getMaxTempProbeNo() == null ? null :
                    ev.getMaxTempSubsystemNo() + "-" + ev.getMaxTempProbeNo());
            sys.setMinTemp(ev.getMinTempValue());
            sys.setMinTempPos(ev.getMinTempSubsystemNo() == null || ev.getMinTempProbeNo() == null ? null :
                    ev.getMinTempSubsystemNo() + "-" + ev.getMinTempProbeNo());
        }
        dto.setSystemStatus(sys);

        RunStatusSection run = new RunStatusSection();
        if (vd != null) {
            run.setChargingStatus(vd.getChargingStatus());
        }
        BmsSystemStatus ss = bmsSystemStatusService.lambdaQuery()
                .eq(BmsSystemStatus::getDeviceId, deviceId)
                .orderByDesc(BmsSystemStatus::getCreateTime).last("limit 1").one();
        if (ss != null) {
            run.setRelayStatus(ss.getRelayStatus());
            run.setOnaaccStatus(ss.getOnaaccStatus());
            run.setResetCount(ss.getResetCount());
            run.setCycleCount(ss.getCycleCount());
            run.setSample25v(ss.getSample25v());
            run.setSample5v(ss.getSample5v());
        }
        dto.setRunStatus(run);

        ChargeSection chg = new ChargeSection();
        BmsChargeDetail cd = bmsChargeDetailService.lambdaQuery()
                .eq(BmsChargeDetail::getDeviceId, deviceId)
                .orderByDesc(BmsChargeDetail::getCreateTime).last("limit 1").one();
        if (cd != null) {
            chg.setAcChargeCurrent(cd.getAcChargeCurrent());
            chg.setAcChargeVoltage(cd.getAcChargeVoltage());
            chg.setDcChargeCurrent(cd.getDcChargeCurrent());
            chg.setDcChargeVoltage(cd.getDcChargeVoltage());
            chg.setChargeTime(cd.getChargeTime());
            chg.setAcStopCode(cd.getAcStopCode());
            chg.setDcStopCode(cd.getDcStopCode());
            chg.setAcCpValue(cd.getAcCpValue());
            chg.setAcGunResistance(cd.getAcGunResistance());
            chg.setChargingStage(cd.getChargingStage());
            chg.setAcStage(cd.getAcStage());
            chg.setDcStage(cd.getDcStage());
        }
        dto.setCharge(chg);

        StatisticsSection stat = new StatisticsSection();
        if (ss != null) {
            stat.setCycleCount(ss.getCycleCount());
        }
        stat.setTotalRunHours(0L);
        stat.setTotalChargeHours(0L);
        stat.setTotalDischargeHours(0L);
        dto.setStatistics(stat);

        List<BmsChargeTemperature> temps = bmsChargeTemperatureService.lambdaQuery()
                .eq(BmsChargeTemperature::getDeviceId, deviceId)
                .orderByDesc(BmsChargeTemperature::getCreateTime).last("limit 8").list();
        List<NameValueDTO> tempItems = new ArrayList<>();
        if (temps != null) {
            String ts = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            for (BmsChargeTemperature t : temps) {
                NameValueDTO nv = new NameValueDTO();
                nv.setName("T" + t.getTempIndex());
                nv.setValue(t.getTemperature() == null ? 0 : t.getTemperature().longValue());
                nv.setCreateTime(ts);
                tempItems.add(nv);
            }
        }
        dto.setTemperatures(tempItems);

        List<BmsVoltageChannelData> chs = bmsVoltageChannelDataService.lambdaQuery()
                .eq(BmsVoltageChannelData::getDeviceId, deviceId)
                .orderByDesc(BmsVoltageChannelData::getCreateTime).last("limit 16").list();
        List<NameValueDTO> voltItems = new ArrayList<>();
        if (chs != null) {
            String ts = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            for (BmsVoltageChannelData c : chs) {
                NameValueDTO nv = new NameValueDTO();
                nv.setName((c.getChannelType() == null ? "CH" : c.getChannelType()) + "-" + c.getChannelIndex());
                nv.setValue(c.getVoltage() == null ? 0 : c.getVoltage().longValue());
                nv.setCreateTime(ts);
                voltItems.add(nv);
            }
        }
        dto.setVoltages(voltItems);

        dto.setFaults(new ArrayList<>());
        // 折线图：最近24小时（按createTime过滤），默认RTP-1与T1
        Date now = new Date();
        Date begin = new Date(now.getTime() - 24L * 3600_000L);
        List<BmsVoltageChannelData> vtrend = bmsVoltageChannelDataService.lambdaQuery()
                .eq(BmsVoltageChannelData::getDeviceId, deviceId)
                .eq(BmsVoltageChannelData::getChannelType, "RTP")
                .eq(BmsVoltageChannelData::getChannelIndex, 1)
                .ge(BmsVoltageChannelData::getCreateTime, begin)
                .le(BmsVoltageChannelData::getCreateTime, now)
                .orderByAsc(BmsVoltageChannelData::getCreateTime)
                .list();
        java.text.SimpleDateFormat f = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<TimePointDTO> vpoints = new ArrayList<>();
        for (BmsVoltageChannelData it : vtrend) {
            TimePointDTO p = new TimePointDTO();
            p.setTime(it.getCreateTime() == null ? null : f.format(it.getCreateTime()));
            p.setValue(it.getVoltage());
            vpoints.add(p);
        }
        LineSeriesDTO vseries = new LineSeriesDTO();
        vseries.setName("RTP-1");
        vseries.setPoints(vpoints);
        dto.setVoltageTrend(java.util.Collections.singletonList(vseries));

        List<BmsChargeTemperature> ttrend = bmsChargeTemperatureService.lambdaQuery()
                .eq(BmsChargeTemperature::getDeviceId, deviceId)
                .eq(BmsChargeTemperature::getTempIndex, 1)
                .ge(BmsChargeTemperature::getCreateTime, begin)
                .le(BmsChargeTemperature::getCreateTime, now)
                .orderByAsc(BmsChargeTemperature::getCreateTime)
                .list();
        List<TimePointDTO> tpoints = new ArrayList<>();
        for (BmsChargeTemperature it : ttrend) {
            TimePointDTO p = new TimePointDTO();
            p.setTime(it.getCreateTime() == null ? null : f.format(it.getCreateTime()));
            p.setValue(it.getTemperature());
            tpoints.add(p);
        }
        LineSeriesDTO tseries = new LineSeriesDTO();
        tseries.setName("T1");
        tseries.setPoints(tpoints);
        dto.setTemperatureTrend(java.util.Collections.singletonList(tseries));
        return success(dto);
    }

    /**
     * 新增BBOX管理
     */
    @PreAuthorize("@ss.hasPermi('system:devices:add')")
    @Log(title = "BBOX管理", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation("新增BBOX设备")
    public AjaxResult add(@RequestBody BmsDevices bmsDevices)
    {
        return toAjax(bmsDevicesService.insertBmsDevices(bmsDevices));
    }

    /**
     * 修改BBOX管理
     */
    @PreAuthorize("@ss.hasPermi('system:devices:edit')")
    @Log(title = "BBOX管理", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("修改BBOX设备")
    public AjaxResult edit(@RequestBody BmsDevices bmsDevices)
    {
        return toAjax(bmsDevicesService.updateBmsDevices(bmsDevices));
    }

    /**
     * 删除BBOX管理
     */
    @PreAuthorize("@ss.hasPermi('system:devices:remove')")
    @Log(title = "BBOX管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation("删除BBOX设备")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        return toAjax(bmsDevicesService.deleteBmsDevicesByIds(ids));
    }
}
