<template>
  <div class="div-container">
    <div class="sidebar">
<!--      左侧树型列表-->
      <el-card class="box-card" shadow="never">
        <template #header>
          <div class="card-header">
            <span>资源列表</span>
            <el-button link type="primary" @click="fetchData">刷新</el-button>
          </div>
        </template>
        <el-input v-model="filterText" placeholder="输入关键字过滤" prefix-icon="Search" style="margin-bottom: 15px" />
        <el-tree
          ref="treeRef"
          :data="treeData"
          :props="defaultProps"
          :filter-node-method="filterNode"
          node-key="id"
          default-expand-all
          highlight-current
          @node-click="handleNodeClick"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <el-icon v-if="data.type === 0"><OfficeBuilding /></el-icon>
              <el-icon v-else-if="data.type === 1"><School /></el-icon>
              <el-icon v-else-if="data.type === 2"><VideoCamera /></el-icon>
              <span class="node-label" :class="{ 'ehv-text': data.type === 'STATION_EHV' }">
                {{ node.label }}
              </span>
            </span>
          </template>
        </el-tree>
      </el-card>
    </div>
    <div class="main-content">
      <div v-if="viewMode === 'list'"  class="box-card">
<!--        NVR查询表单-->
        <el-form
          :inline="true"
          :model="NvrFormData"
          @submit.prevent
          class="QueryForm">
          <el-form-item label="设备名称：">
            <el-input v-model="NvrFormData.name" placeholder="请输入名称" clearable/>
          </el-form-item>
          <el-form-item label="状态" >
            <el-select  v-model="NvrFormData.status" placeholder="请选择" style="width: 210px;" clearable>
            <el-option
              v-for="item in optionsStore.getDictOptions('status').map(it=>{
                return {
                  ... it,
                  id: Number(it.id.substring(6))
                }
              })"
              :key="item.id"
              :label="item.codeName"
              :value="Number(item.id)"
            />
            </el-select>
          </el-form-item>
          <el-form-item >
            <el-button  type="primary" class="queryBtn" @click="queryNvr">查询</el-button>
          </el-form-item>
          <el-form-item >
            <el-button  type="primary" :icon="Plus" style="width: 100px;" @click="openAddNvrDialog">新增设备</el-button>
            <el-button  type="danger" :icon="Delete" style="width: 100px;" @click="deleteNvrsBatch">批量删除</el-button>
          </el-form-item>
        </el-form>
<!--        NVR表格-->
        <el-table :data="tableData"
         style="width: 100%;padding: 10px"  
         stripe height="calc(100vh - 200px)"  
         @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55"/>
          <el-table-column prop="id" label="NVR ID" width="120" />
          <el-table-column prop="name" label="设备名称" min-width="180" />
          <el-table-column prop="ip" label="IP地址" width="140"/>
          <el-table-column prop="port" label="端口号" width="140"/>
          <el-table-column prop="account" label="账号" width="140"/>
          <el-table-column prop="password" label="密码" width="140"/>
          <el-table-column prop="driver" label="类型" width="100" align="center">
            <template #default="scope">
              <el-tag v-if="scope.row.driver === 0" type="success" effect="dark">海康</el-tag>
              <el-tag v-if="scope.row.driver === 1" type="success">大华</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100" align="center">
            <template #default="scope">
              <el-tag v-if="scope.row.status === 1" type="success" effect="dark">在线</el-tag>
              <el-tag v-if="scope.row.status === 0" type="danger">离线</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" width="140"/>
          <el-table-column label="操作" width="320" fixed="right" align="center">
            <template #default="scope">
              <el-button size="small" icon="Refresh" type="primary" @click="handleRefresh(scope.row)" >
                同步 </el-button>
<!--              <el-button size="small" icon="Refresh" type="primary" @click="refreshChannel(scope.row)" :loading="scope.row.isLoading">-->
<!--                刷新 </el-button>-->
              <el-button size="small" icon="VideoCamera" type="primary" @click="showChannelList(scope.row)"> 通道 </el-button>
              <el-button size="small" icon="EditPen"  type="primary" @click="openNvrChangeDialog(scope.row)"> 编辑 </el-button>
              <el-button size="small"  type="danger" icon="Delete" @click="deleteByIdNvr(scope.row.id)"> 删除 </el-button>
            </template>
          </el-table-column>
        </el-table>
        <DataSync
                  :percentage="refreshObj.percentage"
                  :is-syncing="refreshObj.isSyncing"
                  :is-success="refreshObj.isSuccess"
                  :status="refreshObj.status"
                  />

<!--    分页组件  -->
        <div class="pagination-container" >
          <el-pagination
            v-model:current-page="PageParams.pageNum"
            v-model:page-size="PageParams.pageSize"
            :page-sizes="[10, 20, 30, 40]"
            :total="PageParams.total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
