<template>
  <el-dialog
    v-model="visible"
    :title="title"
    width="420px"
    destroy-on-close
    append-to-body
    class="site-pick-dialog"
    @closed="onClosed">
    <p class="hint">请选择车辆要前往的目标站点。</p>
    <el-input
      v-model="filter"
      clearable
      placeholder="搜索站点 ID / 名称"
      class="filter-input"
    />
    <el-scrollbar max-height="280px" class="site-scroll">
      <button
        v-for="s in filteredSites"
        :key="s.id"
        type="button"
        class="site-row"
        :class="{ active: selectedId === s.id }"
        @click="selectedId = s.id">
        <span class="sid">#{{ s.id }}</span>
        <span class="sname">{{ s.name || '未命名' }}</span>
      </button>
      <div v-if="!filteredSites.length" class="empty">无匹配站点</div>
    </el-scrollbar>
    <template #footer>
      <el-button @click="visible = false">取消</el-button>
      <el-button :loading="mapPicking" @click="emitPickOnMap">在地图上拾取</el-button>
      <el-button type="primary" :disabled="selectedId == null" @click="confirm">确认前往</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { SitePickOption } from '@/utils/carActionExecute'

const props = defineProps<{
  modelValue: boolean
  title?: string
  sites: SitePickOption[]
}>()

const emit = defineEmits<{
  'update:modelValue': [v: boolean]
  confirm: [siteId: number]
  pickOnMap: []
}>()

const visible = computed({
  get: () => props.modelValue,
  set: (v) => emit('update:modelValue', v)
})

const filter = ref('')
const selectedId = ref<number | null>(null)
const mapPicking = ref(false)

const filteredSites = computed(() => {
  const q = filter.value.trim().toLowerCase()
  if (!q) return props.sites
  return props.sites.filter(
    (s) =>
      String(s.id).includes(q) ||
      s.name.toLowerCase().includes(q) ||
      s.label.toLowerCase().includes(q)
  )
})

watch(
  () => props.modelValue,
  (open) => {
    if (open) {
      filter.value = ''
      selectedId.value = props.sites[0]?.id ?? null
    }
  }
)

function confirm() {
  if (selectedId.value == null) return
  emit('confirm', selectedId.value)
  visible.value = false
}

function emitPickOnMap() {
  mapPicking.value = true
  emit('pickOnMap')
}

function onClosed() {
  mapPicking.value = false
}

defineExpose({ close: () => { visible.value = false }, endMapPick: () => { mapPicking.value = false } })
</script>

<style scoped>
/* el-dialog 会 teleport 到 body，脱离 .mg-content 的深色覆盖，在所有主题下都是白底，
   因此对话框内自定义内容统一用固定深紫字 + 浅紫面板（不能用 --mg-text-* 变量，
   那些在深色主题里是白色会变白底白字）。 */
.hint { margin: 0 0 10px; font-size: 13px; color: rgba(60, 30, 110, 0.75); }
.filter-input { margin-bottom: 8px; }
.site-scroll { border: 1px solid rgba(170, 110, 250, 0.18); border-radius: 8px; }
.site-row {
  display: flex;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-bottom: 1px solid rgba(170, 110, 250, 0.10);
  background: transparent;
  color: rgba(60, 30, 110, 0.92);
  text-align: left;
  cursor: pointer;
  transition: background 0.12s ease;
}
.site-row:hover { background: rgba(167, 139, 250, 0.15); }
.site-row.active {
  background: rgba(124, 58, 237, 0.16);
  color: #5b21b6;
  font-weight: 600;
  box-shadow: inset 3px 0 0 #7c3aed;
}
.sid { font-family: ui-monospace, Consolas, monospace; font-size: 12px; color: #7c3aed; flex: none; }
.sname { flex: 1; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.empty { padding: 20px; text-align: center; color: rgba(120, 90, 160, 0.7); font-size: 12px; }
</style>
