<template>
  <div class="wizard-page">
    <div class="wz-orb wz-orb-a" aria-hidden="true" />
    <div class="wz-orb wz-orb-b" aria-hidden="true" />

    <div class="wz-card">
      <header class="wz-head">
        <div class="wz-brand">
          <div class="wz-mark">
            <img src="/FRLD-logo-white-no_title.png" alt="迷毂" class="wz-mark-img" />
          </div>
          <div class="wz-titles">
            <div class="wz-title">平台配置向导</div>
            <div class="wz-sub">{{ current.hint }}</div>
          </div>
        </div>
        <div class="wz-user">{{ auth.user?.displayName ?? auth.user?.username ?? '' }}</div>
      </header>

      <ol class="wz-steps" aria-label="向导步骤">
        <li
          v-for="s in steps"
          :key="s.id"
          class="wz-step"
          :class="{
            'is-current': s.id === draft.step,
            'is-done': stepIndex(s.id) < stepIndex(draft.step)
          }"
        >
          <span class="wz-step-n">{{ s.index }}</span>
          <span class="wz-step-t">{{ s.title }}</span>
        </li>
      </ol>

      <div v-if="loading" class="wz-loading">正在加载配置选项…</div>

      <div v-else class="wz-body">
        <!-- 1 导航 -->
        <section v-show="draft.step === 'nav'" class="wz-section">
          <div class="wz-section-head">
            <el-icon><Compass /></el-icon><h3>选择导航方式</h3><span class="req">至少选 1 项</span>
          </div>
          <p class="wz-lead">按现场实际定位方式勾选，系统会据此加载对应内核场景插件。</p>
          <div class="chip-grid">
            <button
              v-for="o in options?.navigationKinds ?? []" :key="o.id" type="button"
              class="chip" :class="{ on: draft.navigationKinds.includes(o.id) }"
              @click="toggle(draft.navigationKinds, o.id)">
              <div class="chip-name">{{ o.name }}</div>
              <div class="chip-desc">{{ o.description }}</div>
            </button>
          </div>
        </section>

        <!-- 2 场景 -->
        <section v-show="draft.step === 'scenario'" class="wz-section">
          <div class="wz-section-head">
            <el-icon><Histogram /></el-icon><h3>选择业务场景</h3><span class="opt">可多选，也可暂不选</span>
          </div>
          <p class="wz-lead">场景决定后面「业务配置」要做什么。例如 SPS 会引导你去设备管理添加上下线机构并配置互锁。</p>
          <div class="chip-grid">
            <button
              v-for="t in scenarioTemplates" :key="t.id" type="button"
              class="chip" :class="{ on: draft.scenarios.includes(t.id) }"
              @click="toggle(draft.scenarios, t.id)">
              <div class="chip-name">{{ t.name }}</div>
              <div class="chip-desc">{{ t.category }}</div>
            </button>
          </div>
        </section>

        <!-- 3 模块 -->
        <section v-show="draft.step === 'modules'" class="wz-section">
          <div class="wz-section-head">
            <el-icon><Box /></el-icon><h3>选择功能模块</h3>
          </div>
          <p class="wz-lead">按项目需要裁剪平台菜单。未选中的模块对应配置页会隐藏。</p>
          <div class="chip-grid">
            <button
              v-for="o in options?.modules ?? []" :key="o.id" type="button"
              class="chip" :class="{ on: draft.modules.includes(o.id) }"
              @click="toggle(draft.modules, o.id)">
              <div class="chip-name">{{ o.name }}</div>
              <div class="chip-desc">{{ o.description }}</div>
            </button>
          </div>
        </section>

        <!-- 4 车辆 -->
        <section v-show="draft.step === 'vehicles'" class="wz-section">
          <div class="wz-section-head">
            <el-icon><Van /></el-icon><h3>车辆配置</h3>
          </div>
          <p class="wz-lead warn">必须添加车辆并补齐参数，否则地图监控与任务无法绑定实车。</p>
          <ol class="check-list">
            <li
              v-for="(it, i) in vehicleItems"
              :key="it.key"
              :class="{ done: isChecked(it.key) }"
            >
              <button type="button" class="check-mark" :aria-pressed="isChecked(it.key)" @click="toggleChecked(it.key)">
                {{ isChecked(it.key) ? '✓' : i + 1 }}
              </button>
              <div class="check-body">
                <div class="check-title">{{ it.title }}</div>
                <div class="check-detail">{{ it.detail }}</div>
              </div>
              <button v-if="it.route" type="button" class="check-cta" @click="openItem(it)">{{ it.cta || '去配置' }}</button>
            </li>
          </ol>
          <div class="cta-row">
            <el-button type="primary" @click="openSetup('admin-cars')">前往车辆管理</el-button>
            <span class="cta-note">必须添加车辆并补齐参数。配完后点顶栏「返回向导」，或勾选清单后点「下一步」。</span>
          </div>
        </section>

        <!-- 5 地图 -->
        <section v-show="draft.step === 'map'" class="wz-section">
          <div class="wz-section-head">
            <el-icon><MapLocation /></el-icon><h3>地图配置</h3>
          </div>
          <p class="wz-lead">在画布上布置站点、绘制路径，并按导航方式填写站点功能参数。</p>
          <ol class="check-list">
            <li
              v-for="(it, i) in mapItems"
              :key="it.key"
              :class="{ done: isChecked(it.key) }"
            >
              <button type="button" class="check-mark" :aria-pressed="isChecked(it.key)" @click="toggleChecked(it.key)">
                {{ isChecked(it.key) ? '✓' : i + 1 }}
              </button>
              <div class="check-body">
                <div class="check-title">{{ it.title }}</div>
                <div class="check-detail">{{ it.detail }}</div>
              </div>
              <button v-if="it.route" type="button" class="check-cta" @click="openItem(it)">{{ it.cta || '去配置' }}</button>
            </li>
          </ol>
          <div class="cta-row">
            <el-button type="primary" @click="openSetup('admin-map-editor')">前往地图编辑</el-button>
            <el-button @click="openSetup('admin-tracks')">场景 / 路径表</el-button>
          </div>
        </section>

        <!-- 6 业务 -->
        <section v-show="draft.step === 'business'" class="wz-section">
          <div class="wz-section-head">
            <el-icon><SetUp /></el-icon><h3>配置业务场景</h3>
          </div>
          <p class="wz-lead">{{ businessHint }}</p>
          <ol class="check-list">
            <li
              v-for="(it, i) in businessItems"
              :key="it.key"
              :class="{ done: isChecked(it.key) }"
            >
              <button type="button" class="check-mark" :aria-pressed="isChecked(it.key)" @click="toggleChecked(it.key)">
                {{ isChecked(it.key) ? '✓' : i + 1 }}
              </button>
              <div class="check-body">
                <div class="check-title">{{ it.title }}</div>
                <div class="check-detail">{{ it.detail }}</div>
              </div>
              <button v-if="it.route" type="button" class="check-cta" @click="openItem(it)">{{ it.cta || '去配置' }}</button>
            </li>
          </ol>
          <div class="cta-row">
            <el-button type="primary" @click="openSetup('admin-config-facility', { tab: 'devices' })">前往设备管理</el-button>
          </div>
        </section>

        <aside class="wz-summary">
          <div class="sum-title">已选概览</div>
          <div class="sum-row"><span>导航方式</span><b>{{ navLabels }}</b></div>
          <div class="sum-row"><span>业务场景</span><b>{{ scenarioLabels }}</b></div>
          <div class="sum-row"><span>功能模块</span><b>{{ moduleLabels }}</b></div>
          <div class="sum-divider" />
          <div class="sum-label">将激活的内核场景插件</div>
          <div class="sum-scenes">
            <el-tag v-for="s in scenes" :key="s" size="small" effect="dark" class="sum-tag">{{ s }}</el-tag>
            <span v-if="!scenes.length" class="sum-empty">（请先选择导航方式）</span>
          </div>
        </aside>
      </div>

      <footer class="wz-foot">
        <el-button text class="logout-btn" @click="onLogout">退出登录</el-button>
        <div class="foot-right">
          <el-button v-if="prevId" @click="goPrev">上一步</el-button>
          <el-button
            v-if="nextId"
            type="primary"
            :disabled="!canAdvance"
            @click="goNext"
          >{{ nextCta }}</el-button>
          <el-button
            v-else
            type="primary"
            :loading="saving"
            :disabled="!canAdvance"
            @click="finish"
          >
            <el-icon v-if="!saving" class="btn-ic"><Check /></el-icon>完成并进入平台
          </el-button>
        </div>
      </footer>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Compass, Box, Histogram, Check, Van, MapLocation, SetUp } from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/auth'