<!--        NVR新增或者编辑弹框-->
        <el-dialog v-model="deviceDialogObj.deviceVisible"
                   @close="handleCancel"
                   :title="deviceDialogObj.title"
                   draggable
                   :close-on-click-modal="false"
                   width="500">
          <el-form :model="deviceDialogObj.deviceForm"
                   ref="addOrUpdateFormRef"
                   :rules="addOrUpdateRules">
            <el-form-item label="设备名称" prop="name">
              <el-input v-model="deviceDialogObj.deviceForm.name"  clearable />
            </el-form-item>
            <el-form-item label="设备账号" prop="account">
              <el-input v-model="deviceDialogObj.deviceForm.account"  clearable/>
            </el-form-item>
            <el-form-item label="设备密码" prop="password">
              <el-input type="password" show-password  v-model="deviceDialogObj.deviceForm.password"  clearable/>
            </el-form-item>
            <el-form-item label="设备IP" prop="ip">
              <el-input v-model="deviceDialogObj.deviceForm.ip"  clearable/>
            </el-form-item>
            <el-form-item label="设备端口" prop="port">
              <el-input v-model="deviceDialogObj.deviceForm.port"  clearable/>
            </el-form-item>
            <el-form-item label="设备类型" prop="driver">
              <el-select v-model="deviceDialogObj.deviceForm.driver" clearable>
                <el-option v-for="item in optionsStore.getDictOptions('device_category').map(it=>{
                  return {
                    ... it,
                    id: Number(it.id.substring(6))
                  }
                })"
                           :key="item.id"
                           :label="item.codeName"
                           :value="item.id"/>
              </el-select>
            </el-form-item>
            <el-form-item label="设备所在变电站" prop="stationId">
              <el-select  placeholder="请选择变电站" style="width: 240px"
                          v-model="deviceDialogObj.deviceForm.stationId"
                          :options="subStationList"
                          :props="StationProps"
              >
              </el-select>
            </el-form-item>
            <el-form-item>
              <div class="form-actions">
                <el-button @click="handleCancel">取消</el-button>
                <el-button type="primary" @click="handleSave">保存</el-button>
              </div>
            </el-form-item>
          </el-form>
        </el-dialog>
      </div>
      <el-card   v-else-if="viewMode === 'detail'"   class="box-card">
        <template #header>
          <div class="card-header">
            <div style="display: flex; align-items: center">
              <el-button link icon="ArrowLeft" @click="backToList" style="margin-right: 10px; font-size: 16px">
                返回列表
              </el-button>
              <el-divider direction="vertical" />
              <el-tag size="small" style="margin-left: 10px" :type="currentNvrDetail?.status === 1 ? 'success' : 'info'">
                {{ currentNvrDetail?.status=== 1 ? '设备在线' : '设备离线' }}
              </el-tag>
            </div>
          </div>
        </template>
        <div class="detail-container" >
<!--        通道查询表单 -->
          <el-form :model="channelQuery"
                   :inline="true"
                   ref="channelQueryRef"
                   @submit.prevent>
            <el-form-item label="名称" prop="name" placeholder="请选择">
              <el-input v-model="channelQuery.name"   placeholder="请输入名称" clearable />
            </el-form-item>
            <el-form-item label="云台类型" prop="type">
              <el-select  v-model="channelQuery.type" placeholder="请选择" style="width: 210px;" clearable>
                <el-option
                  v-for="item in optionsStore.getDictOptions('camera_type').map(it=>{
                return {
                  ... it,
                  id: Number(it.id.substring(6))
                }
              })"
                  :key="item.id"
                  :label="item.codeName"
                  :value="Number(item.id)"
                />
              </el-select>
            </el-form-item>
            <el-form-item >
              <el-button  type="primary" class="queryBtn" @click="queryCamera">查询</el-button>
              <el-button  type="warning" icon="Refresh" @click="refreshCamera(currentNvrDetail)" plain :loading="refreshLoading">同步通道</el-button>
            </el-form-item>
          </el-form>
