<template>
  <div class="mc-panel">
    <div class="mc-toolbar">
      <el-input
        v-model="keyword"
        class="mc-search"
        placeholder="请输入地图名称搜索"
        clearable
        :prefix-icon="Search"
      />
      <el-button type="primary" :icon="Plus" @click="openCreate">添加地图关系</el-button>
    </div>

    <el-table
      v-loading="loading"
      :data="pageRows"
      class="mc-table"
      border
      empty-text="还没有地图连接关系，点击右上角「添加地图关系」创建跨楼层 / 拼接连接。"
    >
      <el-table-column prop="id" label="ID" width="80" sortable />
      <el-table-column prop="sourceMap" label="起始地图名称" min-width="160" show-overflow-tooltip />
      <el-table-column prop="sourceMapId" label="起始地图ID" width="110" />
      <el-table-column prop="sourceStation" label="起始切换点站点" min-width="150" show-overflow-tooltip />
      <el-table-column prop="targetMap" label="目的地图名称" min-width="160" show-overflow-tooltip />
      <el-table-column prop="targetMapId" label="目的地图ID" width="110" />
      <el-table-column prop="targetStation" label="目的切换点站点" min-width="150" show-overflow-tooltip />
      <el-table-column label="转移代价（cm）" width="130">
        <template #default="{ row }">
          <span class="mc-cost mg-mono">{{ row.cost }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="130" align="right" fixed="right">
        <template #default="{ row }">
          <el-button link type="primary" @click="openEdit(row)">编辑</el-button>
          <el-button link type="danger" @click="onDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="mc-pager">
      <el-pagination
        v-model:current-page="page"
        v-model:page-size="pageSize"
        :total="filtered.length"
        :page-sizes="[10, 20, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        background
      />
    </div>

    <!-- 添加 / 编辑 地图关系 -->
    <el-dialog
      v-model="dialogVisible"
      :title="editingId === null ? '添加地图关系' : '编辑地图关系'"
      width="520px"
      class="map-conn-dialog"
      append-to-body
      @closed="onDialogClosed"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="right">
        <el-form-item label="起始地图" prop="sourceMap">
          <el-select v-model="form.sourceMap" placeholder="请选择起始地图" filterable style="width: 100%">
            <el-option v-for="m in mapOptions" :key="m" :label="m" :value="m" />
          </el-select>
        </el-form-item>
        <el-form-item label="起始切换点站点" prop="sourceStation">
          <el-select
            v-model="form.sourceStation"
            placeholder="请选择起始切换点站点"
            filterable
            allow-create
            default-first-option
            style="width: 100%"
          >
            <el-option v-for="s in stationOptions" :key="s" :label="s" :value="s" />
          </el-select>
        </el-form-item>
        <el-form-item label="目的地图" prop="targetMap">
          <el-select v-model="form.targetMap" placeholder="请选择目的地图" filterable style="width: 100%">
            <el-option v-for="m in mapOptions" :key="m" :label="m" :value="m" />
          </el-select>
        </el-form-item>
        <el-form-item label="目的切换点站点" prop="targetStation">
          <el-select
            v-model="form.targetStation"
            placeholder="请选择目的切换点站点"
            filterable
            allow-create
            default-first-option
            style="width: 100%"
          >
            <el-option v-for="s in stationOptions" :key="s" :label="s" :value="s" />
          </el-select>
        </el-form-item>
        <el-form-item label="转移代价(cm)" prop="cost">
          <el-input-number v-model="form.cost" :min="0" :step="100" :controls="false" style="width: 100%" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="onSubmit">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { Search, Plus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import { mapsApi } from '@/api/mapEdit'
import { mapConnectionApi, type MapConnection } from '@/api/mapConnection'

const loading = ref(false)
const saving = ref(false)
const rows = ref<MapConnection[]>([])
const mapOptions = ref<string[]>([])
const stationOptions = ref<string[]>([])

const keyword = ref('')
const page = ref(1)
const pageSize = ref(10)

const dialogVisible = ref(false)
const editingId = ref<number | null>(null)
const formRef = ref<FormInstance>()
const form = reactive({
  sourceMap: '',
  sourceStation: '',
  targetMap: '',
  targetStation: '',
  cost: 1000
})

const rules: FormRules = {
  sourceMap: [{ required: true, message: '请选择起始地图', trigger: 'change' }],
  sourceStation: [{ required: true, message: '请选择起始切换点站点', trigger: 'change' }],
  targetMap: [{ required: true, message: '请选择目的地图', trigger: 'change' }],
  targetStation: [{ required: true, message: '请选择目的切换点站点', trigger: 'change' }],
  cost: [{ required: true, message: '请输入转移代价', trigger: 'blur' }]
}

const filtered = computed(() => {
  const kw = keyword.value.trim().toLowerCase()
  if (!kw) return rows.value
  return rows.value.filter(
    (r) => r.sourceMap.toLowerCase().includes(kw) || r.targetMap.toLowerCase().includes(kw)
  )
})

const pageRows = computed(() => {
  const start = (page.value - 1) * pageSize.value
  return filtered.value.slice(start, start + pageSize.value)
})

// 搜索 / 分页大小变化时回到第一页，避免停留在空白页。
watch([keyword, pageSize], () => {
  page.value = 1
})

async function refresh() {
  loading.value = true
  try {
    rows.value = await mapConnectionApi.list()
    stationOptions.value = mapConnectionApi.stationSuggestions()
  } catch (err) {
    ElMessage.error(`加载地图连接失败：${(err as Error).message}`)
  } finally {
    loading.value = false
  }
}

async function loadMaps() {
  try {
    const r = await mapsApi.list()
    mapOptions.value = r.maps.map((m) => m.name)
  } catch {
    // 地图列表拉取失败不阻塞连接管理；下拉为空时仍可手动输入站点。
    mapOptions.value = []
  }
}

function resetForm() {
  form.sourceMap = ''
  form.sourceStation = ''
  form.targetMap = ''
  form.targetStation = ''
  form.cost = 1000
}

function openCreate() {
  editingId.value = null
  resetForm()
  stationOptions.value = mapConnectionApi.stationSuggestions()
  dialogVisible.value = true
}

function openEdit(row: MapConnection) {
  editingId.value = row.id
  form.sourceMap = row.sourceMap
  form.sourceStation = row.sourceStation
  form.targetMap = row.targetMap
  form.targetStation = row.targetStation
  form.cost = row.cost
  stationOptions.value = mapConnectionApi.stationSuggestions()
  dialogVisible.value = true
}

function onDialogClosed() {
  formRef.value?.clearValidate()
}

async function onSubmit() {
  if (!formRef.value) return
  await formRef.value.validate(async (ok) => {
    if (!ok) return
    saving.value = true
    try {
      const payload = {
        sourceMap: form.sourceMap,
        sourceStation: form.sourceStation,
        targetMap: form.targetMap,
        targetStation: form.targetStation,
        cost: form.cost
      }
      if (editingId.value === null) {
        await mapConnectionApi.create(payload)
        ElMessage.success('已添加地图连接')
      } else {
        await mapConnectionApi.update(editingId.value, payload)
        ElMessage.success('已更新地图连接')
      }
      dialogVisible.value = false
      await refresh()
    } catch (err) {
      ElMessage.error(`保存失败：${(err as Error).message}`)
    } finally {
      saving.value = false
    }
  })
}

async function onDelete(row: MapConnection) {
  try {
    await ElMessageBox.confirm(
      `确认删除「${row.sourceMap} → ${row.targetMap}」这条地图连接？`,
      '删除地图连接',
      { type: 'warning', confirmButtonText: '删除', cancelButtonText: '取消', confirmButtonClass: 'el-button--danger' }
    )
    await mapConnectionApi.remove(row.id)
    ElMessage.success('已删除')
    // 删除后当前页可能空了，回退一页。
    if (pageRows.value.length === 1 && page.value > 1) page.value -= 1
    await refresh()
  } catch (err) {
    if (err === 'cancel' || err === 'close') return
    ElMessage.error(`删除失败：${(err as Error).message}`)
  }
}

onMounted(() => {
  refresh()
  loadMaps()
})

defineExpose({ refresh })
</script>

<style scoped>
.mc-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
}
.mc-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
}
.mc-search {
  width: 300px;
  max-width: 60%;
}
.mc-table {
  flex: 1;
  min-height: 0;
}
.mc-cost {
  font-variant-numeric: tabular-nums;
}
.mc-pager {
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  padding-top: 2px;
}
</style>
