import type { ReleaseManifestPayload } from './auth/auth-api'
import type { DownloadPlatformKey } from './site-routes'
import { getReleasePlatformValidationSummary } from './shared/package-validation'

type FallbackDownloadTarget = {
  platformKey: DownloadPlatformKey
  platform: string
  subtitle: string
  configured: boolean
  details: string
}

type FallbackViewer = {
  authenticated: boolean
  canDownload: boolean
  plan: string | null
  role: string | null
  accessStatus: string | null
}

export type ReleaseManifestView = ReleaseManifestPayload['manifest']
export type ReleaseManifestPlatformView = ReleaseManifestView['platforms'][number]
export type ReleaseManifestCommerceView = NonNullable<ReleaseManifestView['commerce']>

export function buildFallbackReleaseManifest({
  downloadTargets,
  publicDocsUrl,
  releaseNotesUrl,
  correspondingSourceUrl,
  openSourceRepoUrl,
  supportEmail,
  viewer,
}: {
  downloadTargets: readonly FallbackDownloadTarget[]
  publicDocsUrl: string
  releaseNotesUrl: string
  correspondingSourceUrl: string
  openSourceRepoUrl: string
  supportEmail: string
  viewer?: FallbackViewer
}): ReleaseManifestView {
  return {
    generated_at: '',
    support_email: supportEmail,
    public_docs_url: publicDocsUrl || null,
    release_notes_url: releaseNotesUrl || null,
    corresponding_source_url: correspondingSourceUrl || null,
    open_source_repo_url: openSourceRepoUrl || null,
    viewer: viewer ?? {
      authenticated: false,
      canDownload: false,
      plan: null,
      role: null,
      accessStatus: null,
    },
    platforms: downloadTargets.map((target) => ({
      platform_key: target.platformKey,
      platform: target.platform,
      subtitle: target.subtitle,
      details: target.details,
      configured: target.configured,
      channel: 'early-access',
      version: null,
      build_id: null,
      published_at: null,
      file_name: null,
      file_size_bytes: null,
      checksum_sha256: null,
      download_url: null,
      download_available: false,
      validation_summary: getReleasePlatformValidationSummary(target.platformKey),
    })),
  }
}

export function resolveReleaseManifestView(
  manifest: ReleaseManifestView | null | undefined,
  fallback: {
    downloadTargets: readonly FallbackDownloadTarget[]
    publicDocsUrl: string
    releaseNotesUrl: string
    correspondingSourceUrl: string
    openSourceRepoUrl: string
    supportEmail: string
  },
) {
  return manifest ?? buildFallbackReleaseManifest(fallback)
}

export function resolveReleaseCommerceView(
  manifest: ReleaseManifestView | null | undefined,
  fallback: {
    operatorCheckoutUrl: string
    studioCheckoutUrl: string
    planPriceOperator: string
    planPriceStudio: string
  },
): ReleaseManifestCommerceView {
  return {
    operator_checkout_url: manifest?.commerce?.operator_checkout_url ?? fallback.operatorCheckoutUrl ?? null,
    studio_checkout_url: manifest?.commerce?.studio_checkout_url ?? fallback.studioCheckoutUrl ?? null,
    plan_price_operator: manifest?.commerce?.plan_price_operator || fallback.planPriceOperator,
    plan_price_studio: manifest?.commerce?.plan_price_studio || fallback.planPriceStudio,
  }
}

export function formatReleaseFileSize(fileSizeBytes: number | null | undefined) {
  if (typeof fileSizeBytes !== 'number' || !Number.isFinite(fileSizeBytes) || fileSizeBytes < 0) {
    return null
  }

  if (fileSizeBytes < 1024) {
    return `${fileSizeBytes} B`
  }
  if (fileSizeBytes < 1024 * 1024) {
    return `${(fileSizeBytes / 1024).toFixed(1)} KB`
  }
  if (fileSizeBytes < 1024 * 1024 * 1024) {
    return `${(fileSizeBytes / (1024 * 1024)).toFixed(1)} MB`
  }

  return `${(fileSizeBytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
}

export function formatReleasePublishedAt(value: string | null | undefined) {
  if (!value) {
    return null
  }

  const parsedDate = new Date(value)
  if (Number.isNaN(parsedDate.getTime())) {
    return value
  }

  return new Intl.DateTimeFormat('en-US', {
    dateStyle: 'medium',
    timeStyle: 'short',
    timeZone: 'UTC',
  }).format(parsedDate)
}

export function buildReleaseMetadataItems(platform: ReleaseManifestPlatformView) {
  return [
    platform.version ? { label: 'Version', value: platform.version } : null,
    platform.channel ? { label: 'Channel', value: platform.channel } : null,
    platform.build_id ? { label: 'Build', value: platform.build_id } : null,
    platform.file_name ? { label: 'Package', value: platform.file_name } : null,
    formatReleaseFileSize(platform.file_size_bytes)
      ? { label: 'Size', value: formatReleaseFileSize(platform.file_size_bytes) as string }
      : null,
    platform.checksum_sha256 ? { label: 'SHA-256', value: platform.checksum_sha256 } : null,
    formatReleasePublishedAt(platform.published_at)
      ? { label: 'Published', value: formatReleasePublishedAt(platform.published_at) as string }
      : null,
  ].filter((item): item is { label: string; value: string } => item != null)
}