<!--         通道列表 -->
          <el-table :data="channelData" 
          height="350" 
          style="width: 100%"
          :row-key="(row: any)=>row.id"
          size="small" >
            <el-table-column prop="name" label="名称" width="280" align="center"/>
            <el-table-column prop="cameraNo" label="摄像机编号" width="100" align="center"/>
            <el-table-column prop="channelId" label="通道号" width="180" align="center" />
            <el-table-column prop="ipAddress" label="IP地址" width="180" align="center" />
            <el-table-column prop="algInfo" label="算法配置" width="180" align="center" >
              <template #default="{ row }">
                <div class="alg-info-container">
                  <div v-if="row.algInfo && row.algInfo.length > 0">
                    <div v-for="(item,index) in row.algInfo" :key="index" class="alg-tag-item">
                      <el-tag>{{ALGORITHM_MAP[item]}}</el-tag>
                    </div>
                  </div>
                  <div v-else class="no-alg-info">
                    <span>无</span>
                  </div>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="enableInspection" label="抓图对比" width="180" align="center" >
              <template #default="{ row }">
                <el-tag type="primary" v-if="row.enableInspection==1">开启</el-tag>
                <el-tag type="danger" v-else-if="row.enableInspection==0">关闭</el-tag>
                <span v-else>其他</span>
              </template>
            </el-table-column>
            <el-table-column prop="installLocation" label="位置信息" width="180" align="center" >
              <template #default="{ row }">
                <span v-if="row.installLocation==''">无</span>
              </template>
            </el-table-column>
            <el-table-column prop="videoType" label="视频类型" width="180" align="center" >
              <template #default="{ row }">
                <span v-if="row.videoType==1">可见光</span>
                <span v-else-if="row.videoType==2">热成像</span>
                <span v-else>其他</span>
              </template>
            </el-table-column>
            <el-table-column prop="type" label="云台类型" width="180" align="center" >
              <template #default="{ row }">
                <span v-if="row.type==0">枪机</span>
                <span v-else-if="row.type==1">球体</span>
                <span v-else-if="row.type==2">云台</span>
                <span v-else>其他</span>
              </template>
            </el-table-column>
            <el-table-column prop="channelDriver" label="通道类型" width="180" align="center" >
              <template #default="{ row }">
                <span v-if="row.channelDriver==0">海康</span>
                <span v-else-if="row.channelDriver==1">大华</span>
                <span v-else>其他</span>
              </template>
            </el-table-column>
            <el-table-column prop="status" label="状态" width="100">
              <template #default="{ row }">
                <el-tag type="success" v-if="row.status==1">在线</el-tag>
                <el-tag type="danger" v-else-if="row.status==0">离线</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" fixed="right" width="250">
              <template #default="{row}">
                <el-button size="small" type="primary" link @click="openPlayDialog(row)" :loading="playLoading">预览</el-button>
                <el-button size="small" type="primary" link @click="openControlDialog(row)">控制</el-button>
                <el-button size="small" v-if="row.boxId" type="primary" link @click="openAlgDialog(row)">配置算法</el-button>
                <el-button size="small" type="primary" link @click="openCameraEditDialog(row)"> 编辑 </el-button>
                <el-button size="small" type="warning" link @click="handleEditDel(row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
<!--          通道编辑弹框-->
          <el-dialog v-model="editCameraDialog.editVisible" title="编辑" :destroy-on-close="true"  draggable>
            <el-form
              ref="ruleFormRef"
              label-width="140px"
              label-suffix=" :"
              :rules="rules"
              :model="editCameraDialog.cameraForm"
              @submit.enter.prevent="handleSubmit"
            >
              <el-form-item label="摄像机名称" prop="name">
                <el-input v-model="editCameraDialog.cameraForm.name" placeholder="请填写名称" clearable />
              </el-form-item>
              <el-form-item label="摄像机编号" prop="cameraNo">
                <el-input v-model="editCameraDialog.cameraForm.cameraNo" placeholder="请填写编号" clearable />
              </el-form-item>
              <el-form-item label="安装位置" prop="installLocation">
                <el-input v-model="editCameraDialog.cameraForm.installLocation" placeholder="请填写安装位置" clearable />
              </el-form-item>
              <el-form-item label="摄像机类型" prop="type">
                <el-select v-model="editCameraDialog.cameraForm.type" clearable placeholder="请选择摄像机区分类型">
                  <el-option v-for="item in cameraType" :key="item.id" :label="item.codeName" :value="item.id" />
                </el-select>
              </el-form-item>
              <el-form-item label="摄像机品牌" prop="channelDriver">
                <el-select v-model="editCameraDialog.cameraForm.channelDriver" clearable placeholder="请选择摄像机品牌">
                  <el-option v-for="item in cameraProduct" :key="item.id" :label="item.codeName" :value="item.id" />
                </el-select>
              </el-form-item>
              <el-form-item label="抓图对比功能" prop="enableInspection">
                <el-select v-model="editCameraDialog.cameraForm.enableInspection" clearable placeholder="请选择">
                  <el-option v-for="item in inspectionType" :key="item.id" :label="item.codeName" :value="item.id" />
                </el-select>
              </el-form-item>
            </el-form>
            <template #footer>
              <el-button @click="handleEditClose"> 取消 </el-button>
              <el-button type="primary" @click="handleSubmit"> 确定 </el-button>
            </template>
          </el-dialog>
