<template>
  <main class="amap-page">
    <div ref="mapContainerRef" class="amap-container"></div>

    <header class="top-menu">
      <h1>机场道面外来物检测系统</h1>
      <nav class="menu-actions" aria-label="页面菜单">
        <el-button
          v-for="item in menuItems"
          :key="item.key"
          :type="activeDialog === item.key ? 'primary' : 'default'"
          @click="handleMenuClick(item.key)"
        >
          {{ item.label }}
        </el-button>
      </nav>
    </header>

    <section class="bottom-card-row" aria-label="底部监控信息">
      <section class="video-card" aria-label="视频监控">
        <VideoView />
      </section>

      <el-card class="fod-detail-card" shadow="never">
        <section class="fod-detail-panel" aria-label="异物检测详情">
          <div class="fod-header">
            <span>异物检测信息</span>
            <el-tag size="small" :type="statusTagType" effect="dark">
              {{ detectionInfo.status }}
            </el-tag>
          </div>

          <dl class="fod-grid">
            <div v-for="item in detectionFields" :key="item.label" class="fod-item">
              <dt>{{ item.label }}</dt>
              <dd>{{ item.value }}</dd>
            </div>
          </dl>

          <div class="fod-images">
            <el-image
              v-for="(image, index) in detectionImages"
              :key="image"
              class="fod-image"
              :src="image"
              :preview-src-list="detectionImages"
              :initial-index="index"
              fit="cover"
              preview-teleported
            />
          </div>
        </section>
      </el-card>

      <el-card class="fod-table-card" shadow="never">
        <section class="fod-table-panel" aria-label="异物检测列表">
          <el-table :data="detectionRows" height="100%" size="small" class="fod-table">
            <el-table-column prop="index" label="序号" width="52" align="center" />
            <el-table-column prop="location" label="经纬度" min-width="132" show-overflow-tooltip />
            <el-table-column prop="discoveredAt" label="发现时间" min-width="132" show-overflow-tooltip />
            <el-table-column label="操作" width="60" align="center">
              <template #default="{ row }">
                <el-button link type="primary" size="small" @click="selectDetection(row)">
                  查看
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </section>
      </el-card>
    </section>

    <el-dialog
      v-model="dialogVisible"
      :title="currentDialogTitle"
      width="76vw"
      class="system-dialog"
      append-to-body
      destroy-on-close
      @closed="activeDialog = ''"
    >
      <component :is="currentDialogComponent" v-if="currentDialogComponent" />
    </el-dialog>
  </main>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import BlockedDataView from '../blocked-data/index.vue'
import ConfigView from '../config/index.vue'
import HistoryDataView from '../history-data/index.vue'
import VideoView from '../video/index.vue'

const AMAP_KEY = 'f570ff5caa2f5c956fc6bf66cacabb93'
const AMAP_SECURITY_CODE = '114b8c8d2356490283ea98293a9c4ae3'
const AMAP_SCRIPT_ID = 'amap-jsapi'
const AMAP_CALLBACK_NAME = '__initAmapMapView'
const MAP_CENTER = [120.09671, 36.365238]
const MAP_ZOOM = 15
const MAP_ROTATION = -72.6

