<template>
  <section class="fleet-alloc">
    <div class="fa-header">
      <span class="fa-title">车队分配</span>
      <el-tag size="small" type="info" effect="plain">区域管理</el-tag>
      <span class="fa-sub">将车辆分配到车队，并设定车队名称 / 区域 / 楼层</span>
      <div class="spacer" />
      <el-button size="small" :icon="Refresh" :loading="loading" @click="reload(true)">重载</el-button>
      <el-button size="small" :icon="Plus" :disabled="!canWrite" @click="addFleet">新建车队</el-button>
      <el-button size="small" type="primary" :icon="Check" :loading="saving" :disabled="!canWrite || !dirty" @click="save">
        保存
      </el-button>
    </div>

    <div v-loading="loading" class="fa-body">
      <el-empty v-if="!fleets.length" description="暂无车队，点击「新建车队」开始分配" />

      <div v-for="(fleet, idx) in fleets" :key="fleet.id" class="fleet-card">
        <div class="fc-row">
          <el-input
            v-model="fleet.name"
            size="small"
            class="fc-name"
            placeholder="车队名称"
            :disabled="!canWrite"
            @input="markDirty">
            <template #prepend>名称</template>
          </el-input>
          <el-input
            v-model="fleet.region"
            size="small"
            class="fc-region"
            placeholder="区域"
            :disabled="!canWrite"
            @input="markDirty">
            <template #prepend>区域</template>
          </el-input>
          <el-input
            v-model="fleet.floor"
            size="small"
            class="fc-floor"
            placeholder="楼层"
            :disabled="!canWrite"
            @input="markDirty">
            <template #prepend>楼层</template>
          </el-input>
          <el-tag size="small" effect="plain">{{ fleet.carIds.length }} 辆</el-tag>
          <el-button
            size="small"
            type="danger"
            text
            :icon="Delete"
            :disabled="!canWrite"
            @click="removeFleet(idx)">
            删除
          </el-button>
        </div>

        <el-select
          v-model="fleet.carIds"
          size="small"
          multiple
          filterable
          collapse-tags
          collapse-tags-tooltip
          class="fc-cars"
          placeholder="选择要分配到该车队的车辆"
          :disabled="!canWrite"
          @change="markDirty">
          <el-option
            v-for="c in optionsForFleet(fleet)"
            :key="c.id"
            :label="c.label"
            :value="c.id"
            :disabled="c.takenByOther" />
        </el-select>
      </div>
    </div>

    <p v-if="unknownCarIds.length" class="fa-note">
      提示：以下已分配的车辆 ID 不在当前在册车辆中：{{ unknownCarIds.join('、') }}
    </p>
  </section>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { Refresh, Check, Plus, Delete } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { useConfigStore } from '@/stores/config'
import { useFleetGroups } from '@/composables/useFleetGroups'
import { DEFAULT_FLEET } from '@/mock/data/configs'
import type { FleetGroup, FleetLifecycleConfig } from '@/types/config'

const props = defineProps<{
  cars: { id: string; name?: string }[]
  canWrite: boolean
}>()

const emit = defineEmits<{ saved: [] }>()

const store = useConfigStore()
const { reload: reloadShared } = useFleetGroups()
const loading = ref(false)
const saving = ref(false)
const dirty = ref(false)

// 保留 fleet 配置中除 groups 以外的字段（OTA / 批量 / 诊断），保存时原样回写。
const rest = ref<Omit<FleetLifecycleConfig, 'groups'>>({
  ota: DEFAULT_FLEET.ota,
  batchOps: DEFAULT_FLEET.batchOps,
  networkDiag: DEFAULT_FLEET.networkDiag
})
const fleets = ref<FleetGroup[]>([])

function markDirty() {
  dirty.value = true
}

const carIndex = computed(() => {
  const m = new Map<string, string>()
  for (const c of props.cars) m.set(c.id, c.name ?? c.id)
  return m
})

function optionsForFleet(fleet: FleetGroup) {
  const assignedElsewhere = new Set<string>()
  for (const f of fleets.value) {
    if (f === fleet) continue
    for (const id of f.carIds) assignedElsewhere.add(id)
  }
  return props.cars.map((c) => ({
    id: c.id,
    label: c.name && c.name !== c.id ? `${c.id} · ${c.name}` : c.id,
    takenByOther: assignedElsewhere.has(c.id)
  }))
}

const unknownCarIds = computed(() => {
  const known = carIndex.value
  const out: string[] = []
  for (const f of fleets.value) {
    for (const id of f.carIds) {
      if (!known.has(id) && !out.includes(id)) out.push(id)
    }
  }
  return out
})

function newFleetId(): string {
  const used = new Set(fleets.value.map((f) => f.id))
  let i = fleets.value.length + 1
  let id = `G-${i}`
  while (used.has(id)) {
    i += 1
    id = `G-${i}`
  }
  return id
}

function addFleet() {
  fleets.value.push({ id: newFleetId(), name: '新车队', floor: '', region: '', carIds: [] })
  markDirty()
}

function removeFleet(idx: number) {
  fleets.value.splice(idx, 1)
  markDirty()
}

async function reload(force = false) {
  loading.value = true
  try {
    const env = await store.load<FleetLifecycleConfig>('fleet', force)
    const payload = env.payload ?? DEFAULT_FLEET
    rest.value = {
      ota: payload.ota ?? DEFAULT_FLEET.ota,
      batchOps: payload.batchOps ?? DEFAULT_FLEET.batchOps,
      networkDiag: payload.networkDiag ?? DEFAULT_FLEET.networkDiag
    }
    fleets.value = JSON.parse(JSON.stringify(payload.groups ?? [])) as FleetGroup[]
    dirty.value = false
    if (force) ElMessage.success('已重载车队配置')
  } catch (e) {
    ElMessage.error(`加载车队配置失败：${e instanceof Error ? e.message : String(e)}`)
  } finally {
    loading.value = false
  }
}

async function save() {
  saving.value = true
  try {
    const body: FleetLifecycleConfig = {
      ...rest.value,
      groups: JSON.parse(JSON.stringify(fleets.value)) as FleetGroup[]
    }
    const env = await store.save<FleetLifecycleConfig>('fleet', body)
    dirty.value = false
    await reloadShared(true)
    emit('saved')
    ElMessage.success(`车队分配已保存 v${env.version}`)
  } catch (e) {
    ElMessage.error(`保存失败：${e instanceof Error ? e.message : String(e)}`)
  } finally {
    saving.value = false
  }
}

onMounted(() => reload())
</script>

<style scoped>
.fleet-alloc {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 12px;
  background: var(--mg-veil-2, rgba(255, 255, 255, 0.03));
}

.fa-header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.fa-title {
  font-weight: 600;
  font-size: 14px;
  color: var(--mg-text-light, #fff);
}

.fa-sub {
  font-size: 12px;
  color: var(--el-text-color-secondary);
}

.fa-header .spacer {
  flex: 1;
}

.fa-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 280px;
  overflow: auto;
}

.fleet-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 6px;
  padding: 10px;
}

.fc-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.fc-name { width: 220px; }
.fc-region { width: 160px; }
.fc-floor { width: 150px; }
.fc-cars { width: 100%; }

.fa-note {
  margin: 0;
  font-size: 11px;
  color: var(--el-color-warning);
}
</style>
