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
  fileSizeBytes: number
  fileWriteTime: string
  note: string
  durationMs: number
  frameCount: number
  headerReadable: boolean
  error: string
}

export interface ToolbarRecordingState {
  isRecording: boolean
  mode: string
  isPlaying: boolean
  elapsedMs: number
  frameCount: number
  droppedFrames: number
  currentRecordingFile: string | null
  recordingsDirectory: string
  entries: ToolbarRecordingEntry[]
}

export interface ToolbarLayer {
  name: string
  visible: boolean
}

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
}

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`))
}