const mapContainerRef = ref(null)
const activeDialog = ref('')
const detectionInfo = {
  discoveredAt: '2026-06-12 14:35:20',
  location: '120.096710E, 36.365238N',
  intensity: '82%',
  count: 3,
  category: '疑似异物',
  status: '待处理',
}
const detectionImages = [
  createDetectionImage('#0f766e', 'FOD-01'),
  createDetectionImage('#1d4ed8', 'FOD-02'),
  createDetectionImage('#b45309', 'FOD-03'),
]
const detectionRows = [
  {
    index: 1,
    location: '120.096710, 36.365238',
    discoveredAt: '2026-06-12 14:35:20',
  },
  {
    index: 2,
    location: '120.096842, 36.365104',
    discoveredAt: '2026-06-12 14:36:08',
  },
  {
    index: 3,
    location: '120.096514, 36.365387',
    discoveredAt: '2026-06-12 14:37:42',
  },
  {
    index: 4,
    location: '120.096933, 36.365291',
    discoveredAt: '2026-06-12 14:39:16',
  },
]
const detectionFields = computed(() => [
  { label: '发现时间', value: detectionInfo.discoveredAt },
  { label: '位置信息', value: detectionInfo.location },
  { label: '探测强度', value: detectionInfo.intensity },
  { label: '检测次数', value: detectionInfo.count },
  { label: '异物类别', value: detectionInfo.category },
  { label: '处理状态', value: detectionInfo.status },
])
const statusTagType = computed(() => {
  if (detectionInfo.status === '已处理') {
    return 'success'
  }

  if (detectionInfo.status === '处理中') {
    return 'warning'
  }

  return 'danger'
})
const menuItems = [
  { key: 'home', label: '首页' },
  { key: 'history', label: '历史数据' },
  { key: 'config', label: '配置' },
  { key: 'blocked', label: '屏蔽数据' },
]
const dialogMap = {
  history: {
    title: '历史数据',
    component: HistoryDataView,
  },
  config: {
    title: '配置',
    component: ConfigView,
  },
  blocked: {
    title: '屏蔽数据',
    component: BlockedDataView,
  },
}
const dialogVisible = computed({
  get: () => Boolean(activeDialog.value),
  set: (value) => {
    if (!value) {
      activeDialog.value = ''
    }
  },
})
const currentDialogTitle = computed(() => dialogMap[activeDialog.value]?.title || '')
const currentDialogComponent = computed(() => dialogMap[activeDialog.value]?.component || null)

let mapInstance = null
let amapScriptPromise = null

function createDetectionImage(color, label) {
  const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" width="320" height="200" viewBox="0 0 320 200">
      <defs>
        <linearGradient id="bg" x1="0" x2="1" y1="0" y2="1">
          <stop offset="0" stop-color="${color}" stop-opacity="0.95"/>
          <stop offset="1" stop-color="#020617" stop-opacity="1"/>
        </linearGradient>
      </defs>
      <rect width="320" height="200" fill="url(#bg)"/>
      <path d="M0 132 C62 108 94 154 150 130 C206 106 244 82 320 112 L320 200 L0 200 Z" fill="#111827" opacity="0.72"/>
      <rect x="18" y="18" width="284" height="164" rx="10" fill="none" stroke="#e2e8f0" stroke-opacity="0.36"/>
      <circle cx="160" cy="100" r="34" fill="none" stroke="#fef3c7" stroke-width="2.5" stroke-dasharray="7 6"/>
      <path d="M141 105 L158 74 L180 121 Z" fill="#fbbf24" opacity="0.86"/>
      <text x="24" y="44" fill="#f8fafc" font-size="18" font-family="Arial, sans-serif" font-weight="700">${label}</text>
      <text x="24" y="168" fill="#cbd5e1" font-size="12" font-family="Arial, sans-serif">Foreign Object Detection Snapshot</text>
    </svg>`

  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`
}

function waitForAmapMapConstructor(timeout = 10000) {
  return new Promise((resolve, reject) => {
    const startedAt = Date.now()

    const checkAmap = () => {
      if (window.AMap?.Map) {
        resolve(window.AMap)
        return
      }

      if (Date.now() - startedAt >= timeout) {
        reject(new Error('AMap Map constructor is unavailable'))
        return
      }

      window.setTimeout(checkAmap, 50)
    }

    checkAmap()
  })
}

function loadAmapScript() {
  window._AMapSecurityConfig = {
    securityJsCode: AMAP_SECURITY_CODE,
  }

  if (window.AMap?.Map) {
    return Promise.resolve(window.AMap)
  }

  if (amapScriptPromise) {
    return amapScriptPromise
  }

  if (document.getElementById(AMAP_SCRIPT_ID)) {
    amapScriptPromise = waitForAmapMapConstructor()
    return amapScriptPromise
  }

  amapScriptPromise = new Promise((resolve, reject) => {
    window[AMAP_CALLBACK_NAME] = () => {
      waitForAmapMapConstructor().then(resolve).catch(reject)
    }

    const script = document.createElement('script')
    script.id = AMAP_SCRIPT_ID
    script.async = true
    script.src = `https://webapi.amap.com/maps?v=2.0&key=${AMAP_KEY}&callback=${AMAP_CALLBACK_NAME}`
    script.onload = () => {
      waitForAmapMapConstructor().then(resolve).catch(reject)
    }
    script.onerror = (error) => {
      amapScriptPromise = null
      reject(error)
    }
    document.head.appendChild(script)
  })

  amapScriptPromise = amapScriptPromise.catch((error) => {
    amapScriptPromise = null
    throw error
  })

  return amapScriptPromise
}