<!--         算法编辑的组件-->
          <AlgConfigForm :camera-row="algDialogObj.cameraRow"
                          :title="algDialogObj.title"
                          @handleVisibleUpdate="handleVisibleUpdate"
                          @handleSubmit="handleAlgSubmit"
                          :alg-visible="algDialogObj.algVisible"
                          :alg-form="algDialogObj.algForm"/>
          <!--        分页组件-->
          <div class="pagination-container" style="margin-top: 10px;">
            <el-pagination
              v-model:current-page="channelPage.pageNum"
              v-model:page-size="channelPage.pageSize"
              :page-sizes="[10, 20, 30, 40]"
              :total="channelPage.total"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </div>
        </div>
      </el-card>
    </div>
    <!-- 视频预览的弹框-->
    <el-dialog v-model="playDialogObj.playVisible"
               :title="playDialogObj.title"
               :before-close="handleClosePlay"
               :destroy-on-close="true"
               :close-on-click-modal="false"
    >
      <div
        class="video-wrapper"
      >
        <VideoPlayer :camera-id="playDialogObj.id"
        />
      </div>
    </el-dialog>

    <!--   控制摄像头的弹框 -->
    <el-dialog v-model="controlDialogObj.controlVisible"
               :title="controlDialogObj.title"
               :before-close="handleClose"
               align-center
               :destroy-on-close="true"
               :close-on-click-modal="false"
    >
      <CameraControl
        :camera-id="controlDialogObj.id"
        :curCamera="controlDialogObj.curCamera"
      />
    </el-dialog>
  </div>
</template>

<script setup lang="ts">

