/** 首次部署向导：步骤、草稿、配置页放行。 */

export const WIZARD_DRAFT_KEY = 'migu.wizard.draft'
export const WIZARD_SETUP_KEY = 'migu.wizard.inSetup'

export type WizardStepId =
  | 'nav'
  | 'scenario'
  | 'modules'
  | 'vehicles'
  | 'map'
  | 'business'

export interface WizardDraft {
  platformType: string
  navigationKinds: string[]
  modules: string[]
  scenarios: string[]
  step: WizardStepId
  inSetup: boolean
  /** 配置清单勾选（key 见 WizardChecklistItem.key） */
  checked: string[]
}

export interface WizardChecklistItem {
  key: string
  title: string
  detail: string
  route?: string
  query?: Record<string, string>
  cta?: string
}

export interface WizardStepDef {
  id: WizardStepId
  index: number
  title: string
  hint: string
  /** 选型步 / 配置引导步 */
  kind: 'select' | 'setup'
}

export const WIZARD_STEPS: WizardStepDef[] = [
  { id: 'nav', index: 1, title: '导航方式', hint: '选择现场实际使用的定位方式', kind: 'select' },
  { id: 'scenario', index: 2, title: '业务场景', hint: '决定后续设备与互锁怎么配', kind: 'select' },
  { id: 'modules', index: 3, title: '功能模块', hint: '按需裁剪仓储 / 拣选等能力', kind: 'select' },
  { id: 'vehicles', index: 4, title: '车辆配置', hint: '添加车辆并填写运行参数', kind: 'setup' },
  { id: 'map', index: 5, title: '地图配置', hint: '站点、路径与功能参数', kind: 'setup' },
  { id: 'business', index: 6, title: '业务配置', hint: '按场景接入设备与互锁', kind: 'setup' }
]

/** 向导进行中允许进入的业务页（需同时 inSetup=true）。 */
export const WIZARD_SETUP_ROUTES = new Set([
  'admin-cars',
  'admin-map-editor',
  'admin-maps',
  'admin-tracks',
  'admin-config-facility',
  'admin-task-templates',
  'admin-project-properties'
])

export const NAV_SCENE: Record<string, string> = {
  magnetic: 'scene.mag',
  qrcode: 'scene.qrlidar',
  laser: 'scene.qrlidar'
}

const VEHICLE_CHECKLIST: WizardChecklistItem[] = [
  {
    key: 'veh-add',
    title: '添加车辆',
    detail: '打开车辆管理 → 右上角「新建车辆」，从已加载车型实例化至少一台车。没有车则地图监控与任务无法绑定实车。',
    route: 'admin-cars',
    cta: '去添加车辆'
  },
  {
    key: 'veh-params',
    title: '填写车辆参数',
    detail: '编号、名称、车型、IP / 通讯地址必须填写；电池、速度、尺寸等运行参数按车型补齐后保存。',
    route: 'admin-cars',
    cta: '去填参数'
  },
  {
    key: 'veh-list',
    title: '确认列表可见',
    detail: '保存后车辆列表中能看到该车，状态不是空列表。后续站点占用、任务下发都依赖这台车。',
    route: 'admin-cars',
    cta: '查看车辆列表'
  }
]

const MAP_CHECKLIST: WizardChecklistItem[] = [
  {
    key: 'map-sites',
    title: '配置站点',
    detail: '在地图编辑器布置工位、充电、待命、互锁等站点，并核对接驳点 / 站点属性。',
    route: 'admin-map-editor',
    cta: '去布站点'
  },
  {
    key: 'map-paths',
    title: '绘制路径',
    detail: '用直线 / 曲线把站点连起来，保证车辆从待命到工位、充电点均可到达。',
    route: 'admin-map-editor',
    cta: '去画路径'
  },
  {
    key: 'map-params',
    title: '功能参数',
    detail: '按导航方式补站点功能参数：锁点、限速、交管、允许停车等。可在场景/路径表里核对。',
    route: 'admin-tracks',
    cta: '去核路径表'
  }
]

