import {
  extractMediaKeyFromUrl,
  getR2PublicBaseUrl,
  rewriteLegacyMediaPublicUrl,
} from "@/lib/r2-media-url"

/** R2 key prefixes produced by dashboard uploads (CMS pages + entities). */
const MANAGED_MEDIA_KEY_PREFIXES = [
  "home-page/",
  "procedures-page/",
  "blog-page/",
  "hospitals-page/",
  "about-us/",
  "contact-us/",
  "doctors/",
  "hospitals/",
  "procedures/",
  "articles/",
] as const

function urlResolvesToManagedMediaKey(value: string): boolean {
  const key = extractMediaKeyFromUrl(rewriteLegacyMediaPublicUrl(value))
  if (!key) return false
  return MANAGED_MEDIA_KEY_PREFIXES.some(
    (prefix) => key === prefix.replace(/\/$/, "") || key.startsWith(prefix)
  )
}

/**
 * Local-upload-only policy for dashboard media.
 * Shared by frontend (staging/preview) and backend (API validation).
 */

export const LOCAL_UPLOAD_ONLY_ERROR =
  "Images must be uploaded from your device. External image links are not allowed."

export const UPLOAD_DATA_URI_ONLY_ERROR =
  "Image upload must use a local file (data URI). External image links are not allowed."

/** Keys that must never carry remote image URLs in upload request bodies. */
export const FORBIDDEN_UPLOAD_BODY_KEYS = new Set([
  "image",
  "imageurl",
  "imageUrl",
  "url",
  "src",
  "link",
  "externalurl",
  "remoteurl",
  "photo",
  "picture",
])

export function getManagedMediaOrigins(): string[] {
  const origins = new Set<string>()
  try {
    origins.add(new URL(getR2PublicBaseUrl()).origin)
  } catch {
    /* ignore invalid resolved base */
  }
  return [...origins]
}

export function isBlobOrDataImageSource(value: string): boolean {
  const raw = value.trim()
  return raw.startsWith("blob:") || /^data:image\//i.test(raw)
}

export function isRemoteHttpUrl(value: string): boolean {
  const raw = value.trim()
  return /^https?:\/\//i.test(raw)
}

/** True when URL is served from configured R2 public base (or legacy managed host list). */
export function isManagedMediaUrl(value?: string | null): boolean {
  const raw = typeof value === "string" ? value.trim() : ""
  if (!raw) return true
  if (isBlobOrDataImageSource(raw)) return true

  if (!isRemoteHttpUrl(raw)) return true

  if (urlResolvesToManagedMediaKey(raw)) return true

  try {
    const normalized = rewriteLegacyMediaPublicUrl(raw)
    const origin = new URL(normalized).origin
    const allowed = getManagedMediaOrigins()
    if (allowed.length > 0) return allowed.includes(origin)
    return false
  } catch {
    return false
  }
}

/** External = remote http(s) image URL that is not our managed CDN. */
export function isExternalImageUrl(value?: string | null): boolean {
  const raw = typeof value === "string" ? value.trim() : ""
  if (!raw) return false
  if (isBlobOrDataImageSource(raw)) return false
  if (!isRemoteHttpUrl(raw)) return false
  return !isManagedMediaUrl(raw)
}

export function isValidUploadDataUri(value: unknown): value is string {
  if (typeof value !== "string") return false
  const raw = value.trim()
  if (!/^data:image\//i.test(raw)) return false
  if (isRemoteHttpUrl(raw)) return false
  return raw.includes(";base64,")
}

export function assertValidUploadDataUri(value: unknown): string {
  if (!isValidUploadDataUri(value)) {
    throw new Error(UPLOAD_DATA_URI_ONLY_ERROR)
  }
  return value.trim()
}

export type PersistedImageUrlMode = "persist" | "preview"

/** Validate a stored/preview image URL against local-upload policy. */
export function getPersistedImageUrlError(
  value: unknown,
  options: { fieldPath?: string; mode?: PersistedImageUrlMode } = {}
): string | null {
  if (typeof value !== "string") return null
  const raw = value.trim()
  if (!raw) return null

  const label = options.fieldPath ? `Image (${options.fieldPath})` : "Image"
  const mode = options.mode ?? "persist"

  if (mode === "persist" && raw.startsWith("blob:")) {
    return `${label}: save the form to upload staged images from your device. External links are not allowed.`
  }

  if (mode === "persist" && /^data:image\//i.test(raw)) {
    return `${label}: must be uploaded via file picker, not pasted data.`
  }

  if (isExternalImageUrl(raw)) {
    return `${label}: ${LOCAL_UPLOAD_ONLY_ERROR}`
  }

  if (mode === "persist" && isRemoteHttpUrl(raw) && !isManagedMediaUrl(raw)) {
    return `${label}: ${LOCAL_UPLOAD_ONLY_ERROR}`
  }

  return null
}

export function assertPersistedImageUrl(
  value: unknown,
  options: { fieldPath?: string; mode?: PersistedImageUrlMode } = {}
): void {
  const err = getPersistedImageUrlError(value, options)
  if (err) throw new Error(err)
}

export function validateLocalImageFile(file: File, maxBytes?: number): string | null {
  if (!file.type.startsWith("image/")) {
    return "Please select a valid image file from your device."
  }
  if (typeof maxBytes === "number" && file.size > maxBytes) {
    return `Image must be ${Math.round(maxBytes / (1024 * 1024))} MB or less.`
  }
  return null
}