import {onBeforeUnmount, onMounted, reactive, ref, watch} from 'vue';
// 引入需要的图标，增加了 ArrowLeft, Refresh, Document
import {Delete, OfficeBuilding, Plus, School, VideoCamera} from '@element-plus/icons-vue';
import {getTreeData} from "@/api/modules/monitor/Tree.js";
import type {TreeNode} from "@/api/types/monitor/Tree";
import {createNvrApi, getNvrListApi, listByNode, removeNvrApi, updateNvrApi} from "@/api/modules/monitor/Nvr";
import type {NvrForm, NvrQuery, NvrRow} from "@/api/types/monitor/nvr";
import {type ElForm, ElMessage, ElMessageBox, type TreeInstance} from "element-plus";
import {getCameraListApi, removeCameraApi, updateCameraApi} from "@/api/modules/monitor/Camera";
import type {CameraForm, CameraQuery, CameraRow} from "@/api/types/monitor/camera";
import {deviceLogin, refresh} from "@/api/modules/monitor/device";
import CameraControl from "@/views/sysmonitortree/sysMonitorTree/components/CameraControl.vue";
import VideoPlayer from "@/views/sysmonitortree/sysMonitorTree/components/VideoPlayer.vue";
import {useDictOptions} from "@/hooks/useDictOptions";
import {deepClone} from "@/utils/clone";
import {useOptionsStore} from "@/stores/modules/options";
import {getAllSubstationVO} from "@/api/modules/monitor/substation";
import AlgConfigForm from "@/views/sysmonitortree/sysMonitorTree/components/AlgConfigForm.vue";
import {handleAlgTask} from "@/api/modules/monitor/channel";
import {getAlgorithmTaskByCameraId} from "@/api/modules/monitor/algorithmTask";
import type {AlgorithmTaskVO, AlgTaskConfigDto} from "@/api/types/edgebox/EdgeBox";
import DataSync from "@/views/sysmonitortree/sysMonitorTree/components/DataSync.vue";
const refreshLoading=ref(false);
const playLoading = ref(false);
const filterText = ref('');
const treeRef = ref<TreeInstance>();
const treeData = ref<TreeNode[]>([]);
const tableData = ref<NvrRow[]>([]);
const currentSelectNode = ref<TreeNode>();
const loading = ref(false);
const channelData=ref<CameraRow[]>([]);
const ruleFormRef=ref();
const optionsStore = useOptionsStore();
const addOrUpdateFormRef=ref();
const editCameraDialog=reactive({
  editVisible: false,
  cameraForm: {} as CameraForm
})
const addOrUpdateRules = reactive({
  name: [
    { required: true, message: '请输入设备名称', trigger: 'blur' },
  ],
  account: [
    { required: true, message: '请输入账号', trigger: 'blur' },
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
  ],
  ip: [
    { required: true, message: '请输入IP地址', trigger: 'blur' },
  ],
  port: [
    { required: true, message: '请输入端口号', trigger: 'blur' },
  ],
  driver: [
    { required: true, message: '请输入NVR的类型', trigger: 'blur' },
  ],
  manufacturer: [
    { required: true, message: '请输入设备厂商', trigger: 'blur' },
  ],
  stationId: [
    { required: true, message: '请输入区域', trigger: 'blur' },
  ],
});
const NvrFormData=reactive<NvrQuery>({});
const channelQuery=reactive<CameraQuery>({});
const rules = reactive({
  name: [{ required: true, message: '请填写名称' }],
  cameraNo: [{ required: true, message: '请填写摄像头编号' }],
  type: [{ required: true, message: '请填写类型' }],
  channelDriver: [{ required: true, message: '请填写品牌' }],
});
// 算法的映射
const ALGORITHM_MAP: Record<number, string> = {
  8: "明烟明火检测",
  52: "人脸识别",
  58: "脸部抓拍",
  1:"安全帽检测"
};
// 处理算法提交
const handleAlgSubmit=async (algForm:AlgorithmTaskVO)=>{
  try {
    if (algForm.algInfo.length>3) {
      ElMessage.warning("最多只能同时配置三个算法");
      return;
    }
    const res=await handleAlgTask({
      id: algForm.id,
      url: algForm.url,
      AlgInfo: algForm.algInfo,
      TaskDesc: algForm.taskDesc,
      UserData: algForm.userData,
      cameraId: algDialogObj.cameraRow.id,
    });
    if(res.code==="0000")
    {
      handleVisibleUpdate();
      await getChannelPage();
      ElMessage.success('配置成功');
    } else {
      ElMessage.error('配置失败: ' + (res.message || '未知错误'));
    }
  } catch (error) {
    console.error('配置算法失败:', error);
    ElMessage.error('配置失败，请重试');
  }
}
// 关闭配置算法的弹框
const handleVisibleUpdate=()=>{
  algDialogObj.algVisible=false;
  algDialogObj.algForm={};
}
// 配置算法的弹框对象
const algDialogObj=reactive({
  algVisible: false,
  title: '配置算法',
  algForm:{} as AlgorithmTaskVO,
  cameraRow:{} as CameraRow,
});
// 打开配置算法的弹框
const openAlgDialog=async (data:any)=>{
  try {
    // 获取当前摄像头配置的算法信息
    const res=await getAlgorithmTaskByCameraId({
      cameraId: data.id
    })
    algDialogObj.algForm=res.data || {};
    algDialogObj.algVisible=true;
    algDialogObj.cameraRow=data;
  } catch (error) {
    console.error('获取算法配置失败:', error);
    ElMessage.error('获取算法配置失败，请重试');
  }
}
// NVR条件查询
const queryNvr=async ()=>{
  const res=await getNvrListApi(NvrFormData);
  tableData.value=res.data.rows;
  PageParams.pageNum=res.data.current;
  PageParams.pageSize=res.data.limit;
  PageParams.total=res.data.total;
}
// 打开新增NVR的弹框
const openAddNvrDialog=()=>{
  deviceDialogObj.deviceVisible=true;
  deviceDialogObj.title='新增设备';
}
// 新增或者修改设备的弹框
const deviceDialogObj = reactive({
  deviceVisible: false,
  title: '',
  deviceForm:{} as NvrForm,
  id: -1
});
interface SubStation {
  id:number;
  name:string
}
// 打开编辑NVR的弹框
const openNvrChangeDialog=(data:NvrRow)=>{
  deviceDialogObj.deviceVisible=true;
  deviceDialogObj.title='修改设备';
  deviceDialogObj.deviceForm=deepClone(data);
  console.log('编辑',deviceDialogObj.deviceForm)
  deviceDialogObj.id=data.id;
}
// 保存NVR
const handleSave=async ()=>{
  try {
    // 表单验证
    await addOrUpdateFormRef.value.validate();
    if(deviceDialogObj.title=='新增设备')
    {
      // 执行上传并等待结果
      const res=await createNvrApi(deviceDialogObj.deviceForm);
      if(res.code=="0000")
      {
        // 重置表单数据，关闭弹窗
        handleCancel();
        //调用后端，进行一个设备的登录
        const result=await deviceLogin({
          id:res.data
        })
        console.log('登录信息',result);
        // 刷新数据
        await fetchTableData({});
        ElMessage.success('新增成功');
      }else {
        ElMessage.warning("新增失败");
      }
    }else {
      const res=await updateNvrApi(deviceDialogObj.deviceForm);
      if(res.code=="0000")
      {
        // 重置表单数据，关闭弹窗
        handleCancel();
        // 刷新数据
        await fetchTableData({});
        ElMessage.success('修改成功');
      }else {
        ElMessage.warning("修改失败");
      }
    }
  } catch (error) {
    console.log('表单验证失败:', error);
  }
}
// 记录NVR的Id集合
const ids=[] as number[];
// 表格多选点击事件
const handleSelectionChange=(data:NvrRow[])=>{
  ids.length=0;
  for(let i=0;i<data.length;i++)
  {
    ids.push(data[i].id || 1);
  }
}
// 批量删除NVR
const deleteNvrsBatch=async ()=>{
  try {
    if(ids.length === 0) {
      ElMessage.warning('请选择要删除的设备');
      return;
    }
    const res=await removeNvrApi({
      ids
    });
    if(res.code==="0000")
    {
      if(tableData.value.length==1 &&  PageParams.pageNum > 1)
      {
        PageParams.pageNum-=1;
      }
      await fetchTableData({});
      ElMessage.success('批量删除成功');
    }else {
      ElMessage.error('批量删除失败: ' + (res.message || '未知错误'));
    }
  } catch (error) {
    console.error('批量删除NVR失败:', error);
    ElMessage.error('批量删除失败，请重试');
  }
}
// 根据id删除NVR
const deleteByIdNvr=async (id: number)=>{
  try {
    await ElMessageBox.confirm(
      '确定要删除该 NVR 设备吗？',
      '删除确认',
      {
        confirmButtonText: '确定删除',
        cancelButtonText: '取消',
        type: 'warning',
      }
    );
    const res=await removeNvrApi({
      ids: [id]
    });
    if(res.code==="0000")
    {
      if(tableData.value.length==1 &&  PageParams.pageNum > 1)
      {
        PageParams.pageNum-=1;
      }
      // 刷新数据
      await fetchTableData({});
      ElMessage.success('删除成功');
    }
  } catch (error) {
    if (error === 'cancel') {
      ElMessage.info('已取消删除');
    } else {
      console.error('删除NVR失败:', error);
    }
  }
}
const subStationList=ref<SubStation[]>([]);
const StationProps={
  label: 'name',
  value: 'id'
}
// 获取所有的区域
const getAllSubstationVOs= async ()=>{
  try {
    const res=await getAllSubstationVO();
    if(res.code=='0000')
    {
      subStationList.value=res.data;
    } else {
      console.error('获取区域列表失败:', res.message);
    }
  } catch (error) {
    console.error('获取区域列表失败:', error);
  }
}
const openCameraEditDialog=(row:CameraRow)=>{
  console.log(row);
  editCameraDialog.editVisible=true;
  editCameraDialog.cameraForm=deepClone(row) as CameraForm;
  console.log(editCameraDialog.cameraForm);
}
const inspectionType = useDictOptions('inspection_type').value.map(item => {
  return {
    ...item,
    id: Number(item.id.substring(6))
  };
});
const cameraProduct = useDictOptions('camera_driver').value.map(item => {
  return {
    ...item,
    id: Number(item.id.substring(6))
  };
});
const cameraType = useDictOptions('camera_type').value.map(item => {
  return {
    ...item,
    id: Number(item.id.substring(6))
  };
});

