<template>
  <div class="home">
    <div class="map" id="map"></div>
    <div class="left-part">
      <el-card>
        <template #header>
          <div class="custom-title">
            <img src="@/assets/images/title.svg" />
            <span>本月</span>
          </div>
        </template>
        <div class="custom-card">
          <div class="card-item">
            <span>{{ statData.monthCount }}</span>
            <span>所有数量</span>
          </div>
          <div class="card-item">
            <span>{{ statData.monthAlready }}</span>
            <span>已解决</span>
          </div>
          <div class="card-item">
            <span>{{ statData.monthNot }}</span>
            <span>未解决</span>
          </div>
          <div class="card-item">
            <span>{{ statData.monthReport }}</span>
            <span>已上报</span>
          </div>
        </div>
      </el-card>
      <el-card style="margin-top: 10px">
        <template #header>
          <div class="custom-title">
            <img src="@/assets/images/title.svg" />
            <span>本周</span>
          </div>
        </template>
        <div class="custom-card week-card">
          <div class="card-item">
            <span>{{ statData.weekCount }}</span>
            <span>所有数量</span>
          </div>
          <div class="card-item">
            <span>{{ statData.weekAlready }}</span>
            <span>已解决</span>
          </div>
          <div class="card-item">
            <span>{{ statData.weekNot }}</span>
            <span>未解决</span>
          </div>
          <div class="card-item">
            <span>{{ statData.weekReport }}</span>
            <span>已上报</span>
          </div>
        </div>
      </el-card>
      <el-card style="margin-top: 10px">
        <template #header>
          <div class="custom-title">
            <img src="@/assets/images/title.svg" />
            <span>当天</span>
          </div>
        </template>
        <div class="custom-card day-card">
          <div class="card-item">
            <span>{{ statData.dayCount }}</span>
            <span>所有数量</span>
          </div>
          <div class="card-item">
            <span>{{ statData.dayAlready }}</span>
            <span>已解决</span>
          </div>
          <div class="card-item">
            <span>{{ statData.dayNot }}</span>
            <span>未解决</span>
          </div>
          <div class="card-item">
            <span>{{ statData.dayReport }}</span>
            <span>已上报</span>
          </div>
        </div>
      </el-card>
      <el-card style="margin-top: 10px">
        <template #header>
          <div class="custom-title">
            <img src="@/assets/images/title.svg" />
            <span>统计分析</span>
          </div>
        </template>
        <BaseChart width="100%" height="100%" :option="pieOptions" />
      </el-card>
    </div>
    <div class="expandOrFold" :style="{ 'right': showList ? '550px' : '0' }" @click="showList = !showList">
      <img v-if="showList" src="@/assets/images/fold.svg" alt="" />
      <img v-else src="@/assets/images/expand.svg" alt="" />
    </div>
    <div class="right-part" v-show="showList">
      <div class="event-title">
        <div>
          <el-select style="width: 100px" v-model="queryParams.level" clearable placeholder="事件等级">
            <el-option v-for="dict in event_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
          </el-select>
          <el-select style="width: 100px; margin-left: 10px" v-model="queryParams.params.lx" filterable clearable placeholder="事件类型">
            <el-option v-for="dict in eventTypeOptions" :key="dict" :label="dict" :value="dict"></el-option>
          </el-select>
          <el-date-picker
            v-model="queryParams.dateRange"
            style="margin-left: 10px"
            type="daterange"
            unlink-panels
            range-separator="～"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :shortcuts="shortcuts"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
        </div>
        <div style="margin-top: 10px">
          <el-select style="width: 210px" v-model="queryParams.params.deviceId" clearable placeholder="设备">
            <el-option v-for="dict in deviceList" :key="dict.name" :label="dict.name" :value="dict.id"></el-option>
          </el-select>
          <el-input v-model="queryParams.params.key" style="margin-left: 10px; width: 165px" placeholder="输入地点关键词" :suffix-icon="Search" />
          <div style="margin-left: 10px">
            <el-button color="#1890FF" style="color: #fff" @click="getList">查询</el-button>
            <el-button @click="resetQuery">重置</el-button>
          </div>
        </div>
      </div>
      <div class="event-list">
        <el-table :data="eventList" :show-header="false" :border="false" style="width: 100%; --el-table-border-color: none">
          <el-table-column prop="level" width="80">
            <template #default="{ row }">
              {{ event_level.filter((item) => item.value == row.level)[0]?.label }}
            </template>
          </el-table-column>
          <el-table-column prop="ext2.lx" show-overflow-tooltip width="100" />
          <el-table-column prop="addr" show-overflow-tooltip />
          <el-table-column prop="createTimeFormat" width="100" />
          <el-table-column prop="status" width="70">
            <template #default="{ row }">
              <span v-if="row.status == 3" style="color: #5f86fd">已上报</span>
              <span v-else-if="row.status == 1" style="color: #26c768">已解决</span>
              <span v-else-if="row.status == 2" style="color: #ff6124">未解决</span>
              <span v-else>{{ event_status.filter((item) => item.value == row.status)[0]?.label }}</span>
            </template>
          </el-table-column>
          <el-table-column width="60">
            <template #default="{ row }">
              <el-button link type="primary" @click="showDetails(row)">查看</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="event-footer">
        <pagination
          background
          layout="prev, pager, next"
          v-show="total > 0"
          :total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="getList"
        />
      </div>
    </div>
    <el-dialog v-model="dialog.visible" :title="dialog.title" width="1000px" top="0" append-to-body @close="dialogClose">
      <template #title>
        <div style="display: flex; justify-content: space-between; align-items: center; padding-right: 30px">
          <span>事件详情</span>
          <el-button @click="saveClick">保存</el-button>
        </div>
      </template>
      <div class="dialog-loading-warp">
        <el-form ref="addFormRef" :model="form" label-position="top" label-width="90px" label-suffix=":">
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item label="事件ID" prop="id">
                <el-input v-model="form.id" placeholder="请输入" readonly />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="事件类型" prop="ext2.lx">
                <el-select v-model="form.ext2.lx" clearable filterable allow-create placeholder="请选择" @change="formSubmit('lx', 'ext2')">
                  <el-option v-for="dict in eventTypeOptions" :key="dict" :label="dict" :value="dict"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="发生时间" prop="createTime">
                <el-date-picker
                  style="width: 100%"
                  v-model="form.createTime"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  @change="formSubmit('createTime')"
                  type="date"
                  placeholder="请选择"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="事件等级" prop="level">
                <el-select v-model="form.level" clearable placeholder="请选择" @change="formSubmit('level')">
                  <el-option v-for="dict in event_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="桩号" prop="ext2.zh">
                <el-input v-model="form.ext2.zh" placeholder="请输入" @blur="formSubmit('zh', 'ext2')" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="状态" prop="status">
                <el-select v-model="form.status" clearable placeholder="请选择" @change="formSubmit('status')">
                  <el-option v-for="dict in event_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="地点描述" prop="addr">
                <el-input v-model="form.addr" type="textarea" placeholder="请输入" @blur="formSubmit('addr')" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div class="event-media" v-if="form.imgList && form.imgList.length">
          <div class="event-media-title">现场画面</div>
          <div class="event-media-content">
            <div class="imgs">
              <el-image v-for="item in form.imgList" :key="item" :src="item" show-progress :preview-src-list="form.imgList" fit="cover" />
            </div>
          </div>
        </div>
        <div class="event-media" v-if="form.videoList && form.videoList.length" style="margin-top: 10px">
          <div class="event-media-title">现场视频</div>
          <div class="event-media-content">
            <div class="videos">
              <div v-for="(item, index) in form.videoList" :key="index" :id="`dplayer${index}`"></div>
            </div>
          </div>
        </div>
        <div class="report-btn">
          <img @click="generateClick" src="@/assets/images/report.svg" alt="" />
        </div>
        <template v-if="showReport">
          <div class="report-editor">
            <div class="report-title">报告内容：</div>
            <div style="border: 1px solid #d9d9d9; margin-top: 10px">
              <!-- <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" mode="simple" /> -->
              <Editor style="height: 500px; overflow-y: hidden" v-model="valueHtml" :defaultConfig="editorConfig" @onCreated="handleCreated" />
            </div>
          </div>
          <div style="margin-top: 20px">
            <div class="report-title">格式选择：</div>
            <el-select style="width: 300px; margin-top: 10px" v-model="reportForm.type" clearable placeholder="请选择">
              <el-option label="pdf" value="pdf"></el-option>
              <el-option label="word" value="docx"></el-option>
            </el-select>
          </div>
          <div style="margin-top: 20px">
            <el-button color="#2AB55C" style="color: #fff; margin-bottom: 20px" @click="dialogVisible = true">导出报告</el-button>
          </div>
          <el-dialog v-model="dialogVisible" title="导出信息" width="500">
            <el-form ref="reportFormRef" :model="reportForm" label-width="90px" label-suffix=":">
              <el-row :gutter="20">
                <el-col :span="24">
                  <el-form-item label="期数" prop="seq" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
                    <el-input v-model="reportForm.seq" placeholder="请输入" />
                  </el-form-item>
                </el-col>
                <el-col :span="24">
                  <el-form-item label="发送范围" prop="fw" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
                    <el-input v-model="reportForm.fw" placeholder="请输入" />
                  </el-form-item>
                </el-col>
                <el-col :span="24">
                  <el-form-item label="备案号" prop="ba" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
                    <el-input v-model="reportForm.ba" placeholder="请输入" />
                  </el-form-item>
                </el-col>
                <el-col :span="24">
                  <el-form-item label="值班员" prop="zby" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
                    <el-input v-model="reportForm.zby" placeholder="请输入" />
                  </el-form-item>
                </el-col>
                <el-col :span="24">
                  <el-form-item label="审核" prop="sh" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
                    <el-input v-model="reportForm.sh" placeholder="请输入" />
                  </el-form-item>
                </el-col>
                <el-col :span="24">
                  <el-form-item label="签发" prop="qf" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
                    <el-input v-model="reportForm.qf" placeholder="请输入" />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-form>
            <template #footer>
              <div class="dialog-footer">
                <el-button type="primary" :loading="downLoading" @click="htmlToPdfFn">确 认</el-button>
              </div>
            </template>
          </el-dialog>
        </template>
      </div>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue';