import { getWizardOptions, getWizardProfile, saveWizardProfile } from '@/api/wizard'
import type { WizardOptions, ScenarioTemplateLite } from '@/types/wizard'
import {
  WIZARD_STEPS,
  activeSceneIds,
  businessChecklist,
  clearWizardDraft,
  loadWizardDraft,
  mapChecklist,
  nextStep,
  prevStep,
  saveWizardDraft,
  scenarioSetupHint,
  stepDef,
  stepIndex,
  vehicleChecklist,
  type WizardChecklistItem,
  type WizardDraft,
  type WizardStepId
} from '@/utils/wizardSetup'

const router = useRouter()
const auth = useAuthStore()

const loading = ref(true)
const saving = ref(false)
const options = ref<WizardOptions | null>(null)
const steps = WIZARD_STEPS

const draft = reactive<WizardDraft>(loadWizardDraft())

const current = computed(() => stepDef(draft.step))
const nextId = computed(() => nextStep(draft.step))
const prevId = computed(() => prevStep(draft.step))
const scenes = computed(() => activeSceneIds(draft.navigationKinds, draft.scenarios))
const scenarioTemplates = computed<ScenarioTemplateLite[]>(() => options.value?.scenarios?.templates ?? [])
const vehicleItems = computed(() => vehicleChecklist())
const mapItems = computed(() => mapChecklist())
const businessItems = computed(() => businessChecklist(draft.scenarios))
const businessHint = computed(() => scenarioSetupHint(draft.scenarios))