const handleSubmit=async ()=>{
  try {
    await ruleFormRef.value.validate();
    const res=await updateCameraApi(editCameraDialog.cameraForm);
    if(res.code==='0000')
    {
      ElMessage.success("修改成功");
      // 刷新数据
      await getChannelPage();
      // 关闭弹框
      editCameraDialog.editVisible=false;
    }else {
      ElMessage.success("修改失败");
      // 重置数据
      editCameraDialog.cameraForm={};
    }
  }catch(error)
  {
    console.log('表单验证失败:', error);
  }

}
// 取消
const handleEditClose=()=>{
  editCameraDialog.editVisible=false;

}


const handleEditDel = async (data: CameraRow) => {
  try {
    await ElMessageBox.confirm('确定要删除该摄像机吗？', '删除确认', {
      confirmButtonText: '确定删除',
      cancelButtonText: '取消',
      type: 'warning',
    });
    await removeCameraApi({ ids: [data.id] });
    ElMessage.success('删除成功');
    await getChannelPage();
  } catch (error) {
    // 5. 捕获取消操作或接口报错
    if (error === 'cancel') {
      // 用户点击了取消按钮
      ElMessage.info('已取消删除');
    } else {
      // 接口层面的报错（如果你的 axios 拦截器没有抛出全局提示，可以在这里处理）
      console.error('删除失败:', error);
    }
  }
};
// 查询摄像机
const queryCamera= async()=>{
  const res=await getCameraListApi({
    ...channelQuery,
    nvrId:NvrId.value,
    limit: channelPage.pageSize,
    page: channelPage.pageNum
  });
  channelData.value=res.data.rows;
  channelPage.pageNum=res.data.current;
  channelPage.pageSize=res.data.limit;
  channelPage.total=res.data.total;
}
const handleCancel=()=>{
  deviceDialogObj.deviceVisible=false;
  deviceDialogObj.deviceForm={};
}
// 新增：视图模式控制
const viewMode = ref('list');
const currentNvrDetail = ref<NvrRow>();
const defaultProps = {
  children: 'children',
  label: 'name'
};
// 分页查询参数
const PageParams = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0
});
// 通道分页参数
const channelPage=reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0
})
// 视频控制对象
const controlDialogObj=reactive({
  controlVisible:false,
  title:'',
  id: -1,
  curCamera:{}
})
// 视频播放对象
const playDialogObj=reactive({
  playVisible: false,
  title:'',
  id: -1
})

