<template>
  <section class="fleet-alloc" :class="{ 'is-collapsed': collapsed }">
    <div class="fa-header">
      <button type="button" class="fa-fold" :aria-expanded="!collapsed" @click="toggleCollapsed">
        <el-icon class="fold-chevron" :class="{ 'is-collapsed': collapsed }"><ArrowDown /></el-icon>
        <span class="fa-title">车队分配</span>
      </button>
      <el-tag v-if="collapsed" size="small" type="info" effect="plain">{{ fleets.length }} 个车队</el-tag>
      <el-tag v-else size="small" type="info" effect="plain">区域管理</el-tag>
      <span v-if="!collapsed" class="fa-sub">将车辆分配到车队，并设定车队名称 / 区域 / 楼层</span>
      <div class="spacer" />
      <template v-if="!collapsed">
        <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>
      </template>
      <el-button v-else size="small" text type="primary" @click="toggleCollapsed">展开</el-button>
    </div>

    <div v-show="!collapsed" 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="!collapsed && 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, ArrowDown } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { reflectionApi } from '@/api/reflection'
import { useConfigStore } from '@/stores/config'
import { useFleetGroups } from '@/composables/useFleetGroups'
import { DEFAULT_FLEET } from '@/mock/data/configs'
import type { VehicleCardModel } from '@/types/car'
import type { FleetGroup, FleetLifecycleConfig } from '@/types/config'

type FleetAllocCar = Pick<VehicleCardModel, 'id' | 'name' | 'rawId'>

const props = defineProps<{
  cars: FleetAllocCar[]
  canWrite: boolean
}>()

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

const store = useConfigStore()
const { reload: reloadShared } = useFleetGroups()
const COLLAPSE_KEY = 'vehicle-hub.fleet-alloc-collapsed'

const loading = ref(false)
const saving = ref(false)
const dirty = ref(false)
const collapsed = ref(readCollapsed())

function readCollapsed(): boolean {
  try {
    const v = localStorage.getItem(COLLAPSE_KEY)
    if (v === null) return true
    return v === '1'
  } catch {
    return true
  }
}

function toggleCollapsed() {
  collapsed.value = !collapsed.value
  try {
    localStorage.setItem(COLLAPSE_KEY, collapsed.value ? '1' : '0')
  } catch {
    /* ignore */
  }
}

// 保留 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, FleetAllocCar>()
  for (const c of props.cars) m.set(c.id, c)
  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 resolveCarReflectionId(car: FleetAllocCar): number | null {
  if (car.rawId != null && Number.isFinite(car.rawId)) return car.rawId
  const parsed = Number.parseInt(car.id.replace(/\D/g, ''), 10)
  return Number.isFinite(parsed) ? parsed : null
}

async function syncCarGroupFields(): Promise<number> {
  const assignments = new Map<string, { reflectionId: number; fleetName: string }>()
  const cars = carIndex.value

  for (const fleet of fleets.value) {
    const fleetName = fleet.name.trim() || fleet.id
    for (const carId of fleet.carIds) {
      const car = cars.get(carId)
      if (!car) continue
      const reflectionId = resolveCarReflectionId(car)
      if (reflectionId == null) continue
      assignments.set(carId, { reflectionId, fleetName })
    }
  }

  const tasks = [...assignments.values()].map(({ reflectionId, fleetName }) =>
    reflectionApi.setField('car', reflectionId, 'carGroup', fleetName)
  )
  const results = await Promise.allSettled(tasks)
  const failed = results.filter((r) => r.status === 'rejected')
  if (failed.length) {
    throw new Error(`${failed.length}/${tasks.length} 辆车同步失败`)
  }
  return tasks.length
}

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[]
    }
    await store.save<FleetLifecycleConfig>('fleet', body)
    let syncedCars = 0
    try {
      syncedCars = await syncCarGroupFields()
    } catch (e) {
      ElMessage.warning(`车队配置已保存，但同步 carGroup 字段失败：${e instanceof Error ? e.message : String(e)}`)
    }
    dirty.value = false
    await reloadShared(true)
    emit('saved')
    ElMessage.success(syncedCars ? `车队分配已保存，已同步 ${syncedCars} 辆车 carGroup` : '车队分配已保存')
  } 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));
  transition: padding 0.2s ease;
}

.fleet-alloc.is-collapsed {
  padding: 8px 12px;
}

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

.fa-fold {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  appearance: none;
  border: none;
  background: transparent;
  padding: 0;
  cursor: pointer;
  color: inherit;
}

.fa-fold:hover .fa-title {
  color: var(--mg-accent, #c4b5fd);
}

.fold-chevron {
  font-size: 14px;
  color: var(--mg-text-muted, rgba(255, 255, 255, 0.55));
  transition: transform 0.2s ease;
}

.fold-chevron.is-collapsed {
  transform: rotate(-90deg);
}

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

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