const canAdvance = computed(() => {
  if (draft.step === 'nav') return draft.navigationKinds.length > 0
  return true
})

const nextCta = computed(() => {
  if (draft.step === 'modules') return '进入配置'
  return '下一步'
})

function namesOf(ids: string[], pool: { id: string; name: string }[]): string {
  if (!ids.length) return '未选'
  return ids.map((id) => pool.find((o) => o.id === id)?.name ?? id).join('、')
}

const navLabels = computed(() => namesOf(draft.navigationKinds, options.value?.navigationKinds ?? []))
const moduleLabels = computed(() => namesOf(draft.modules, options.value?.modules ?? []))
const scenarioLabels = computed(() => namesOf(draft.scenarios, scenarioTemplates.value))

function persist() {
  saveWizardDraft({ ...draft })
}

watch(draft, persist, { deep: true })

function toggle(list: string[], id: string) {
  const i = list.indexOf(id)
  if (i >= 0) list.splice(i, 1)
  else list.push(id)
}

function isChecked(key: string) {
  return draft.checked.includes(key)
}

function toggleChecked(key: string) {
  toggle(draft.checked, key)
}

function goPrev() {
  const p = prevId.value
  if (p) draft.step = p
  if (stepDef(draft.step).kind === 'select') draft.inSetup = false
}

function goNext() {
  if (!canAdvance.value) {
    ElMessage.warning('请至少选择一种导航方式')
    return
  }
  const n = nextId.value
  if (!n) return
  if (n === 'vehicles') draft.inSetup = true
  draft.step = n
}

async function openSetup(name: string, query?: Record<string, string>) {
  draft.inSetup = true
  persist()
  await router.push({ name, query })
}

async function openItem(it: WizardChecklistItem) {
  if (!it.route) return
  await openSetup(it.route, it.query)
}

async function finish() {
  if (draft.navigationKinds.length === 0) {
    ElMessage.warning('请至少选择一种导航方式')
    draft.step = 'nav'
    return
  }
  saving.value = true
  try {
    await saveWizardProfile({
      platformType: draft.platformType,
      modules: draft.modules,
      navigationKinds: draft.navigationKinds,
      scenarios: draft.scenarios
    })
    clearWizardDraft()
    auth.markWizardDone()
    ElMessage.success('部署配置已保存')
    router.push(auth.scope === 'RCSMonitor' ? '/monitor/map' : '/admin/dashboard')
  } catch (e) {
    ElMessage.error(`保存失败：${(e as Error).message}`)
  } finally {
    saving.value = false
  }
}

function onLogout() {
  clearWizardDraft()
  auth.logout()
  router.push('/login')
}