import BaseChart from '@/components/BaseChart/index.vue';
import monitorIcon from '@/assets/images/monitor.svg';
import monitorEventIcon from '@/assets/images/monitor-event.svg';
import DPlayer from 'dplayer';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { downloadFile } from '@/utils/download.js';
import { listEvent, generateReport, updateEvent, getEvent, getEventTypes } from '@/api/system/event';
import { listDevice } from '@/api/system/device';
import { dateFormat } from '@/utils/index';
import { ElLoading } from 'element-plus';
import { base64Encoded, base64Decoded } from '@/utils/crypto';
const { proxy } = getCurrentInstance();
const bdmap = ref(null);
const downLoading = ref(false);
const { event_level } = toRefs(proxy?.useDict('event_level'));
const { event_status } = toRefs(proxy?.useDict('event_status'));
const editorRef = shallowRef();
const editorConfig = { placeholder: '请输入内容...' };
// 内容 HTML
const valueHtml = ref('');
const handleCreated = (editor) => {
  editorRef.value = editor; // 记录 editor 实例，重要！
};
const showReport = ref(false);
const reportFormRef = ref(null);
const reportTime = ref('');
const queryParams = ref({
  pageNum: 1,
  pageSize: 15,
  level: undefined,
  dateRange: undefined,
  params: {
    lx: undefined,
    key: undefined,
    deviceId: undefined,
    beginCreateTime: '',
    endCreateTime: ''
  }
});
const dialog = reactive({
  visible: false,
  title: '事件详情',
  loading: null
});
const form = ref<any>({});
const statData = reactive({
  monthCount: undefined,
  monthAlready: undefined,
  monthNot: undefined,
  monthReport: undefined,
  weekCount: undefined,
  weekAlready: undefined,
  weekNot: undefined,
  weekReport: undefined,
  dayCount: undefined,
  dayAlready: undefined,
  dayNot: undefined,
  dayReport: undefined,
  already: undefined,
  not: undefined,
  report: undefined
});
const showList = ref(true);
const shortcuts = [
  {
    text: '最近一周',
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
      return [start, end];
    }
  },
  {
    text: '最近一个月',
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
      return [start, end];
    }
  },
  {
    text: '最近三个月',
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
      return [start, end];
    }
  }
];
const pieOptions = computed(() => {
  const options = {
    tooltip: {
      trigger: 'item'
    },
    legend: {
      orient: 'horizontal',
      left: 'center',
      itemWidth: 15,
      itemHeight: 8,
      itemGap: 10
    },
    series: [
      {
        type: 'pie',
        radius: ['40%', '80%'],
        center: ['50%', '60%'],
        data: [
          {
            value: statData.already,
            name: '已解决',
            itemStyle: {
              color: '#FAC858'
            }
          },
          {
            value: statData.not,
            name: '未解决',
            itemStyle: {
              color: '#93BEFF'
            }
          },
          {
            value: statData.report,
            name: '已上报',
            itemStyle: {
              color: '#507AFC'
            }
          }
        ],
        labelLine: {
          show: false
        },
        label: {
          show: false,
          position: 'center'
        }
      }
    ]
  };
  return options;
});
const eventList = ref([]);
const total = ref(0);
const dialogVisible = ref(false);
const reportForm = reactive({
  'year': null,
  'seq': 1,
  'title': '',
  'month': null,
  'day': null,
  'content': '',
  'fw': '市委、市政府总值班室',
  'qf': '宗仁',
  'sh': '朱劲',
  'ps': '',
  'ba': 'KB608',
  'zby': '83194295',
  'tpl': 'sg.docx',
  'type': 'pdf'
});
const reportSeq = ref(0);
const deviceList = ref([]);
const hasEventDevices = ref([]);
const eventTypeOptions = ref([]);
onMounted(() => {
  try {
    const map = new BMapGL.Map('map'); // 创建地图实例
    const point = new BMapGL.Point(118.879999, 32.016216); // 创建点坐标
    map.centerAndZoom(point, 14);
    map.enableScrollWheelZoom(true);
    bdmap.value = map;
    map.addEventListener('click', function (e) {
      const { lng, lat } = e.latlng;
      console.log(e.latlng);
    });
  } catch (e) {}
  getEventTypeOptions();
  getList();
  getStat();
  getDeviceList();
});
const getEventTypeOptions = () => {
  getEventTypes().then(({ code, data }) => {
    if (code === 200) {
      eventTypeOptions.value = data;
    }
  });
};
const getList = async () => {
  const { dateRange } = queryParams.value;
  if (dateRange && dateRange.length) {
    queryParams.value.params.beginCreateTime = dateRange[0];
    queryParams.value.params.endCreateTime = dateRange[1];
  } else {
    queryParams.value.params.beginCreateTime = undefined;
    queryParams.value.params.endCreateTime = undefined;
  }
  const res = await listEvent(queryParams.value);
  eventList.value = res.rows.map((item) => ({
    ...item,
    status: item.status || '2',
    createTimeFormat: dateFormat(new Date(item.createTime), 'yyyy-MM-dd'),
    ext1: item.ext1 ? JSON.parse(item.ext1) : [],
    ext2: item.ext2 ? JSON.parse(item.ext2) : {}
  }));
  total.value = res.total;
};
const getStat = async () => {
  const monthRange = getTimeRange('month');
  const monthRes = await listEvent({
    params: {
      beginCreateTime: monthRange.start,
      endCreateTime: monthRange.end
    }
  });
  statData.monthCount = monthRes.total;
  statData.monthAlready = monthRes.rows.filter((item) => item.status == '1').length;
  statData.monthNot = monthRes.rows.filter((item) => item.status == '2' || item.status === null).length;
  statData.monthReport = monthRes.rows.filter((item) => item.status == '3').length;
  const weekRange = getTimeRange('week', { firstDayOfWeek: 0 });
  const weekRes = await listEvent({
    params: {
      beginCreateTime: weekRange.start,
      endCreateTime: weekRange.end
    }
  });
  statData.weekCount = weekRes.total;
  statData.weekAlready = weekRes.rows.filter((item) => item.status == '1').length;
  statData.weekNot = weekRes.rows.filter((item) => item.status == '2' || item.status === null).length;
  statData.weekReport = weekRes.rows.filter((item) => item.status == '3').length;
  const todayRange = getTimeRange('day');
  const todayRes = await listEvent({
    params: {
      beginCreateTime: todayRange.start,
      endCreateTime: todayRange.end
    }
  });
  statData.dayCount = todayRes.total;
  statData.dayAlready = todayRes.rows.filter((item) => item.status == '1').length;
  statData.dayNot = todayRes.rows.filter((item) => item.status == '2' || item.status === null).length;
  statData.dayReport = todayRes.rows.filter((item) => item.status == '3').length;
  const res = await listEvent({});
  statData.already = res.rows.filter((item) => item.status == '1').length;
  statData.not = res.rows.filter((item) => item.status == '2' || item.status === null).length;
  statData.report = res.rows.filter((item) => item.status == '3').length;
};
const getTimeRange = (unit = 'day', options: any = {}) => {
  const now = new Date();
  const { firstDayOfWeek = 1 } = options;

  // 定义结果容器
  const result = {
    unit,
    startDate: null,
    endDate: null,
    start: '',
    end: '',
    description: '',
    duration: 0
  };

  // 内部工具函数：格式化日期时间为字符串
  const format = (date) => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  };

  // 处理不同类型的时间范围
  switch (unit.toLowerCase()) {
    case 'day':
      // 当天范围 (00:00:00.000 - 23:59:59.999)
      const dayStart = new Date(now);
      dayStart.setHours(0, 0, 0, 0);

      const dayEnd = new Date(now);
      dayEnd.setHours(23, 59, 59, 999);

      result.startDate = dayStart;
      result.endDate = dayEnd;
      result.start = format(dayStart);
      result.end = format(dayEnd);
      result.description = `当天范围: ${result.start} 至 ${result.end}`;
      result.duration = 1;
      break;

    case 'week':
      // 计算周起始日偏移
      const dayOfWeek = now.getDay();
      const diffToFirstDay = (dayOfWeek < firstDayOfWeek ? 7 : 0) + dayOfWeek - firstDayOfWeek;

      // 本周开始 (周一 00:00:00.000)
      const weekStart = new Date(now);
      weekStart.setDate(now.getDate() - diffToFirstDay);
      weekStart.setHours(0, 0, 0, 0);

      // 本周结束 (周日 23:59:59.999)
      const weekEnd = new Date(weekStart);
      weekEnd.setDate(weekStart.getDate() + 6);
      weekEnd.setHours(23, 59, 59, 999);

      // 设置结果
      result.startDate = weekStart;
      result.endDate = weekEnd;
      result.start = format(weekStart);
      result.end = format(weekEnd);
      result.duration = 7;

      // 生成描述信息
      const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
      const startDayName = weekDays[firstDayOfWeek];
      const endDayName = weekDays[(firstDayOfWeek + 6) % 7];
      result.description = `本周范围 (${startDayName}至${endDayName}): ${result.start} 至 ${result.end}`;
      break;

    case 'month':
      // 本月第一天 (1号 00:00:00.000)
      const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
      monthStart.setHours(0, 0, 0, 0);

      // 本月最后一天 (月末日 23:59:59.999)
      const monthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0);
      monthEnd.setHours(23, 59, 59, 999);

      // 设置结果
      result.startDate = monthStart;
      result.endDate = monthEnd;
      result.start = format(monthStart);
      result.end = format(monthEnd);

      // 计算天数
      const dayDiff = Math.floor((monthEnd - monthStart) / (1000 * 60 * 60 * 24)) + 1;
      result.duration = dayDiff;

      // 获取月份名称
      const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
      result.description = `${monthNames[now.getMonth()]}范围 (共${dayDiff}天): ${result.start} 至 ${result.end}`;
      break;

    default:
      throw new Error(`无效的时间单位: "${unit}". 请使用 'day', 'week' 或 'month'`);
  }

  return result;
};
const resetQuery = () => {
  queryParams.value = {
    pageNum: 1,
    pageSize: 15,
    level: undefined,
    dateRange: undefined,
    params: {
      lx: undefined,
      key: undefined,
      deviceId: undefined,
      beginCreateTime: '',
      endCreateTime: ''
    }
  };
  getList();
};
const getDeviceList = () => {
  listDevice({}).then(async ({ code, rows }) => {
    if (code === 200) {
      await getHasEventDeviceList();
      deviceList.value = rows.map((item) => {
        let hasEvent = 0;
        if (hasEventDevices.value.some((el) => el.id == item.id)) {
          hasEvent = 1;
        }
        return {
          ...item,
          hasEvent
        };
      });
      showMarks();
    }
  });
};
const getHasEventDeviceList = async () => {
  await listDevice({ params: { hasevent: '1' } }).then(({ code, rows }) => {
    if (code === 200) {
      hasEventDevices.value = rows;
    }
  });
};
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});
const showMarks = () => {
  bdmap.value.clearOverlays();
  deviceList.value
    .filter((item) => item.lon && item.lat)
    .forEach((item) => {
      const pt = new BMapGL.Point(Number(item.lon), Number(item.lat));
      const img = item.hasEvent == 1 ? monitorEventIcon : monitorIcon;
      const icon = new BMapGL.Icon(img, new BMapGL.Size(30, 30));
      const marker = new BMapGL.Marker(pt, { icon });
      marker.addEventListener('click', (e) => {
        if (item.hasEvent == 1) {
          queryParams.value.params.deviceId = item.id;
          queryParams.value.pageNum = 1;
          getList();
        }
      });
      bdmap.value.addOverlay(marker);
    });
};
const showDetails = (row) => {
  getEvent(row.id).then(({ code, data }) => {
    if (code === 200) {
      data.ext1 = JSON.parse(data.ext1) || [];
      data.ext2 = JSON.parse(data.ext2) || {};
      data.status = data.status || '2';
      let imgList = [];
      let videoList = [];
      if (data.ext1.length) {
        videoList = data.ext1
          .filter((item) => item.includes('mp4'))
          .map((item) => `${import.meta.env.VITE_APP_BASE_HOST}/api/oss/local/upload/${item}`);
        imgList = data.ext1
          .filter((item) => !item.includes('mp4'))
          .map((item) => `${import.meta.env.VITE_APP_BASE_HOST}/api/oss/local/upload/${item}`);
      }
      if(data.ext2.EventVideoPath){
        videoList = [data.ext2.EventVideoPath];
      }

      form.value = data;
      Object.assign(form.value, { imgList, videoList });
      dialog.visible = true;
      nextTick(() => {
        form.value.videoList.forEach((item, index) => {
          new DPlayer({
            container: document.getElementById(`dplayer${index}`),
            video: {
              url: item
            }
          });
        });
      });
      const { content, ext2 } = form.value;
      if (content && base64Decoded(content) && ext2.reportTime) {
        showReport.value = true;
        dealReportData(base64Decoded(content), ext2.reportTime);
      }
    }
  });
};

