import { Platform } from 'react-native'
import { uploadMediaV2 } from 'src/lib/api'
import type { UploadV2ErrorResponse, UploadV2Response } from 'src/lib/api-types'
import type { MediaAsset, UploadFile } from './types'

export type UploadResult =
  | { ok: true; data: UploadV2Response }
  | { ok: false; data: UploadV2ErrorResponse; message: string }

/** Builds the multipart file payload from a processed asset. On iOS we strip
 *  `file://` to satisfy the NSURLSession upload path. */
export function toUploadFile(asset: Pick<MediaAsset, 'uri' | 'mimeType'>): UploadFile {
  const name = asset.uri.split('/').slice(-1)[0]
  const uri = Platform.OS === 'ios' ? asset.uri.replace('file://', '') : asset.uri
  return {
    uri,
    type: asset.mimeType || 'image/jpeg',
    name: name || 'upload',
  }
}

export async function uploadOne(
  asset: MediaAsset,
  signal?: AbortSignal
): Promise<UploadResult> {
  if (signal?.aborted) {
    return {
      ok: false,
      data: { errors: { file: ['Cancelled'] }, message: 'Cancelled' },
      message: 'Cancelled',
    }
  }
  const file = toUploadFile(asset)
  const params =
    asset.altText && asset.altText.length
      ? { file, description: asset.altText }
      : { file }

  const res = await uploadMediaV2(params)
  if (Object.hasOwn(res, 'errors')) {
    const err = res as UploadV2ErrorResponse
    return {
      ok: false,
      data: err,
      message: err.errors?.file?.[0] ?? err.message ?? 'Upload failed',
    }
  }
  return { ok: true, data: res as UploadV2Response }
}

/** Uploads in parallel, returns the first error message if any upload failed. */
export async function uploadMediaBatch(
  assets: MediaAsset[],
  signal?: AbortSignal
): Promise<{ ok: true; ids: string[] } | { ok: false; message: string }> {
  const results = await Promise.all(assets.map((a) => uploadOne(a, signal)))
  const err = results.find((r) => !r.ok)
  if (err && !err.ok) return { ok: false, message: err.message }
  return { ok: true, ids: results.map((r) => (r.ok ? r.data.id : '')) }
}
