import * as ImagePicker from 'expo-image-picker'
import { ensureCameraPermission, ensureMediaLibraryPermission } from './permissions'
import type { MediaKind, PickOptions, RawAsset } from './types'

function assetToRaw(asset: ImagePicker.ImagePickerAsset): RawAsset {
  const kind: MediaKind = asset.type === 'video' ? 'video' : 'photo'
  const fallbackMime = kind === 'video' ? 'video/mp4' : 'image/jpeg'
  return {
    uri: asset.uri,
    kind,
    mimeType: asset.mimeType ?? fallbackMime,
    width: asset.width ?? undefined,
    height: asset.height ?? undefined,
    durationMs: asset.duration ?? undefined,
    size: asset.fileSize ?? undefined,
  }
}

/** The single entry point for library picks across the app. */
export async function pickMedia(opts: PickOptions): Promise<RawAsset[]> {
  const kinds = opts.kinds
  const wantsVideo = kinds.includes('video')
  // SDK 54+ behavior change: when videos are allowed, iOS shows its
  // permission dialog *after* selection. Pre-request so the prompt appears
  // up-front — feels consistent with image-only picks.
  if (wantsVideo) await ensureMediaLibraryPermission()

  const result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: kinds.map((k) => (k === 'video' ? 'videos' : 'images')),
    allowsMultipleSelection: opts.multiple ?? false,
    selectionLimit: opts.limit ?? 1,
    allowsEditing: opts.squareCrop ?? false,
    aspect: opts.squareCrop ? [1, 1] : undefined,
    quality: 1,
    orderedSelection: opts.ordered ?? true,
    exif: false,
    // Document intent: we don't want the picker to re-encode.
    // react-native-compressor owns that step for videos.
    videoExportPreset: ImagePicker.VideoExportPreset.Passthrough,
    legacy: opts.legacy,
  })

  if (result.canceled) return []
  return result.assets.map(assetToRaw)
}

/** Native camera capture via the system picker (post composer "camera" button). */
export async function captureMedia(kinds: MediaKind[]): Promise<RawAsset[]> {
  await ensureCameraPermission()
  const result = await ImagePicker.launchCameraAsync({
    mediaTypes: kinds.map((k) => (k === 'video' ? 'videos' : 'images')),
    quality: 1,
    exif: false,
    videoExportPreset: ImagePicker.VideoExportPreset.Passthrough,
  })
  if (result.canceled) return []
  return result.assets.map(assetToRaw)
}
