import { onBeforeUnmount, onMounted } from 'vue'
import { useProjectionStream, type StreamEvent } from './useProjectionStream'

/**
 * 编辑器 / 监控页对 SimpleLite SSE 的事件订阅封装，把以下 5 类事件转给业务回调：
 *
 * - `alarm`               (来自 AlarmStreamService)：报警新增/更新/解除
 * - `object-created`      (来自 MapEditApiController)：对象创建后
 * - `object-deleted`      (来自 MapEditApiController)：对象删除后
 * - `object-patched`      (来自 MapEditApiController)：对象字段被 patch 后
 * - `object-batch-changed`(来自 batch / ai 调用)：一组对象变化，建议直接整页重拉
 * - `pick-result`         (来自 /pick)：拾取会话完成
 *
 * 业务页只用关心自己感兴趣的事件回调，其它走默认忽略。
 */

export interface AlarmEvent {
  action: 'raise' | 'update' | 'clear'
  carId: number
  carName: string
  info?: string
  x?: number
  y?: number
  timestamp: string
}

export interface ObjectChangeEvent {
  kind: string
  id: number
  typeName?: string
  source?: string
}

export interface PickResultEvent {
  x: number
  y: number
  siteId: number
}

export interface SelectionDetailEvent {
  /** 主选中 kind (site|track|car|null)；当多选时取首个非空集合的 kind。 */
  kind: 'site' | 'track' | 'car' | null
  /** 主选中 id；多选时取首个。 */
  id: number
  siteIds: number[]
  trackIds: number[]
  carIds: number[]
  /** 完整对象名列表，例如 ["UISite-12", "UITrack-7", "Car-3"]。 */
  names: string[]
}

export interface WorkspaceShortcutEvent {
  action: 'undo' | 'redo' | 'delete'
}

export interface MapEditStreamHandlers {
  onAlarm?: (e: AlarmEvent) => void
  onObjectCreated?: (e: ObjectChangeEvent) => void
  onObjectDeleted?: (e: ObjectChangeEvent) => void
  onObjectPatched?: (e: ObjectChangeEvent) => void
  onObjectBatchChanged?: (e: { count: number; source?: string }) => void
  onPickResult?: (e: PickResultEvent) => void
  onSelectionDetail?: (e: SelectionDetailEvent) => void
  /** iframe 画布聚焦时由 SimpleLite 经 SSE 转发的撤销/重做/删除。 */
  onWorkspaceShortcut?: (e: WorkspaceShortcutEvent) => void
  /** 视口样式（站点/路径 Painter）在 Web 或桌面对话框中变更后广播。 */
  onViewportStyleUpdated?: () => void
}

export function useMapEditStream(handlers: MapEditStreamHandlers) {
  const stream = useProjectionStream({ autoConnect: false })

  function dispatch(ev: StreamEvent) {
    const payload = ev?.payload as Record<string, unknown> | undefined
    if (!payload) return
    switch (ev.kind) {
      case 'alarm':
        handlers.onAlarm?.(payload as unknown as AlarmEvent)
        break
      case 'object-created':
        handlers.onObjectCreated?.(payload as unknown as ObjectChangeEvent)
        break
      case 'object-deleted':
        handlers.onObjectDeleted?.(payload as unknown as ObjectChangeEvent)
        break
      case 'object-patched':
        handlers.onObjectPatched?.(payload as unknown as ObjectChangeEvent)
        break
      case 'object-batch-changed':
        handlers.onObjectBatchChanged?.(payload as unknown as { count: number; source?: string })
        break
      case 'pick-result':
        handlers.onPickResult?.(payload as unknown as PickResultEvent)
        break
      case 'selection-detail':
        handlers.onSelectionDetail?.(payload as unknown as SelectionDetailEvent)
        break
      case 'workspace-shortcut':
        handlers.onWorkspaceShortcut?.(payload as unknown as WorkspaceShortcutEvent)
        break
      case 'viewport-style-updated':
        handlers.onViewportStyleUpdated?.()
        break
    }
  }

  onMounted(() => {
    stream.on(dispatch)
    stream.connect()
  })
  onBeforeUnmount(() => {
    stream.off(dispatch)
    stream.disconnect()
  })

  return { connected: stream.connected }
}