function selectDetection(row) {
  console.info('查看异物检测记录:', row)
}

function handleMenuClick(key) {
  if (key === 'home') {
    activeDialog.value = ''
    return
  }

  activeDialog.value = key
}

async function initMap() {
  try {
    const AMap = await loadAmapScript()

    if (!AMap?.Map) {
      throw new Error('AMap Map constructor is unavailable')
    }

    mapInstance = new AMap.Map(mapContainerRef.value, {
      viewMode: '3D',
      zoom: MAP_ZOOM,
      center: MAP_CENTER,
      pitch: 0,
      rotation: MAP_ROTATION,
      showLabel: false,
      layers: [
        new AMap.TileLayer.Satellite(),
      ],
    })
  } catch (error) {
    console.error('Load AMap failed:', error)
  }
}

onMounted(initMap)

onBeforeUnmount(() => {
  mapInstance?.destroy()
  mapInstance = null
  delete window[AMAP_CALLBACK_NAME]
})
</script>

<style scoped>
.amap-page {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #030712;
}

.amap-container {
  width: 100%;
  height: 100%;
}

.top-menu {
  position: absolute;
  top: 18px;
  left: 24px;
  right: 24px;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 56px;
  padding: 0 18px;
  border: 1px solid rgba(226, 232, 240, 0.26);
  border-radius: 14px;
  color: #f8fafc;
  background: rgba(2, 6, 23, 0.5);
  box-shadow: 0 20px 70px rgba(0, 0, 0, 0.28);
  backdrop-filter: blur(14px);
}

.top-menu h1 {
  margin: 0;
  overflow: hidden;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 10px;
  align-items: center;
}

.menu-actions :deep(.el-button) {
  min-width: 86px;
  margin: 0;
  border-color: rgba(226, 232, 240, 0.22);
  border-radius: 8px;
  color: #e5eefb;
  background: rgba(15, 23, 42, 0.66);
}

.menu-actions :deep(.el-button:hover) {
  border-color: rgba(56, 189, 248, 0.72);
  color: #ffffff;
  background: rgba(14, 116, 144, 0.72);
}

.menu-actions :deep(.el-button--primary) {
  border-color: rgba(34, 211, 238, 0.85);
  background: rgba(8, 145, 178, 0.86);
}

.bottom-card-row {
  position: absolute;
  left: 24px;
  right: 24px;
  bottom: 24px;
  z-index: 2;
  display: grid;
  grid-template-columns: 2fr 2fr 1fr;
  gap: 16px;
  height: 60%;
  min-height: 0;
}

.video-card,
.fod-detail-card,
.fod-table-card {
  min-width: 0;
  height: 100%;
  overflow: hidden;
  border: 1px solid rgba(226, 232, 240, 0.28);
  border-radius: 16px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.32);
  backdrop-filter: blur(10px);
}

.video-card {
  background: rgba(2, 6, 23, 0.28);
}

.video-card :deep(.monitor-page) {
  width: 100%;
  height: 100%;
}

.video-card :deep(.control-panel) {
  top: 12px;
  right: 12px;
  width: 212px;
  padding: 12px;
  transform: scale(0.5);
  transform-origin: top right;
}

.video-card :deep(.stream-status) {
  left: 12px;
  right: 12px;
  bottom: 12px;
  max-width: none;
}

.video-card :deep(.direction-pad) {
  grid-template-columns: repeat(3, 42px);
  grid-template-rows: repeat(3, 38px);
  gap: 7px;
}

.fod-detail-card,
.fod-table-card {
  color: #e5eefb;
  background: rgba(2, 6, 23, 0.48);
}

.fod-detail-card :deep(.el-card__body),
.fod-table-card :deep(.el-card__body) {
  height: 100%;
  padding: 14px;
}

.fod-detail-panel,
.fod-table-panel {
  min-width: 0;
  min-height: 0;
}