const SCENARIO_CHECKLIST: Record<string, WizardChecklistItem[]> = {
  'tpl-sps': [
    {
      key: 'sps-device',
      title: '添加上下线机构',
      detail: '进入设备管理 → 设备实例，添加上线机构、下线机构（或对应 SPS 台架设备）。',
      route: 'admin-config-facility',
      query: { tab: 'devices' },
      cta: '去添加机构'
    },
    {
      key: 'sps-interlock-site',
      title: '配置互锁站点',
      detail: '把机构对应的互锁站点绑到地图上的上线/下线工位，避免车未到位就放行机构。',
      route: 'admin-map-editor',
      cta: '去绑互锁站点'
    },
    {
      key: 'sps-comm',
      title: '设备通讯参数',
      detail: '填写协议（如 Modbus / PLC）、IP、端口，确认设备实例已启用、能通讯。',
      route: 'admin-config-facility',
      query: { tab: 'devices' },
      cta: '去配通讯'
    },
    {
      key: 'sps-addr',
      title: '互锁点地址',
      detail: '配置互锁点（锁点）地址参数，与现场 PLC / 机构到位、放行信号对齐。',
      route: 'admin-config-facility',
      query: { tab: 'devices' },
      cta: '去配互锁地址'
    }
  ],
  'tpl-pack': [
    {
      key: 'pack-device',
      title: '工位对接设备',
      detail: '在设备管理中添加产线工位对接设备。',
      route: 'admin-config-facility',
      query: { tab: 'devices' },
      cta: '去添加设备'
    },
    {
      key: 'pack-interlock',
      title: '互锁站点',
      detail: '绑定工位互锁站点，避免车与设备抢位。',
      route: 'admin-map-editor',
      cta: '去绑站点'
    },
    {
      key: 'pack-comm',
      title: '通讯与地址',
      detail: '配置设备通讯参数及互锁点地址。',
      route: 'admin-config-facility',
      query: { tab: 'devices' },
      cta: '去配参数'
    }
  ],
  'tpl-loop': [
    {
      key: 'loop-sites',
      title: '环线站点',
      detail: '确认环线进出站、循环路径已在地图中闭合，避免堵车。',
      route: 'admin-map-editor',
      cta: '去核地图'
    }
  ],
  'tpl-p2p': [
    {
      key: 'p2p-sites',
      title: '取放货站点',
      detail: '明确取货点与放货点，并在地图中标好。',
      route: 'admin-map-editor',
      cta: '去标站点'
    },
    {
      key: 'p2p-tpl',
      title: '任务模板',
      detail: '可在任务编排中配置点对点搬运模板。',
      route: 'admin-task-templates',
      cta: '去配任务模板'
    }
  ]
}

const GENERIC_BUSINESS: WizardChecklistItem[] = [
  {
    key: 'biz-device',
    title: '设备接入',
    detail: '如现场有门、充电桩、机构等，在设备管理中添加并配置通讯。',
    route: 'admin-config-facility',
    query: { tab: 'devices' },
    cta: '去设备管理'
  }
]

export function emptyDraft(): WizardDraft {
  return {
    platformType: 'standard',
    navigationKinds: [],
    modules: ['wms'],
    scenarios: [],
    step: 'nav',
    inSetup: false,
    checked: []
  }
}

export function loadWizardDraft(): WizardDraft {
  try {
    const raw = sessionStorage.getItem(WIZARD_DRAFT_KEY)
    if (!raw) return emptyDraft()
    const parsed = JSON.parse(raw) as Partial<WizardDraft>
    const base = emptyDraft()
    return {
      ...base,
      ...parsed,
      navigationKinds: Array.isArray(parsed.navigationKinds) ? parsed.navigationKinds : [],
      modules: Array.isArray(parsed.modules) ? parsed.modules : base.modules,
      scenarios: Array.isArray(parsed.scenarios) ? parsed.scenarios : [],
      step: WIZARD_STEPS.some((s) => s.id === parsed.step) ? (parsed.step as WizardStepId) : 'nav',
      inSetup: !!parsed.inSetup,
      checked: Array.isArray(parsed.checked) ? parsed.checked : []
    }
  } catch {
    return emptyDraft()
  }
}