const generateClick = () => {
  dialog.loading = ElLoading.service({
    lock: true,
    text: '正在生成AI报告...',
    fullscreen: false,
    target: '.dialog-loading-warp',
    background: 'rgba(255, 255, 255, 0.6)'
  });
  generateReport(form.value.id).then(async ({ code, msg }) => {
    dialog.loading.close();
    if (code == 200 && msg) {
      showReport.value = true;
      const { report, time } = JSON.parse(msg).data.outputs;
      const reportHtml = report.replace(/```/g, '').replace(/html\n/, '');
      reportTime.value = time;
      updateEvent({
        id: form.value.id,
        content: base64Encoded(reportHtml),
        ext2: JSON.stringify({
          ...form.value.ext2,
          reportTime: time
        })
      });
      dealReportData(reportHtml, time);
      proxy?.$modal.msgSuccess('报告生成成功');
    } else {
      proxy?.$modal.msgError('报告生成失败');
    }
  });
};
const saveClick = async () => {
  const { ext2, createTime, level, status, addr } = form.value;
  const params = {
    id: form.value.id,
    createTime,
    level,
    status,
    addr,
    ext2: JSON.stringify({
      ...ext2
    })
  };
  if (showReport.value) {
    let htmlcontent = '';
    const text = editorRef.value.getText();
    if (text) {
      htmlcontent = editorRef.value.getHtml();
    }
    await updateEvent({
      ...params,
      content: base64Encoded(htmlcontent),
      ext2: JSON.stringify({
        ...ext2,
        reportTime: reportTime.value
      })
    });
  } else {
    await updateEvent(params);
  }
  getList();
  getStat();
  getEventTypeOptions();
  proxy?.$modal.msgSuccess('保存成功');
};
const extractDate = (dateStr) => {
  // 统一处理两种格式的正则表达式
  const match = dateStr.match(/(\d{4})[^\d]*(\d{1,2})[^\d]*(\d{1,2})/);

  if (!match) return null;

  return {
    year: parseInt(match[1]),
    month: parseInt(match[2]),
    day: parseInt(match[3])
  };
};
const dealReportData = async (reportHtml, time) => {
  const res = await proxy?.getConfigKey('report_seq');
  reportSeq.value = Number(res.data);
  valueHtml.value = reportHtml;
  const { year, month, day } = extractDate(time);
  reportForm.year = year;
  reportForm.month = month;
  reportForm.day = day;
  reportForm.seq = reportSeq.value;
};
const extractTitleAndContents = (htmlString) => {
  // 提取标题（从 <h2><strong> 中获取）
  const titleMatch = htmlString.match(/<h2[^>]*>.*?<strong>(.*?)<\/strong>.*?<\/h2>/is);
  const title = titleMatch ? titleMatch[1].trim() : '';

  // 提取所有 <p> 内容（从 <p><span> 中获取）
  const contentMatches = [...htmlString.matchAll(/<p[^>]*>.*?<span[^>]*>(.*?)<\/span>.*?<\/p>/gis)];
  const contents = contentMatches.map((match) => match[1].trim());

  return {
    title,
    contents
  };
};
const htmlToPdfFn = async () => {
  reportFormRef.value.validate((valid) => {
    if (valid) {
      downLoading.value = true;
      const { title, contents } = extractTitleAndContents(editorRef.value.getHtml());
      reportForm.title = title;
      reportForm.content = contents.join('');
      //import.meta.env.VITE_APP_ENV === 'development' ? 'loadFile/generate' :
      let url = `${import.meta.env.VITE_APP_BASE_HOST}/generate`;
      if (import.meta.env.DEV) {
        url = 'loadFile/generate';
      }
      downloadFile(url, {
        method: 'POST',
        data: reportForm,
        filename: `${reportForm.title}.${reportForm.type}`,
        onProgress: (percent) => {
          console.log(percent);
          if (percent == 100) {
            downLoading.value = false;
            proxy?.updateConfigByKey('report_seq', reportSeq.value + 1);
            proxy?.$modal.msgSuccess('报告导出成功');
          }
        }
      });
    }
  });
};
const dialogClose = () => {
  showReport.value = false;
  dialog.loading && dialog.loading.close();
};
const formSubmit = async (field, obj = '') => {
  // const { id } = form.value;
  // const params = {
  //   id
  // };
  // if (obj) {
  //   params[obj] = form.value[obj];
  //   params[obj] = JSON.stringify(params[obj]);
  // } else {
  //   params[field] = form.value[field];
  // }
  // await updateEvent(params);
  // getList();
  // if (field === 'status') {
  //   getStat();
  // }
  // if (field === 'ext2.lx') {
  //   getEventTypeOptions();
  // }
};
</script>
<style lang="scss" scoped>
.home {
  height: 100%;
  background-color: #f0f2f5;
  position: relative;

  .left-part {
    position: absolute;
    width: 300px;
    top: 10px;
    left: 20px;
    bottom: 10px;
    z-index: 10;
    display: flex;
    flex-direction: column;

    > .el-card:nth-child(-n + 3) {
      height: 22%;
      flex-shrink: 0;

      :deep(.el-card__body) {
        height: 70%;
      }
    }

    > .el-card:last-child {
      flex: 1;

      :deep(.el-card__body) {
        height: 80%;
      }
    }
  }

  .right-part {
    position: absolute;
    background: #fff;
    border-radius: 4px;
    top: 0;
    width: 550px;
    right: 0;
    bottom: 0px;
    z-index: 10;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
  }

  .expandOrFold {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    right: 550px;
    cursor: pointer;
    z-index: 10;

    img {
      height: 50px;
    }
  }
}

.custom-title {
  display: flex;
  align-items: center;
  color: #000000;
  font-size: 16px;

  img {
    height: 16px;
    margin-right: 5px;
  }
}

.custom-card {
  display: flex;
  justify-content: space-between;
  height: 100%;

  .card-item {
    display: flex;
    width: 22.5%;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
    background: #e3eefe;
    color: #2d5794;
    border-radius: 4.8px;

    span:first-child {
      flex: 1;
      font-size: 22px;
      margin-top: 10px;
      display: flex;
      align-items: center;
    }

    span:last-child {
      width: 80%;
      text-align: center;
      height: 26px;
      line-height: 26px;
      border-top: 0.6px solid #d0dff4;
      font-size: 10px;
    }
  }
}

.week-card {
  .card-item {
    background: #fef4e3;

    span:first-child {
      color: #7c5b22;
    }

    span:last-child {
      border-color: #eddbbc;
      color: #8c692e;
    }
  }
}

.day-card {
  .card-item {
    background: #e3fef0;

    span:first-child {
      color: #248647;
    }

    span:last-child {
      border-color: #ade7cd;
      color: #238546;
    }
  }
}

.map {
  width: 100%;
  height: 100%;
}

.event-title {
  flex-shrink: 0;
  padding: 10px;
  background: linear-gradient(180deg, #ffffff 0%, #f5f5f5 100%);
  border-radius: 4px 4px 0 0;

  > div {
    display: flex;
    align-items: center;

    > .el-select {
      flex-shrink: 0;
    }
  }
}

.event-list {
  flex: 1;
  overflow-y: auto;

  :deep() {
    .el-table__cell {
      border: none;
    }
  }
}

.event-footer {
  height: 60px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding-right: 20px;

  .pagination-container {
    margin-top: 0;
  }

  :deep() {
    .el-pagination.is-background .btn-next,
    .el-pagination.is-background .btn-prev,
    .el-pagination.is-background .el-pager li {
      background: transparent;
      border: 1px solid #00000026;
      color: #000000a6;
    }

    .el-pagination.is-background .is-active {
      background: #1890ff !important;
      border: none !important;
      color: #fff !important;
      font-weight: normal;
    }
  }
}

.event-media {
  border: 1px solid #f0f0f0;

  &-title {
    background: #fbfbfb;
    padding: 10px;
    font-size: 14px;
    color: #000000;
  }

  &-content {
    padding: 20px;

    .imgs {
      display: flex;
      flex-wrap: wrap;

      .el-image {
        height: 100px;
        width: 100px;
        margin-right: 10px;
        border-radius: 4px;
        margin-top: 10px;
      }
    }

    .videos {
      display: flex;
      flex-wrap: wrap;

      div {
        height: 200px;
        width: 32%;
        border-radius: 4px;
        margin-right: 10px;
        margin-top: 10px;
      }
    }
  }
}

.report-btn {
  text-align: center;
  margin-top: 20px;

  img {
    height: 62px;
    cursor: pointer;
  }
}

.hidden-report {
  position: absolute;
  visibility: hidden;
  left: -9999px;
  top: -9999px;
  width: max-content;
  height: max-content;
  display: inline-block;
  contain: layout;
}

.report-content {
  width: 800px;
  height: auto;
  padding: 20px;
  background-color: #fff;
  border: 1px solid #eee;
}

.report-editor {
  margin-top: 20px;
}

.report-title {
  color: #5d5d5dd9;
  font-size: 14px;
}
</style>