// 视频播放
const openPlayDialog=(data:CameraRow) =>{
  if(data.status==0)
  {
    ElMessage.warning('摄像头不在线');
    return;
  }
  playDialogObj.playVisible=true;
  playDialogObj.title= '视频预览';
  if (data.channelId !== undefined) {
    playDialogObj.id = data.id;
  } else {
    console.warn('channelId 不存在于当前数据中');
  }
}
// 视频控制
const openControlDialog=(data:CameraRow)=>{
  if(data.status==0)
  {
    ElMessage.warning('摄像头不在线');
    return;
  }
  controlDialogObj.controlVisible=true;
  controlDialogObj.title="摄像头控制"
  if (data.id !== undefined) {
    controlDialogObj.id = data.id;
    controlDialogObj.curCamera=data;
  } else {
    console.warn('channelId 不存在于当前数据中');
  }
}
const handleClosePlay= async ()=>{
  playDialogObj.playVisible=false
}
const handleClose=async ()=>{
  controlDialogObj.controlVisible=false
}
// 记录NVR的id
const NvrId=ref();

// 获取通道列表
const showChannelList= async (data:NvrRow)=>{
  viewMode.value='detail';
  currentNvrDetail.value=data;
  console.log(currentNvrDetail.value)
  // 根据NVRid获取通道列表
  const res=await getCameraListApi({
    nvrId:data.id,
    limit: channelPage.pageSize,
    page: channelPage.pageNum
  })
  NvrId.value=data.id;
  channelData.value=res.data.rows;
  channelPage.pageNum=res.data.current;
  channelPage.pageSize=res.data.limit;
  channelPage.total=res.data.total;
}
// 分页获取通道列表
const getChannelPage=async () =>{
  const res=await getCameraListApi({
    nvrId:NvrId.value,
    limit: channelPage.pageSize,
    page: channelPage.pageNum
  })
  channelData.value=res.data.rows;
  channelPage.pageNum=res.data.current;
  channelPage.pageSize=res.data.limit;
  channelPage.total=res.data.total;
}
// 点击节点
const handleNodeClick =async (data:TreeNode) => {
  currentSelectNode.value = data;
  if(data.type===3) return;
  // 获取该节点下的所有NVR列表
  viewMode.value = 'list';
  PageParams.pageNum = 1;
  if (data.type === 2) {
    // 如果点击的是Nvr节点，直接展示这个NVR的列表
    const res=await getNvrListApi({
      id: data.id
    });
    tableData.value = res.data.rows;
    PageParams.pageNum=res.data.current;
    PageParams.pageSize=res.data.limit;
    PageParams.total=res.data.total;
  } else {
    // 获取该节点下的所有NVR列表
    viewMode.value = 'list';
    const res=await listByNode({
      nodeId: data.id,
      type: data.type,
      ...PageParams
    })
    tableData.value = res.data.rows;
    PageParams.pageNum=res.data.current;
    PageParams.pageSize=res.data.limit;
    PageParams.total=res.data.total;
  }
};
// 2. 请求后端分页接口
const fetchTableData = async (params:NvrQuery) => {
  loading.value = true;
  try {
    // 调用后端
    const res = await getNvrListApi({
      ...params,
      page:PageParams.pageNum,
      limit:PageParams.pageSize
    });
    tableData.value=res.data.rows;
    PageParams.pageNum=res.data.current;
    PageParams.pageSize=res.data.limit;
    PageParams.total=res.data.total;
  } catch (err) {
    console.error('加载NVR列表失败', err);
  } finally {
    loading.value = false;
  }
};
// 3. 分页事件处理
const handleSizeChange = (val:number) => {
  PageParams.pageSize = val;
  channelPage.pageSize=val;
  if(viewMode.value=='list')
  {
    fetchTableData({});
  }else if(viewMode.value=='detail') {
    getChannelPage();
  }

};

const handleCurrentChange = (val:number) => {
  PageParams.pageNum = val;
  channelPage.pageNum=val;
  if(viewMode.value=='list')
  {
    fetchTableData({});
  }else if(viewMode.value=='detail') {
    getChannelPage();
  }
};