export function saveWizardDraft(draft: WizardDraft) {
  try {
    sessionStorage.setItem(WIZARD_DRAFT_KEY, JSON.stringify(draft))
    if (draft.inSetup) sessionStorage.setItem(WIZARD_SETUP_KEY, '1')
    else sessionStorage.removeItem(WIZARD_SETUP_KEY)
  } catch { /* ignore */ }
}

export function clearWizardDraft() {
  try {
    sessionStorage.removeItem(WIZARD_DRAFT_KEY)
    sessionStorage.removeItem(WIZARD_SETUP_KEY)
  } catch { /* ignore */ }
}

export function isWizardSetupActive(): boolean {
  try {
    return sessionStorage.getItem(WIZARD_SETUP_KEY) === '1'
  } catch {
    return false
  }
}

export function stepDef(id: WizardStepId): WizardStepDef {
  return WIZARD_STEPS.find((s) => s.id === id) ?? WIZARD_STEPS[0]!
}

export function stepIndex(id: WizardStepId): number {
  return WIZARD_STEPS.findIndex((s) => s.id === id)
}

export function nextStep(id: WizardStepId): WizardStepId | null {
  const i = stepIndex(id)
  return i >= 0 && i < WIZARD_STEPS.length - 1 ? WIZARD_STEPS[i + 1]!.id : null
}

export function prevStep(id: WizardStepId): WizardStepId | null {
  const i = stepIndex(id)
  return i > 0 ? WIZARD_STEPS[i - 1]!.id : null
}

const SIGNAL_SCENARIOS = ['tpl-sps', 'tpl-pack']

export function activeSceneIds(navKinds: string[], scenarios: string[] = []): string[] {
  const out: string[] = []
  for (const k of navKinds) {
    const id = NAV_SCENE[k] ?? `scene.${k}`
    if (!out.includes(id)) out.push(id)
  }
  if (scenarios.some((s) => SIGNAL_SCENARIOS.includes(s)) && !out.includes('scene.signal')) {
    out.push('scene.signal')
  }
  if (out.length > 0 && !out.includes('scene.device')) out.push('scene.device')
  return out
}

export function vehicleChecklist(): WizardChecklistItem[] {
  return VEHICLE_CHECKLIST
}

export function mapChecklist(): WizardChecklistItem[] {
  return MAP_CHECKLIST
}

export function businessChecklist(scenarios: string[]): WizardChecklistItem[] {
  const items: WizardChecklistItem[] = []
  const seen = new Set<string>()
  for (const id of scenarios) {
    const list = SCENARIO_CHECKLIST[id]
    if (!list) continue
    for (const it of list) {
      if (seen.has(it.key)) continue
      seen.add(it.key)
      items.push(it)
    }
  }
  return items.length ? items : GENERIC_BUSINESS
}

export function scenarioSetupHint(scenarios: string[]): string {
  if (scenarios.includes('tpl-sps')) {
    return '已选 SPS：进入设备管理，添加上下线机构，再配互锁站点、通讯参数和互锁点地址。'
  }
  if (scenarios.includes('tpl-pack')) {
    return '已选 Pack 产线：在设备管理中对接工位设备，并配置互锁站点与通讯。'
  }
  if (scenarios.includes('tpl-loop')) {
    return '已选环线：确认环线路径闭合，并按需配置交管参数。'
  }
  if (scenarios.includes('tpl-p2p')) {
    return '已选点对点：明确取放货站点，必要时配置任务模板。'
  }
  return '未选具体场景时，可按现场需要接入设备，或直接完成向导。'
}
