import {
  reflectionApi,
  emptyMonitorVisibilityMap,
  type MonitorConfigPayload,
  type MonitorVisibilityMap
} from '@/api/reflection'
import { invalidateMonitorConfigCache } from '@/utils/monitorConfigCache'
import { DEFAULT_OPS } from '@/mock/data/configs'
import type { MonitorOpsPolicy, OpsConfig } from '@/types/config'

export type MonitorConfigRoot = MonitorVisibilityMap & { carActionByType?: Record<string, string[]> }

export function defaultMonitorPolicy(): MonitorOpsPolicy {
  return JSON.parse(JSON.stringify(DEFAULT_OPS.monitor)) as MonitorOpsPolicy
}

export function normalizeOpsConfig(raw?: Partial<OpsConfig> | null): OpsConfig {
  const base = JSON.parse(JSON.stringify(DEFAULT_OPS)) as OpsConfig
  if (!raw) return base
  const monitor = {
    ...defaultMonitorPolicy(),
    ...(raw.monitor ?? {}),
    car: { ...defaultMonitorPolicy().car, ...(raw.monitor?.car ?? {}) },
    site: { ...defaultMonitorPolicy().site, ...(raw.monitor?.site ?? {}) },
    track: { ...defaultMonitorPolicy().track, ...(raw.monitor?.track ?? {}) },
    carActionByType: { ...(raw.monitor?.carActionByType ?? {}) }
  }
  return {
    ...base,
    ...raw,
    playback: { ...base.playback, ...(raw.playback ?? {}) },
    logRetention: { ...base.logRetention, ...(raw.logRetention ?? {}) },
    version: { ...base.version, ...(raw.version ?? {}) },
    monitor
  }
}

/** 深拷贝车型动作表，避免与 SimpleLite 返回对象共享引用导致勾选 UI 不同步。 */
export function cloneCarActionByType(
  src?: Record<string, string[] | readonly string[]> | null
): Record<string, string[]> {
  const out: Record<string, string[]> = {}
  if (!src) return out
  for (const [k, v] of Object.entries(src)) {
    if (!k || !Array.isArray(v)) continue
    out[k] = [...v]
  }
  return out
}

function pickMonitorRoot(cfg: MonitorConfigRoot) {
  return {
    carActionByType: cloneCarActionByType(cfg.carActionByType),
    siteActionKeys: [...(cfg.site?.methods ?? [])],
    trackActionKeys: [...(cfg.track?.methods ?? [])]
  }
}

/**
 * 从 SimpleLite simple.json 加载地图监控配置（运行时唯一可信源）。
 * Platform ops 里的 monitor 仅作备份；以 SimpleLite 为准覆盖表单。
 */
export interface LoadMonitorSettingsResult {
  config: OpsConfig
  /** 与 SimpleLite 对齐的 monitor-config 快照，供保存时合并 fields/status，避免每次 POST 前再 GET。 */
  cache: MonitorConfigRoot | null
}

export async function loadMonitorSettingsIntoOps(
  payload: OpsConfig,
  preloaded?: MonitorConfigPayload | null
): Promise<LoadMonitorSettingsResult> {
  const next = normalizeOpsConfig(payload)
  let cache: MonitorConfigRoot | null = null
  try {
    const mc = preloaded ?? (await reflectionApi.getMonitorConfig())
    cache = mc.config as MonitorConfigRoot
    const picked = pickMonitorRoot(cache)
    next.monitor.carActionByType = picked.carActionByType
    next.monitor.site.actionKeys = picked.siteActionKeys
    next.monitor.track.actionKeys = picked.trackActionKeys
  } catch {
    // SimpleLite 未连接：退回 Platform payload 中已有的 monitor（若有）
  }
  return { config: next, cache }
}

/**
 * 将运营维护表单中的地图监控配置写入 SimpleLite（simple.json）。
 * 保留「地图监控配置」页面对 fields/status 的既有设置，只更新动作相关字段。
 */
export interface SaveMonitorSettingsOptions {
  /** 页面加载时缓存的 monitor-config，避免勾选自动保存时重复 GET（该接口会全量反射扫描）。 */
  cachedRoot?: MonitorConfigRoot | null
}

export async function saveMonitorSettingsFromOps(
  payload: OpsConfig,
  options?: SaveMonitorSettingsOptions
): Promise<MonitorConfigRoot> {
  const monitor = normalizeOpsConfig(payload).monitor
  let current: MonitorConfigRoot = options?.cachedRoot ?? emptyMonitorVisibilityMap()
  if (!options?.cachedRoot) {
    try {
      const mc = await reflectionApi.getMonitorConfig()
      current = mc.config as MonitorConfigRoot
    } catch {
      // 无现有配置时用空壳，仍可写入动作白名单
    }
  }

  const saved = await reflectionApi.saveMonitorConfig({
    car: {
      fields: [...(current.car?.fields ?? [])],
      status: [...(current.car?.status ?? [])],
      methods: [...(current.car?.methods ?? [])]
    },
    site: {
      fields: [...(current.site?.fields ?? [])],
      status: [...(current.site?.status ?? [])],
      methods: [...monitor.site.actionKeys]
    },
    track: {
      fields: [...(current.track?.fields ?? [])],
      status: [...(current.track?.status ?? [])],
      methods: [...monitor.track.actionKeys]
    },
    carActionByType: cloneCarActionByType(monitor.carActionByType)
  })
  invalidateMonitorConfigCache()
  return saved as MonitorConfigRoot
}

/** @deprecated 使用 loadMonitorSettingsIntoOps */
export const mergeMonitorFromSimpleLite = loadMonitorSettingsIntoOps

/** @deprecated 使用 saveMonitorSettingsFromOps */
export const syncOpsMonitorToSimpleLite = saveMonitorSettingsFromOps