.fod-detail-panel {
  display: flex;
  flex-direction: column;
}

.fod-header {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(226, 232, 240, 0.16);
  color: #f8fafc;
  font-size: 15px;
  font-weight: 700;
}

.fod-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 14px;
  flex: 0 0 auto;
  margin: 12px 0 0;
}

.fod-item {
  min-width: 0;
}

.fod-item dt {
  margin-bottom: 4px;
  color: rgba(203, 213, 225, 0.74);
  font-size: 12px;
  line-height: 1.2;
}

.fod-item dd {
  margin: 0;
  overflow: hidden;
  color: #f8fafc;
  font-size: 13px;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fod-images {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-content: end;
  gap: 8px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid rgba(226, 232, 240, 0.16);
}

.fod-image {
  width: 100%;
  height: 74px;
  overflow: hidden;
  border: 1px solid rgba(226, 232, 240, 0.18);
  border-radius: 8px;
  background: rgba(15, 23, 42, 0.62);
  cursor: zoom-in;
}

.fod-table-panel {
  overflow: hidden;
  border: 1px solid rgba(226, 232, 240, 0.14);
  border-radius: 10px;
  background: rgba(15, 23, 42, 0.28);
}

.fod-table {
  width: 100%;
  height: 100%;
  color: #e5eefb;
  background: transparent;
}

.fod-table :deep(.el-table__inner-wrapper::before) {
  display: none;
}

.fod-table :deep(.el-table__header-wrapper th) {
  border-bottom-color: rgba(226, 232, 240, 0.16);
  color: rgba(226, 232, 240, 0.82);
  background: rgba(15, 23, 42, 0.72);
  font-weight: 700;
}

.fod-table :deep(.el-table__row) {
  background: transparent;
}

.fod-table :deep(.el-table__row:hover > td.el-table__cell) {
  background: rgba(14, 165, 233, 0.16);
}

.fod-table :deep(td.el-table__cell) {
  border-bottom-color: rgba(226, 232, 240, 0.1);
  color: #e5eefb;
  background: transparent;
}

.fod-table :deep(.el-table__body-wrapper) {
  background: transparent;
}

:global(.system-dialog) {
  border: 1px solid rgba(226, 232, 240, 0.22);
  border-radius: 14px;
  background: rgba(2, 6, 23, 0.92);
  box-shadow: 0 32px 120px rgba(0, 0, 0, 0.56);
  backdrop-filter: blur(18px);
}

:global(.system-dialog .el-dialog__header) {
  padding: 18px 20px 12px;
  border-bottom: 1px solid rgba(226, 232, 240, 0.14);
}

:global(.system-dialog .el-dialog__title) {
  color: #f8fafc;
  font-size: 18px;
  font-weight: 800;
}

:global(.system-dialog .el-dialog__body) {
  padding: 18px 20px 20px;
  color: #e5eefb;
}

:global(.el-select__popper.el-popper) {
  border-color: rgba(226, 232, 240, 0.18);
  background: rgba(2, 6, 23, 0.96);
}

:global(.el-select-dropdown) {
  background: transparent;
}

:global(.el-select-dropdown__item) {
  color: #cbd5e1;
}

:global(.el-select-dropdown__item.is-hovering),
:global(.el-select-dropdown__item:hover) {
  color: #ffffff;
  background: rgba(14, 165, 233, 0.18);
}

:global(.el-select-dropdown__item.is-selected) {
  color: #67e8f9;
}

@media (max-width: 680px) {
  .top-menu {
    top: 12px;
    left: 12px;
    right: 12px;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 12px;
  }

  .top-menu h1 {
    font-size: 17px;
  }

  .menu-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .menu-actions :deep(.el-button) {
    min-width: 0;
  }

  .bottom-card-row {
    left: 12px;
    right: 12px;
    bottom: 12px;
    grid-template-columns: 1fr;
    gap: 10px;
    height: 72%;
    overflow: auto;
  }

  .video-card {
    min-height: 220px;
    border-radius: 12px;
  }

  .fod-detail-card,
  .fod-table-card {
    min-height: 220px;
    border-radius: 12px;
  }

  .fod-table-panel {
    min-height: 180px;
  }

  .fod-grid {
    grid-template-columns: 1fr;
  }
}
</style>
