import { invoke } from '@tauri-apps/api/core'

export interface EngineStatus {
  running: boolean
  pid: number | null
  binaryPath: string | null
  args: string[]
  startedAt: number | null
}

export interface BinaryProbeResult {
  found: boolean
  binaryPath: string | null
  source: string | null
  candidates: string[]
}

export interface EngineStartPayload {
  binaryPath?: string
  rpcListenPort?: number
  rpcSecret?: string
  downloadDir?: string
  maxConcurrentDownloads?: number
  split?: number
}

export interface Aria2RpcConfig {
  rpcListenPort?: number
  rpcSecret?: string
}

export interface Aria2Task {
  gid: string
  status: string
  totalLength: string
  completedLength: string
  downloadSpeed: string
  dir: string
  fileName: string
  uri: string
}

export interface Aria2TaskSnapshot {
  active: Aria2Task[]
  waiting: Aria2Task[]
  stopped: Aria2Task[]
}

export interface Aria2TaskDetailFile {
  path: string
  length: string
  completedLength: string
  selected: string
  uris: string[]
}

export interface Aria2TaskDetailPeer {
  peerId: string
  ip: string
  port: string
  bitfield: string
  amChoking: string
  peerChoking: string
  downloadSpeed: string
  uploadSpeed: string
}

export interface Aria2TaskDetailServer {
  uri: string
  currentUri: string
  downloadSpeed: string
}

export interface Aria2TaskDetail {
  gid: string
  status: string
  totalLength: string
  completedLength: string
  uploadLength: string
  downloadSpeed: string
  uploadSpeed: string
  numSeeders: string
  connections: string
  pieceLength: string
  numPieces: string
  dir: string
  infoHash: string
  creationDate: string
  comment: string
  errorCode: string
  errorMessage: string
  trackers: string[]
  files: Aria2TaskDetailFile[]
  peers: Aria2TaskDetailPeer[]
  servers: Aria2TaskDetailServer[]
}

export interface AddUriPayload {
  rpc: Aria2RpcConfig
  uri: string
  out?: string
  dir?: string
  split?: number
  options?: Record<string, string | string[]>
  position?: number
}

export interface AddTorrentPayload {
  rpc: Aria2RpcConfig
  torrentBase64: string
  out?: string
  dir?: string
  split?: number
  options?: Record<string, string | string[]>
  position?: number
}

export interface TaskCommandPayload {
  rpc: Aria2RpcConfig
  gid: string
}

export interface ChangeGlobalOptionPayload {
  rpc: Aria2RpcConfig
  options: Record<string, string>
}

export interface TorrentFilePayload {
  name: string
  base64: string
  size: number
}

export interface ExternalAddRequest {
  url: string
  out?: string
  dir?: string
  referer?: string
  userAgent?: string
  authorization?: string
  cookie?: string
  proxy?: string
  split?: number
}

export async function getEngineStatus(): Promise<EngineStatus> {
  return invoke<EngineStatus>('engine_status')
}

export async function startEngine(payload: EngineStartPayload): Promise<EngineStatus> {
  return invoke<EngineStatus>('engine_start', { request: payload })
}

export async function stopEngine(): Promise<EngineStatus> {
  return invoke<EngineStatus>('engine_stop')
}

export async function detectAria2Binary(binaryPath?: string): Promise<BinaryProbeResult> {
  return invoke<BinaryProbeResult>('detect_aria2_binary', { binaryPath })
}

export async function listAria2Tasks(config: Aria2RpcConfig): Promise<Aria2TaskSnapshot> {
  return invoke<Aria2TaskSnapshot>('aria2_list_tasks', { config })
}

export async function getAria2TaskDetail(payload: TaskCommandPayload): Promise<Aria2TaskDetail> {
  return invoke<Aria2TaskDetail>('aria2_get_task_detail', { request: payload })
}

export async function addAria2Uri(payload: AddUriPayload): Promise<string> {
  return invoke<string>('aria2_add_uri', { request: payload })
}

export async function addAria2Torrent(payload: AddTorrentPayload): Promise<string> {
  return invoke<string>('aria2_add_torrent', { request: payload })
}

export async function loadTorrentFile(path: string): Promise<TorrentFilePayload> {
  return invoke<TorrentFilePayload>('load_torrent_file', { path })
}

export async function pauseAria2Task(payload: TaskCommandPayload): Promise<string> {
  return invoke<string>('aria2_pause_task', { request: payload })
}

export async function resumeAria2Task(payload: TaskCommandPayload): Promise<string> {
  return invoke<string>('aria2_resume_task', { request: payload })
}

export async function removeAria2Task(payload: TaskCommandPayload): Promise<string> {
  return invoke<string>('aria2_remove_task', { request: payload })
}

export async function removeAria2TaskRecord(payload: TaskCommandPayload): Promise<string> {
  return invoke<string>('aria2_remove_task_record', { request: payload })
}

export async function pauseAllAria2(config: Aria2RpcConfig): Promise<string> {
  return invoke<string>('aria2_pause_all', { config })
}

export async function resumeAllAria2(config: Aria2RpcConfig): Promise<string> {
  return invoke<string>('aria2_resume_all', { config })
}

export async function changeAria2GlobalOption(payload: ChangeGlobalOptionPayload): Promise<string> {
  return invoke<string>('aria2_change_global_option', { request: payload })
}

export async function openPathInFileManager(path: string): Promise<void> {
  return invoke<void>('open_path_in_file_manager', { path })
}

export async function focusMainWindow(): Promise<void> {
  return invoke<void>('focus_main_window')
}

export async function takeExternalAddRequests(): Promise<ExternalAddRequest[]> {
  return invoke<ExternalAddRequest[]>('take_external_add_requests')
}
