<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.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 day-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>
        <BaseChart width="100%" height="100%" :option="pieOptions" />
      </el-card>
    </div>
    <div class="right-part">
      <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-input v-model="queryParams.ext2.lx" style="width: 110px; margin-left: 10px" placeholder="事件类型" />
          <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-input v-model="queryParams.addr" style="width: 210px" 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 style="color: #ff6124">未解决</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">
      <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="请输入" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="事件类型" prop="ext2.lx">
                <el-input v-model="form.ext2.lx" placeholder="请输入" />
                <!-- <el-select v-model="form.ext2.lx" clearable placeholder="请选择">
                <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="createTime">
                <el-date-picker style="width: 100%" v-model="form.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="请输入" />
              </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="请输入" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div class="event-media" v-if="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.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="default" />
              <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="fileType" clearable placeholder="请选择">
              <el-option label="pdf" :value="1"></el-option>
              <el-option label="word" :value="2"></el-option>
              <el-option label="图片" :value="3"></el-option>
            </el-select>
          </div>
          <div>
            <el-button color="#2AB55C" style="color: #fff; margin-top: 20px; margin-bottom: 30px" @click="htmlToPdfFn">导出报告</el-button>
          </div>
        </template>
      </div>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { Search } from '@element-plus/icons-vue';
import BaseChart from '@/components/BaseChart/index.vue';
import monitorIcon from '@/assets/images/monitor.svg';
import DPlayer from 'dplayer';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { exportAsPdf, exportAsWord, exportAsImage } from 'html2image-pdf-word';
import { listEvent, generateReport, updateEvent } from '@/api/system/event';
import { dateFormat } from '@/utils/index';
import { ElLoading } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const bdmap = ref(null);
const marks = ref([
  {
    longitude: 118.84651017058795,
    latitude: 32.03286965957209
  },
  {
    longitude: 118.87381865809128,
    latitude: 32.050866853291296
  },
  {
    longitude: 118.88459832421101,
    latitude: 32.01094988629638
  }
]);
const { event_level } = toRefs<any>(proxy?.useDict('event_level'));
const { event_status } = toRefs<any>(proxy?.useDict('event_status'));
const editorRef = shallowRef();
const editorConfig = { placeholder: '请输入内容...' };
// 内容 HTML
const valueHtml = ref('');
const handleCreated = (editor) => {
  console.log('created', editor);
  editorRef.value = editor; // 记录 editor 实例，重要！
};
const fileType = ref(1);
const showReport = ref(false);
const htmlToPdfFn = async () => {
  const dom: any = document.querySelector('.w-e-text-container');
  const filename = '报告';
  const type = fileType.value;
  switch (type) {
    case 1:
      await exportAsPdf(dom, filename);
      break;
    case 2:
      await exportAsWord(dom, filename);
      break;
    case 3:
      await exportAsImage(dom, filename);
      break;
  }
};

const queryParams = ref({
  pageNum: 1,
  pageSize: 15,
  level: undefined,
  ext2: {
    lx: undefined
  },
  dateRange: undefined,
  addr: undefined,
  params: {
    beginTime: '',
    endTime: ''
  }
});
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 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.monthAlready,
            name: '已解决',
            itemStyle: {
              color: '#FAC858'
            }
          },
          {
            value: statData.monthNot,
            name: '未解决',
            itemStyle: {
              color: '#93BEFF'
            }
          },
          {
            value: statData.monthReport,
            name: '已上报',
            itemStyle: {
              color: '#507AFC'
            }
          }
        ],
        labelLine: {
          show: false
        },
        label: {
          show: false,
          position: 'center'
        }
      }
    ]
  };
  return options;
});
const eventList = ref([]);
const total = ref(0);
onMounted(() => {
  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);
  });
  showMarks();
  getList();
  getStat();
});
const getList = async () => {
  const { dateRange } = queryParams.value;
  if (dateRange && dateRange.length) {
    queryParams.value.params.beginTime = dateRange[0];
    queryParams.value.params.endTime = dateRange[1];
  } else {
    queryParams.value.params.beginTime = undefined;
    queryParams.value.params.endTime = undefined;
  }
  const res = await listEvent(queryParams.value);
  eventList.value = res.rows.map((item: any) => ({
    ...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 res = await listEvent({});
  statData.monthCount = res.total;
  statData.monthAlready = res.rows.filter((item) => item.status == '1').length;
  statData.monthNot = res.rows.filter((item) => item.status == '2' || item.status === null).length;
  statData.monthReport = res.rows.filter((item) => item.status == '3').length;
};
const resetQuery = () => {
  queryParams.value = {
    pageNum: 1,
    pageSize: 15,
    level: undefined,
    ext2: {
      lx: undefined
    },
    dateRange: undefined,
    addr: undefined,
    params: {
      beginTime: '',
      endTime: ''
    }
  };
  getList();
};
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});
const showMarks = () => {
  bdmap.value.clearOverlays();
  marks.value.forEach((item) => {
    const pt = new BMapGL.Point(Number(item.longitude), Number(item.latitude));
    const icon = new BMapGL.Icon(monitorIcon, new BMapGL.Size(30, 30));
    const marker = new BMapGL.Marker(pt, { icon });
    bdmap.value.addOverlay(marker);
  });
};
const showDetails = (row) => {
  dialog.visible = true;
  let imgList = [];
  let videoList = [];
  if (row.ext1 && row.ext1.length) {
    videoList = row.ext1.filter((item) => item.includes('mp4')).map((item) => `http://jtjai.xt.wenhq.top:8083/api/oss/local/upload/${item}`);
    imgList = row.ext1.filter((item) => !item.includes('mp4')).map((item) => `http://jtjai.xt.wenhq.top:8083/api/oss/local/upload/${item}`);
  }
  Object.assign(form.value, JSON.parse(JSON.stringify(row)), { imgList, videoList });
  nextTick(() => {
    form.value.videoList.forEach((item, index) => {
      new DPlayer({
        container: document.getElementById(`dplayer${index}`),
        video: {
          url: item
        }
      });
    });
  });
};

const generateClick = () => {
  dialog.loading = ElLoading.service({
    lock: true,
    text: '正在生成报告，请稍候...',
    fullscreen: false,
    target: '.dialog-loading-warp',
    background: 'rgba(255, 255, 255, 0.6)'
  });
  generateReport(form.value.id).then(({ code, msg }) => {
    dialog.loading.close();
    if (code == 200 && msg) {
      showReport.value = true;
      valueHtml.value = JSON.parse(msg).data.outputs.report;
      proxy?.$modal.msgSuccess('报告生成成功');
    } else {
      proxy?.$modal.msgError('报告生成失败');
    }
  });
};
const dialogClose = () => {
  showReport.value = false;
  dialog.loading && dialog.loading.close();
};
const formSubmit = async (field) => {
  const { id } = form.value;
  const params = {
    id
  };
  params[field] = form.value[field];
  await updateEvent(params);
  getList();
  getStat();
};
</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: 10px;
    width: 550px;
    right: 20px;
    bottom: 10px;
    z-index: 10;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
  }
}

.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>
