<template>
  <div class="alert-container">
    <!-- <el-row class="top-pan">
      <el-col :sm="24" :md="12" class="panel-section">
        <statistics />
      </el-col>
      <el-col :sm="24" :md="12" class="panel-section">
        <alertChart />
      </el-col>
    </el-row> -->
    <!-- <el-row class="middle-row">
      <span>
        告警总数:{{ displayTotalItems }}
      </span>
    </el-row> -->
    <el-row class="filter-row">
      <el-col :span="4">
        <el-form-item label="摄像头名称">
          <el-select v-model="filterParams.cameraId" placeholder="请选择摄像头" filterable clearable>
            <el-option v-for="camera in cameras" :key="camera.id" :label="camera.name" :value="camera.id">
            </el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="3">
        <el-form-item label="告警类型">
          <el-select v-model="filterParams.types" placeholder="请选择类型" clearable>
            <el-option v-for="(label, key) in typeMapping" :key="key" :label="label" :value="key"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="3">
        <el-form-item label="处理情况">
          <el-select v-model="filterParams.status" placeholder="全部" clearable>
            <el-option label="全部" value=""></el-option>
            <el-option label="待处理" value="pending"></el-option>
            <el-option label="已处理" value="closed"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="4">
        <el-form-item label="开始时间">
          <el-date-picker v-model="filterParams.timeAfter" type="datetime" placeholder="请选择开始时间"></el-date-picker>
        </el-form-item>
      </el-col>
      <el-col :span="4">
        <el-form-item label="结束时间">
          <el-date-picker v-model="filterParams.timeBefore" type="datetime" placeholder="请选择结束时间"></el-date-picker>
        </el-form-item>
      </el-col>
      <el-col :span="4" class="filter-buttons">
        <el-button type="primary" @click="handleFilter">查询</el-button>
        <el-button @click="handleReset">重置</el-button>
        <el-button :disabled="isExporting" @click="exportData">
          {{ isExporting ? '正在导出，请勿重复点击' : '导出' }}
        </el-button>
      </el-col>
    </el-row>

    <el-row class="table-row">
      <el-col :span="24" class="table-col">
        <div class="table-container">
          <el-table :data="tableData" header-row-class-name="table-header" :fit="true" height="580">
            <el-table-column prop="id" label="告警编号" min-width="100"></el-table-column>
            <el-table-column label="告警类型" min-width="150">
              <template v-slot="scope">
                {{ typeMapping[scope.row.types] }}
              </template>
            </el-table-column>
            <el-table-column prop="camera.name" label="告警位置" min-width="150"></el-table-column>
            <el-table-column label="告警时间" min-width="200">
              <template v-slot="scope">
                {{ formatDateTime(scope.row.ended_at) }}
              </template>
            </el-table-column>
            <el-table-column prop="status" label="告警状态" min-width="100">
              <template v-slot="scope">
                <el-tag :type="scope.row.status === 'pending' ? 'warning' : 'success'">{{ statusMapping[scope.row.status]
                }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" min-width="150">
              <template v-slot="scope">
                <el-button type="text" @click="handleView(scope.row)">查看</el-button>
                <el-button type="text" v-if="scope.row.status === 'pending'"
                  @click="submitStatusUpdate('closed', scope.row)">
                  标记为已处理
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="pagination-container">
          <el-pagination @size-change="handleSizeChange" @current-change="handlePageChange" :current-page="currentPage"
            :page-size="pageSize" :total="totalItems" layout="total, sizes, prev, pager, next, jumper">
          </el-pagination>
        </div>
      </el-col>
    </el-row>
    <el-dialog v-model="dialogVisible" title="告警详情" width="80%">
      <div>
        <el-row>
          <el-col :span="6">
            <p>告警编号: {{ selectedRow.id }}</p>
          </el-col>
          <el-col :span="6">
            <p>告警类型: {{ typeMapping[selectedRow.types] }}</p>
          </el-col>
          <el-col :span="6">
            <p>告警位置: {{ selectedRow.camera.name }}</p>
          </el-col>
          <el-col :span="6">
            <p>告警时间: {{ selectedRow.formatted_started_at }}</p>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="6">
            <p>告警状态: <el-tag :type="selectedRow.status === 'pending' ? 'warning' : 'success'">{{
              statusMapping[selectedRow.status]
            }}</el-tag></p>
          </el-col>
          <el-col :span="6">
            <p>摄像头编号: {{ selectedRow.camera_id }}</p>
          </el-col>
          <el-col :span="6">
            <p>持续时间: {{ duration }}</p>
          </el-col>
          <el-col :span="6">
            <p>备注: {{ selectedRow.remark }}</p>
          </el-col>
        </el-row>
        <!-- <div class="event-media">
          <div v-for="medium in selectedRow.mediums" :key="medium.id" class="media-container">
            <div v-if="medium.name === 'video'" class="media-item video-item">
              <p>告警关联视频</p>
              <video :src="medium.file" controls></video>
            </div>
            <div v-if="medium.name === 'snapshot'" class="media-item image-item">
              <p>告警关联图片</p>
              <el-image :src="medium.file" fit="contain"></el-image>
            </div>
          </div>
        </div> -->
        <div class="event-media" :class="{ 'center-media': mediums.length === 1 }">
          <!-- 告警关联视频 -->
          <div v-if="hasVideo" class="media-container video-item">
            <p>告警关联视频</p>
            <video :src="videoFile" controls @click="openMediaDialog('video', videoFile)"></video>
          </div>

          <!-- 告警关联图片 -->
          <div v-if="hasSnapshot" class="media-container image-item">
            <p>告警关联图片</p>
            <el-image :src="snapshotFile" fit="contain" @click="openMediaDialog('image', snapshotFile)"></el-image>
          </div>
        </div>
        <!-- 备注输入框 -->
        <el-row>
          <el-col :span="24">
            <el-form-item>
              <el-input v-model="remark" placeholder="请描述事件原因，处理过程方法，以及处理结果" type="textarea" rows="5"></el-input>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 条件显示按钮 -->
        <el-row class="dialog-button">
          <el-col :span="24" style="text-align: center;">
            <el-button v-if="selectedRow.status === 'pending'" type="primary" @click="submitStatusUpdate('closed')">
              标记为已处理
            </el-button>
            <el-button v-else type="primary" @click="submitStatusUpdate(selectedRow.status)">
              提交
            </el-button>
          </el-col>
        </el-row>
      </div>
    </el-dialog>
    <el-dialog v-model="mediaDialogVisible" width="70%">
      <div v-if="mediaType === 'image'">
        <el-image :src="mediaSrc" fit="contain" style="width: 100%;"></el-image>
      </div>
      <div v-if="mediaType === 'video'">
        <video :src="mediaSrc" controls style="width: 100%;"></video>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
// import Statistics from '@/components/Statistics.vue';
// import AlertChart from '@/components/AlertChart.vue';
import { BoxApi } from '@/utils/boxApi.ts';  // 导入 BoxApi

import { saveAs } from 'file-saver';
import Papa from 'papaparse';

// 创建 BoxApi 实例
const boxApi = new BoxApi();

// 响应式数据
const tableData = ref([]);
const dialogVisible = ref(false);
const remark = ref("");
const mediaDialogVisible = ref(false);
const mediaType = ref('');
const mediaSrc = ref('');

const selectedRow = ref({});
const mediums = ref([]);
const duration = ref('');
const typeMapping = reactive({});
const statusMapping = {
  'pending': '待处理',
  'assigned': '处理中',
  'closed': '已处理'
};
const currentPage = ref(1);
const pageSize = ref(20);
const token = ref(null);
const totalItems = ref(0);
const displayTotalItems = ref(0); // 用于展示的数字
const cameras = ref([]);

const formatDateTimeToISO = (datetime) => {
  return new Date(datetime).toISOString().replace('.000', '');
};


const isExporting = ref(false);
// 导出数据方法
const exportData = async () => {
  if (isExporting.value) return; // 如果已经在导出，直接返回，避免重复点击

  isExporting.value = true; // 设置为正在导出状态
  try {
    const allData = [];
    let page = 1;
    let totalPages = 1;
    const limit = 500;

    // 循环分页请求所有数据
    do {
      const { results, count } = await boxApi.getEventsByParams(
        token.value,
        limit,
        page,
        filterParams.timeBefore ? formatDateTimeToISO(filterParams.timeBefore) : null,
        filterParams.timeAfter ? formatDateTimeToISO(filterParams.timeAfter) : null,
        filterParams.types,
        filterParams.cameraId,
        filterParams.status
      );

      // 格式化数据
      const formattedData = results.map(item => ({
        '告警编号': item.id,
        '告警类型': typeMapping[item.types] || item.types,
        '告警位置': item.camera ? item.camera.name : '',
        '告警时间': formatDateTime(item.ended_at),
        '告警状态': statusMapping[item.status] || item.status
      }));

      allData.push(...formattedData);
      totalPages = Math.ceil(count / limit);
      page += 1;
    } while (page <= totalPages);

    // 使用 PapaParse 将 JSON 转换为 CSV，指定列标题
    const csv = Papa.unparse(allData, {
      columns: ['告警编号', '告警类型', '告警位置', '告警时间', '告警状态']
    });

    // 添加 BOM，确保中文编码正确
    const blob = new Blob(["\uFEFF" + csv], { type: 'text/csv;charset=utf-8;' });
    saveAs(blob, 'Alert_data.csv');
  } catch (error) {
    console.error("导出数据错误:", error);
  }finally {
    isExporting.value = false; 
  }
};


const fetchCameras = async () => {
  try {
    const token = localStorage.getItem('alertToken');
    const limit = 20; // 每次请求 20 条数据
    let offset = 0; // 从 0 开始
    let allCameras = [];

    // 第一次请求，用于获取总数
    const firstResponse = await boxApi.getCameras(limit, offset, token);
    const cameraCount = firstResponse.count;
    allCameras = firstResponse.results;

    // 根据总数继续请求剩余的数据
    while (offset + limit < cameraCount) {
      offset += limit;
      const response = await boxApi.getCameras(limit, offset, token);
      allCameras = allCameras.concat(response.results);
    }

    cameras.value = allCameras; // 存储所有摄像头信息
  } catch (error) {
    console.error("Error fetching cameras:", error);
  }
};




const filterParams = reactive({
  types: null,
  timeAfter: null,
  timeBefore: null,
  cameraId: null,
  status: null,
});


// 更新状态和备注的方法
const submitStatusUpdate = async (newStatus, row = null) => {
  try {
    // console.console.log(row,row.id);
    const eventId = row ? row.id : selectedRow.value.id;
    const remarkContent = remark.value && remark.value.trim() !== "" ? remark.value : null;

    // 调用 setEventStatus 更新事件状态和备注
    await boxApi.setEventStatus(eventId, newStatus, remarkContent);


    if (row) {
      row.status = newStatus;
      row.remark = remarkContent; // 更新该行的备注
    } else {
      selectedRow.value.status = newStatus;
      selectedRow.value.remark = remarkContent;
      dialogVisible.value = false; // 关闭弹窗
      remark.value = ""; // 清空备注
    }
  } catch (error) {
    console.error("Error updating event status:", error);
  }
};

const handleFilter = async () => {
  try {
    const types = filterParams.types || null;
    // const timeAfter = filterParams.timeAfter ? new Date(filterParams.timeAfter).toISOString() : null;
    // const timeBefore = filterParams.timeBefore ? new Date(filterParams.timeBefore).toISOString() : null;
    const timeAfter = filterParams.timeAfter ? formatDateTimeToISO(new Date(filterParams.timeAfter)) : null;
    const timeBefore = filterParams.timeBefore ? formatDateTimeToISO(new Date(filterParams.timeBefore)) : null;
    const cameraId = filterParams.cameraId || null;
    const status = filterParams.status || null;

    const { results, count } = await boxApi.getEventsByParams(
      token.value,
      pageSize.value,
      currentPage.value,
      timeBefore,
      timeAfter,
      types,
      cameraId,
      status
    );
    tableData.value = results;
    totalItems.value = count;
  } catch (error) {
    console.error("Error fetching filtered events:", error);
  }
};

const handleReset = () => {
  filterParams.types = null;
  filterParams.timeAfter = null;
  filterParams.timeBefore = null;
  filterParams.cameraId = null;
  filterParams.status = null;
  fetchEvents(); // 重置筛选条件后，重新获取所有告警数据
};



const openMediaDialog = (type, src) => {
  mediaType.value = type;  // 设置媒体类型
  mediaSrc.value = src;  // 设置媒体源文件
  mediaDialogVisible.value = true;  // 打开弹窗
};

// 计算属性：根据 mediums 动态判断是否存在视频和图片
const hasVideo = computed(() => mediums.value.some(medium => medium.name === 'video'));
const hasSnapshot = computed(() => mediums.value.some(medium => medium.name === 'snapshot'));

// 获取视频和图片的文件
const videoFile = computed(() => {
  const video = mediums.value.find(medium => medium.name === 'video');
  return video ? video.file : '';
});

const snapshotFile = computed(() => {
  const snapshot = mediums.value.find(medium => medium.name === 'snapshot');
  return snapshot ? snapshot.file : '';
});

// 获取类型映射
const fetchTypeMapping = async (token) => {
  try {
    const algorithms = await boxApi.getAlgorithms(token);  // 使用 BoxApi 的 getAlgorithms 方法
    const additionalMappings = [{ code_name: 'minizawu:532', name: '杂物堆积' }];
    algorithms.forEach((algorithm) => {
      typeMapping[algorithm.code_name] = algorithm.name;
    });
  } catch (error) {
    console.error("Error fetching algorithms:", error);
  }
};

// 获取告警数据
const fetchEvents = async () => {
  try {
    const { tableData: data, totalItems: total } = await boxApi.getEvents(token.value, pageSize.value, currentPage.value);  // 使用 BoxApi 的 getEvents 方法
    tableData.value = data;
    totalItems.value = total;
    animateNumberChange(total);
  } catch (error) {
    console.error("Error fetching events data:", error);
  }
};

const animateNumberChange = (newTotal) => {
  const stepTime = 50; // 每次递增的时间间隔
  // const stepCount = Math.abs(newTotal - displayTotalItems.value);
  const stepCount = Math.abs(newTotal - displayTotalItems.value) / 20;

  const incrementStep = Math.ceil((newTotal - displayTotalItems.value) / stepCount); // 每次递增的值

  const step = () => {
    if (displayTotalItems.value < newTotal) {
      displayTotalItems.value = Math.min(displayTotalItems.value + incrementStep, newTotal);
      requestAnimationFrame(step);
    } else if (displayTotalItems.value > newTotal) {
      displayTotalItems.value = Math.max(displayTotalItems.value - incrementStep, newTotal);
      requestAnimationFrame(step);
    }
  };

  step();
};

// 查看告警详情
const handleView = (row) => {
  selectedRow.value = row;
  duration.value = calculateDuration(row.started_at, row.ended_at);
  row.formatted_started_at = formatDateTime(row.started_at);
  dialogVisible.value = true;
  mediums.value = row.mediums || [];
  remark.value = row.remark || "";
};

const closeDialog = () => {
  remark.value = "";
};

// 分页处理
const handlePageChange = (page) => {
  currentPage.value = page;
  if (filterParams.types || filterParams.timeAfter || filterParams.timeBefore || filterParams.cameraId || filterParams.status) {
    handleFilter();
  } else {
    fetchEvents();
  }
};

// 页大小处理
const handleSizeChange = (size) => {
  pageSize.value = size;
  fetchEvents();
};

// 计算持续时间
const calculateDuration = (started_at, ended_at) => {
  const start = new Date(started_at);
  const end = new Date(ended_at);
  const durationMs = end - start;
  const minutes = Math.floor(durationMs / 60000);
  const seconds = ((durationMs % 60000) / 1000).toFixed(0);
  return `${minutes}分${seconds < 10 ? '0' : ''}${seconds}秒`;
};

// 格式化日期时间
const formatDateTime = (datetime) => {
  const date = new Date(datetime);
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  const hours = date.getHours().toString().padStart(2, '0');
  const minutes = date.getMinutes().toString().padStart(2, '0');
  const seconds = date.getSeconds().toString().padStart(2, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};

// 页面加载后执行
onMounted(async () => {
  token.value = localStorage.getItem('alertToken');
  await fetchTypeMapping(token.value);
  await fetchEvents();
  await fetchCameras();
});
</script>

<style scoped>
.alert-container {
  padding: 0;
  margin: 0;
  background-color: #001529;
  overflow-y: auto;
  height: 100%;
}

/* .top-pan {
  padding: 0px;
  margin: 0px;
  display: flex;
  gap: 10px;
  background-color: #fff;
  overflow: auto;
}

.panel-section {
  flex: 1;
  background-color: #fff;
  box-shadow: 0 20px 8px rgba(0, 0, 0, 0.1);
  border-radius: 15px;
} */

/* .middle-row {
  min-height: 5vw;
  display: flex;
  justify-content: center;
  align-content: center;
  font-size: 30px;
  font-weight: bold;
  background: linear-gradient(to bottom left, rgb(150, 151, 243), rgb(215, 214, 250));
  border-radius: 8px;
} */

.filter-row {
  display: flex;
  justify-content: center;
  align-content: center;
  height: 15vh;
  padding: 0px 0;
  margin: 5vh 6vw 5vh 1vw;
  gap: 8px;
  /* font-weight: bold; */
  font-size: 15px;
  background-color: rgb(251, 254, 255);
  border-radius: 8px;
}

.table-container {
  max-width: 100%;
  height: 80%;
  /* min-height: 50vh; */
  /* max-height: 70vh; */
  overflow-x: auto;
  margin: 0vh 6vw 0vh 1vw;
  padding: 0;
  overflow-y: hidden;
  border-radius: 8px 8px 0 0;
  background-color: white;

}

.pagination-container {
  display: flex;
  justify-content: flex-start;
  background-color: #e9eefc;
  padding-left: 20px;
  margin: 0vh 6vw 5vh 1vw;
}

.table-header {
  background-color: #f7f8fa;
  font-weight: bold;
}

::v-deep .el-table th.el-table__cell {
  background-color: #e9eefca4;
  color: #000;
}

.event-media {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  width: 100%;
}

.center-media {
  justify-content: center;
}

.media-container {
  flex: 0 0 48%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
  box-sizing: border-box;
  padding: 10px;
}

.table-col {
  max-height: 100%;
}

.video-item video,
.image-item img {
  width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.video-item p,
.image-item p {
  margin-bottom: 8px;
  text-align: center;
  font-weight: bold;
}



::v-deep .pagination-container .el-pagination__total,
::v-deep .pagination-container .el-pagination__goto,
::v-deep .pagination-container .el-pagination__classifier {
  color: #000;
}

.dialog-button {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 20px;
}
</style>