onMounted(async () => {
  try {
    const [opt, profile] = await Promise.all([getWizardOptions(), getWizardProfile()])
    options.value = opt
    if (!draft.navigationKinds.length && profile.navigationKinds?.length) {
      draft.navigationKinds = [...profile.navigationKinds]
    }
    if (!draft.modules.length) {
      draft.modules = profile.modules?.length ? [...profile.modules] : ['wms']
    }
    if (!draft.scenarios.length && profile.scenarios?.length) {
      draft.scenarios = [...profile.scenarios]
    }
    draft.platformType = draft.platformType || profile.platformType || 'standard'
  } catch (e) {
    ElMessage.error(`加载向导失败：${(e as Error).message}`)
  } finally {
    loading.value = false
  }
})
</script>

<style scoped>
.wizard-page {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 24px;
  background:
    radial-gradient(ellipse 75% 55% at 16% 14%, #dcbef7 0%, transparent 55%),
    radial-gradient(ellipse 80% 65% at 86% 90%, #abc9f5 0%, transparent 58%),
    linear-gradient(135deg, #cbb2f0 0%, #b7adec 46%, #a7c6f2 100%);
}
.wz-orb {
  position: absolute; border-radius: 50%; filter: blur(110px); pointer-events: none; opacity: 0.28;
}
.wz-orb-a {
  width: 480px; height: 480px; top: -180px; left: -140px;
  background: radial-gradient(circle, var(--lg-accent) 0%, var(--lg-primary) 55%, transparent 85%);
}
.wz-orb-b {
  width: 560px; height: 560px; bottom: -220px; right: -180px;
  background: radial-gradient(circle, var(--lg-primary-hover) 0%, var(--lg-primary-deep) 55%, transparent 88%);
}

.wz-card {
  position: relative;
  z-index: 2;
  width: 1080px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background:
    linear-gradient(135deg, rgba(var(--lg-card-rgb), 0.92) 0%, rgba(20, 12, 38, 0.95) 100%);
  backdrop-filter: blur(26px) saturate(150%);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  box-shadow:
    0 40px 100px rgba(0, 0, 0, 0.6),
    0 0 80px rgba(var(--lg-primary-rgb), 0.4),
    0 0 0 1px rgba(var(--lg-accent-rgb), 0.28) inset;
}

.wz-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 28px 12px;
}
.wz-brand { display: flex; align-items: center; gap: 14px; }
.wz-mark {
  height: 46px; min-width: 46px;
  padding: 0 12px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(var(--lg-primary-rgb), 0.55) 0%, rgba(var(--lg-accent-rgb), 0.30) 100%);
  border: 1px solid rgba(255, 255, 255, 0.20);
  display: inline-flex; align-items: center; justify-content: center;
}
.wz-mark-img { display: block; height: 28px; width: auto; }
.wz-titles { display: flex; flex-direction: column; gap: 4px; }
.wz-title { font-size: 20px; font-weight: 700; letter-spacing: 2px; color: #fff; }
.wz-sub { font-size: 12.5px; color: rgba(232, 215, 245, 0.65); }
.wz-user {
  font-size: 13px; color: rgba(255, 255, 255, 0.8);
  padding: 5px 12px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.14);
}

.wz-steps {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0 22px 12px;
}
.wz-step {
  display: flex; align-items: center; gap: 6px;
  min-width: 0;
  padding: 7px 8px;
  border-radius: 10px;
  color: rgba(255, 255, 255, 0.42);
  font-size: 12px;
}
.wz-step.is-done { color: rgba(232, 215, 245, 0.78); }
.wz-step.is-current {
  color: #fff;
  background: rgba(var(--lg-primary-rgb), 0.28);
}
.wz-step-n {
  flex: none;
  width: 20px; height: 20px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700;
  border: 1px solid currentColor;
}
.wz-step-t {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650;
}

.wz-loading { padding: 80px; text-align: center; color: rgba(255, 255, 255, 0.7); }

.wz-body {
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns: 1fr 260px;
  overflow: hidden;
}
.wz-section {
  overflow-y: auto;
  padding: 8px 26px 22px;
}
.wz-section-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px; color: #fff;
}
.wz-section-head .el-icon { font-size: 18px; color: var(--lg-accent); }
.wz-section-head h3 { margin: 0; font-size: 15px; font-weight: 600; }
.wz-section-head .req,
.wz-section-head .opt {
  font-size: 11px; padding: 1px 8px; border-radius: 8px;
}
.wz-section-head .req {
  color: var(--lg-accent);
  border: 1px solid rgba(var(--lg-accent-rgb), 0.4);
}
.wz-section-head .opt {
  color: rgba(232, 215, 245, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.wz-lead {
  margin: 0 0 14px;
  font-size: 13px;
  line-height: 1.55;
  color: rgba(232, 215, 245, 0.72);
}
.wz-lead.warn { color: #f3c77a; }

.chip-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px;
}
.chip {
  appearance: none; cursor: pointer; text-align: left;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 12px;
  padding: 12px 14px;
  color: rgba(255, 255, 255, 0.78);
  transition: all .18s ease;
}
.chip:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.chip.on {
  background: linear-gradient(135deg, rgba(var(--lg-primary-rgb), 0.6) 0%, rgba(var(--lg-primary-hover-rgb), 0.4) 100%);
  border-color: rgba(var(--lg-accent-rgb), 0.85);
  color: #fff;
}
.chip-name { font-size: 14px; font-weight: 600; }
.chip-desc { font-size: 11.5px; opacity: 0.75; margin-top: 4px; line-height: 1.5; }

.check-list {
  list-style: none; margin: 0 0 16px; padding: 0;
  display: flex; flex-direction: column; gap: 10px;
}
.check-list li {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.check-list li.done {
  border-color: rgba(34, 197, 94, 0.45);
  background: rgba(34, 197, 94, 0.08);
}
.check-mark {
  appearance: none;
  flex: none;
  width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #fff;
  background: rgba(var(--lg-primary-rgb), 0.7);
  border: 0;
  cursor: pointer;
}
.check-list li.done .check-mark { background: #16a34a; }
.check-body { flex: 1; min-width: 0; }
.check-title { font-size: 13.5px; font-weight: 650; color: #fff; }
.check-detail { font-size: 12px; color: rgba(232, 215, 245, 0.68); margin-top: 3px; line-height: 1.5; }
.check-cta {
  appearance: none;
  flex: none;
  height: 28px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid rgba(var(--lg-accent-rgb), 0.45);
  background: rgba(var(--lg-primary-rgb), 0.28);
  color: #fff;
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
}
.check-cta:hover { background: rgba(var(--lg-primary-rgb), 0.45); }
.cta-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.cta-note { font-size: 12px; color: rgba(232, 215, 245, 0.55); }

.wz-summary {
  border-left: 1px solid rgba(var(--lg-accent-rgb), 0.16);
  background: rgba(0, 0, 0, 0.18);
  padding: 18px 18px;
  overflow-y: auto;
}
.sum-title { font-size: 13px; font-weight: 600; color: #fff; margin-bottom: 14px; }
.sum-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 10px;
  font-size: 13px; color: rgba(255, 255, 255, 0.75); padding: 7px 0;
}
.sum-row b {
  color: var(--lg-accent); font-size: 12.5px; font-weight: 650; text-align: right; max-width: 58%;
}
.sum-divider { height: 1px; background: rgba(255, 255, 255, 0.12); margin: 14px 0; }
.sum-label { font-size: 12px; color: rgba(232, 215, 245, 0.65); margin-bottom: 10px; }
.sum-scenes { display: flex; flex-wrap: wrap; gap: 6px; }
.sum-tag {
  font-family: var(--mg-font-mono);
  background: rgba(var(--lg-primary-rgb), 0.30) !important;
  border-color: rgba(var(--lg-accent-rgb), 0.5) !important;
  color: #fff !important;
}
.sum-empty { font-size: 12px; color: rgba(255, 255, 255, 0.4); }

.wz-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 26px;
  border-top: 1px solid rgba(var(--lg-accent-rgb), 0.18);
  background: rgba(var(--lg-aside-rgb), 0.4);
}
.logout-btn { color: rgba(255, 255, 255, 0.6) !important; }
.foot-right { display: flex; align-items: center; gap: 10px; }
.btn-ic { margin-right: 4px; }
.wz-foot :deep(.el-button--primary) {
  --el-button-bg-color: var(--lg-primary);
  --el-button-border-color: var(--lg-primary);
  --el-button-hover-bg-color: var(--lg-primary-hover);
  --el-button-hover-border-color: var(--lg-primary-hover);
  color: #fff;
}

@media (max-width: 880px) {
  .wz-body { grid-template-columns: 1fr; }
  .wz-summary { border-left: none; border-top: 1px solid rgba(var(--lg-accent-rgb), 0.16); }
  .wz-steps { grid-template-columns: repeat(3, 1fr); }
}
</style>
