import http from './http'

/**
 * 工作区画布工具栏 API（对应 SimpleLite `WorkspaceToolbarApiController`）。
 *
 * 历史背景（会话33）：原 SimpleLite iframe 内 ImGui 底栏 (`Panel_4` /
 * `WorkspaceBottomBar.DefineForTerminalEmbedMinimal`) 提供 8 个按钮，平台 iframe
 * 嵌入时该底栏会盖在画布上影响交互。本会话把这条底栏整体迁到 Vue 端
 * `WorkspaceCanvasToolbar.vue` 渲染，状态读写改走该 HTTP API。
 *
 * 路径前缀：`/sl/projection/toolbar` (Platform.Server YARP → SimpleLite EmbedIO :8222)
 */

const BASE = '/sl/projection/toolbar'

export type AlignKey = 'sites' | 'cars' | 'tracks'
export type SelectKey = 'tracks' | 'cars' | 'decor' | 'sites'
export type DisplayKey = 'labels' | 'primitives' | 'cars'

export interface ToolbarRecordingEntry {
  fileName: string
  /** 用户可编辑的显示名（旁挂 .meta.json，决策 A-方案2）；为空时回退到 fileName。 */
  displayName: string
  fileSizeBytes: number
  fileWriteTime: string
  note: string
  durationMs: number
  frameCount: number
  headerReadable: boolean
  error: string
}

export interface ToolbarRecordingState {
  isRecording: boolean
  mode: string
  isPlaying: boolean
  isAutoPlaying?: boolean
  speed?: number
  elapsedMs: number
  durationMs?: number
  frameCount: number
  currentFrameIndex?: number
  droppedFrames: number
  currentRecordingFile: string | null
  currentPlaybackFile?: string | null
  recordingsDirectory: string
  entries: ToolbarRecordingEntry[]
}

export interface ToolbarLayer {
  name: string
  visible: boolean
}

export interface ToolbarViewState {
  map2D: boolean
  follow: {
    enabled: boolean
    carId: number | null
  }
}

export interface ToolbarState {
  align: { sites: boolean; cars: boolean; tracks: boolean }
  select: { tracks: boolean; cars: boolean; decor: boolean; sites: boolean }
  display: { labels: boolean; primitives: boolean; cars: boolean }
  layers: ToolbarLayer[]
  recording: ToolbarRecordingState
  view?: ToolbarViewState
}

interface Envelope<T> {
  success: boolean
  code: number
  data: T | null
  message: string
}

function compatTogglePayload(key: string, value: boolean) {
  return { key, value, Key: key, Value: value }
}

function compatLayerPayload(name: string, visible: boolean) {
  return { name, visible, Name: name, Visible: visible }
}

function compatNotePayload(note: string) {
  return { note, Note: note }
}

function compatFilePayload(fileName: string) {
  return { fileName, FileName: fileName }
}

async function unwrap<T>(p: Promise<{ data: Envelope<T> }>): Promise<T> {
  const resp = (await p).data
  if (!resp?.success) throw new Error(resp?.message ?? '请求失败')
  if (resp.data == null) throw new Error('服务端返回空数据')
  return resp.data
}

export const workspaceToolbarApi = {
  getState: () => unwrap<ToolbarState>(http.get(`${BASE}/state`)),

  setAlign: (key: AlignKey, value: boolean) =>
    unwrap<ToolbarState>(http.post(`${BASE}/align`, compatTogglePayload(key, value))),

  setSelect: (key: SelectKey, value: boolean) =>
    unwrap<ToolbarState>(http.post(`${BASE}/select`, compatTogglePayload(key, value))),

  setDisplay: (key: DisplayKey, value: boolean) =>
    unwrap<ToolbarState>(http.post(`${BASE}/display`, compatTogglePayload(key, value))),

  setLayerVisibility: (name: string, visible: boolean) =>
    unwrap<ToolbarState>(http.post(`${BASE}/layer`, compatLayerPayload(name, visible))),

  startRecording: (note?: string) =>
    unwrap<ToolbarState>(http.post(`${BASE}/recording/start`, compatNotePayload(note ?? ''))),

  stopRecording: () => unwrap<ToolbarState>(http.post(`${BASE}/recording/stop`)),

  deleteRecording: (fileName: string) =>
    unwrap<ToolbarState>(http.delete(`${BASE}/recording/${encodeURIComponent(fileName)}`)),

  startPlayback: (fileName: string) =>
    unwrap<ToolbarState>(http.post(`${BASE}/playback/start`, compatFilePayload(fileName))),

  stopPlayback: () => unwrap<ToolbarState>(http.post(`${BASE}/playback/stop`)),

  playPause: () => unwrap<ToolbarState>(http.post(`${BASE}/playback/play-pause`, {})),

  seekElapsed: (elapsedMs: number) =>
    unwrap<ToolbarState>(http.post(`${BASE}/playback/seek`, { elapsedMs, ElapsedMs: elapsedMs })),

  seekFrame: (frameIndex: number) =>
    unwrap<ToolbarState>(http.post(`${BASE}/playback/seek`, { frameIndex, FrameIndex: frameIndex })),

  step: (delta = 1) =>
    unwrap<ToolbarState>(http.post(`${BASE}/playback/step`, { delta, Delta: delta })),

  setSpeed: (speed: number) =>
    unwrap<ToolbarState>(http.post(`${BASE}/playback/speed`, { speed, Speed: speed })),

  toggleViewMode: () => unwrap<ToolbarState>(http.post(`${BASE}/view/toggle`)),

  setCameraFollow: (carId: number | null, enabled: boolean) =>
    unwrap<ToolbarState>(
      http.post(`${BASE}/camera/follow`, {
        carId: carId ?? undefined,
        enabled,
        CarId: carId ?? undefined,
        Enabled: enabled
      })
    ),

  /**
   * 一次性把地图相机定位（居中 + 2D 俯视）到指定车辆，不开启持续跟随。
   * 对应 SimpleLite `WorkspaceToolbarApiController.LocateCamera`（与原生「双击车辆行 = 选中+定位」一致）。
   */
  locateCamera: (carId: number) =>
    unwrap<ToolbarState>(
      http.post(`${BASE}/camera/locate`, {
        carId,
        CarId: carId
      })
    )
}
