import http from './http'
import type {
  OtaJob,
  OtaPackageInfo,
  OtaSettings,
  OtaTarget,
  OtaVehicleRow
} from '@/types/ota'

export async function getOtaSettings(): Promise<OtaSettings> {
  const { data } = await http.get<OtaSettings>('/ota/settings')
  return data
}

export async function putOtaSettings(settings: OtaSettings): Promise<OtaSettings> {
  const { data } = await http.put<OtaSettings>('/ota/settings', settings)
  return data
}

export async function getOtaTarget(): Promise<{ target: OtaTarget | null; summary?: Record<string, string> }> {
  const { data } = await http.get<{ target: OtaTarget | null; summary?: Record<string, string> }>('/ota/target')
  return data
}

export async function listOtaPackages(): Promise<OtaPackageInfo[]> {
  const { data } = await http.get<OtaPackageInfo[]>('/ota/packages')
  return data
}

export async function activateOtaPackage(id: string, name?: string): Promise<OtaTarget> {
  const { data } = await http.post<OtaTarget>(`/ota/packages/${encodeURIComponent(id)}/activate`, null, {
    params: name ? { name } : undefined
  })
  return data
}

export async function deleteOtaPackage(id: string): Promise<void> {
  await http.delete(`/ota/packages/${encodeURIComponent(id)}`)
}

export async function pullOtaPackage(carId: string): Promise<OtaPackageInfo> {
  const { data } = await http.post<OtaPackageInfo>('/ota/packages/pull', { carId }, { timeout: 120000 })
  return data
}

export async function uploadOtaPackage(file: File): Promise<OtaPackageInfo> {
  const form = new FormData()
  form.append('file', file)
  const { data } = await http.post<OtaPackageInfo>('/ota/packages/upload', form, {
    headers: { 'Content-Type': 'multipart/form-data' },
    timeout: 300000
  })
  return data
}

export async function listOtaVehicles(latency?: boolean): Promise<OtaVehicleRow[]> {
  const { data } = await http.get<OtaVehicleRow[]>('/ota/vehicles', {
    params: latency === undefined ? undefined : { latency },
    timeout: 60000
  })
  return data
}

export async function listOtaJobs(take = 100): Promise<OtaJob[]> {
  const { data } = await http.get<OtaJob[]>('/ota/jobs', { params: { take } })
  return data
}

export async function getOtaJob(id: string): Promise<OtaJob> {
  const { data } = await http.get<OtaJob>(`/ota/jobs/${encodeURIComponent(id)}`)
  return data
}

export async function createOtaSyncJob(body: {
  carIds: string[]
  components?: string[]
  requireLatencyCheck?: boolean
}): Promise<OtaJob> {
  const { data } = await http.post<OtaJob>('/ota/jobs', body)
  return data
}

export async function cancelOtaJob(id: string): Promise<void> {
  await http.post(`/ota/jobs/${encodeURIComponent(id)}/cancel`)
}

export async function retryOtaJob(id: string): Promise<OtaJob> {
  const { data } = await http.post<OtaJob>(`/ota/jobs/${encodeURIComponent(id)}/retry`)
  return data
}

export async function getOtaConfig(carId: string, app: string): Promise<{ json: string }> {
  const { data } = await http.get<{ json: string }>(`/ota/config/${encodeURIComponent(carId)}/${encodeURIComponent(app)}`)
  return data
}

export async function pushOtaConfig(body: {
  carIds: string[]
  app: string
  json: string
  requireLatencyCheck?: boolean
}): Promise<OtaJob> {
  const { data } = await http.post<OtaJob>('/ota/config/push', body)
  return data
}

export async function pushOtaCustomFile(opts: {
  carIds: string[]
  remotePath: string
  restartOps: number[]
  files: File[]
}): Promise<OtaJob> {
  const form = new FormData()
  form.append('carIds', JSON.stringify(opts.carIds))
  form.append('remotePath', opts.remotePath)
  form.append('restartOps', JSON.stringify(opts.restartOps.length ? opts.restartOps : [-1]))
  for (const f of opts.files) form.append('files', f)
  const { data } = await http.post<OtaJob>('/ota/custom-file', form, {
    headers: { 'Content-Type': 'multipart/form-data' },
    timeout: 300000
  })
  return data
}