// 摄像头通道刷新
const refreshCamera= async (data:NvrRow)=>{
  try {
    refreshLoading.value=true;
    const res=await refresh({
      id:Number(data.id),
      deviceType:data.driver
    });
    if(res.code=="0000")
    {
      // 重新加载通道列表
      await getChannelPage();
      ElMessage.success('刷新成功');
    } else {
      ElMessage.error('刷新失败: ' + (res.message || '未知错误'));
    }
  } catch (error)
  {
    console.error('刷新通道失败:', error);
    ElMessage.error('刷新失败，请重试');
  } finally {
    refreshLoading.value=false;
  }
}
// 刷新通道对象
const refreshObj=reactive({
  isSyncing:false,
  isSuccess:false,
  percentage:0,
  status:'',
  timer:null
})
let timer: ReturnType<typeof setInterval> | null = null;
const handleRefresh=(data:NvrRow)=>{
  // // 1. 初始化状态
  refreshObj.percentage= 0;
  refreshObj.isSyncing = true;
  refreshObj.isSuccess = false;
  refreshObj.status = '';
  if(timer) clearInterval(timer);
  // 模拟进度条增长
  timer = setInterval( async () => {
    const step = Math.floor(Math.random() * 10) + 30;
    refreshObj.percentage += step;
    // 卡在 99% 等待后端最终响应
    if (refreshObj.percentage >= 99) {
      refreshObj.percentage = 99;
      clearInterval(timer!);
      // 向后端请求
      await refreshChannel(data);
      refreshObj.percentage = 100;
      refreshObj.status = 'success';
      refreshObj.isSuccess = true;
      // 停留 2 秒让用户看清楚大对号和“同步完成”，然后关闭弹窗
      setTimeout(() => {
        refreshObj.isSyncing = false;
      }, 2000);
    }
  }, 400);
};

// 刷新通道
const refreshChannel= async (data:NvrRow)=>{
  try {
    data.isLoading=true;
    refreshLoading.value=true;
    const res=await refresh({
      id:Number(data.id),
      deviceType:data.driver
    });
    if(res.code=="0000")
    {
      ElMessage.success('刷新成功');
    } else {
      ElMessage.error('刷新失败: ' + (res.message || '未知错误'));
    }
  } catch (error)
  {
    console.error('刷新通道失败:', error);
    ElMessage.error('刷新失败，请重试');
  } finally {
    refreshLoading.value=false;
    data.isLoading=false;
  }
}

// 新增：返回列表页逻辑
const backToList = () => {
  viewMode.value = 'list';
};
// 过滤树节点
watch(filterText, (val) => {
  treeRef.value?.filter(val);
});
const filterNode  = (value:string, data:TreeNode) => {
  if (!value) return true;
  return data.name.includes(value);
};

// 获取树型列表数据
const fetchData = async () => {
  try {
    const res = await getTreeData();
    treeData.value = res.data;
  } catch (error) {
    console.error('获取数据失败', error);
    ElMessage.error('获取资源列表失败，请重试');
  }
};

onMounted(() => {
  fetchData();
  fetchTableData({});
  getAllSubstationVOs();
});
// 组件销毁前清理定时器，防止内存泄漏
onBeforeUnmount(() => {
  if (timer) clearInterval(timer);
});
</script>

<style scoped>
/* 保持原有布局 */
.div-container {
  display: flex;
  height: 100%;
}

.sidebar {
  width: 320px;
  padding: 10px;
  display: flex;
  flex-direction: column;
}

.main-content {
  flex: 1;
  padding: 10px;
  overflow: hidden;
}

.box-card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

:deep(.el-card__body) {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  font-size: 14px;
}

.node-label {
  margin-left: 6px;
}

.ehv-text {
  color: #d32f2f;
  font-weight: bold;
}

/* 详情页特有样式 */
.detail-container {
  padding: 10px;
}
.detail-tabs {
  margin-top: 20px;
  height: 100%;
}

.video-wrapper {
  width: 100%; /* 宽度跟随 Dialog */

  /* 核心代码：强制保持 16:9 比例 */
  aspect-ratio: 16 / 9;

  background-color: #000; /* 视频未加载时显示黑色背景，像专业监控屏 */
  position: relative; /* 为内部绝对定位做准备（如果需要） */
  overflow: hidden;
  border-radius: 4px; /* 稍微搞点圆角，好看 */

  /* 如果你的播放器组件是基于 canvas 或 absolute 定位的，
     可能需要给内部元素加上这个 */
  :deep(video), :deep(canvas) {
    width: 100%;
    height: 100%;
    display: block;
  }
}

/* 算法配置列样式 */
.alg-info-container {
  min-height: 60px; /* 设置最小高度，确保行高一致 */
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 8px 0;
}

.alg-tag-item {
  margin-bottom: 4px;
}

.alg-tag-item:last-child {
  margin-bottom: 0;
}

.no-alg-info {
  color: #909399;
  font-size: 14px;
}
</style>
