import { NextRequest, NextResponse } from "next/server"
import { getApproximateDataUriSizeInBytes } from "@/lib/media-manager/data-uri-size"
import { validateImageUploadRequest } from "@/lib/media-manager/validate-upload-request"
import { uploadImage } from "@/lib/r2-storage"
import { canonicalPublicMediaUrl } from "@/lib/r2-media-url"

export { appendCmsPageUploadQuery } from "@/lib/cms-page-upload-query"

const MAX_IMAGE_SIZE_BYTES = 1 * 1024 * 1024

export const CMS_PAGE_IDS = [
  "home-page",
  "procedures-page",
  "blog-page",
  "hospitals-page",
  "about-us",
  "contact-us",
] as const

export type CmsPageId = (typeof CMS_PAGE_IDS)[number]

function parseUploadIndex(value: unknown): number | undefined {
  if (typeof value === "number" && Number.isInteger(value) && value >= 0) return value
  if (typeof value === "string" && /^\d+$/.test(value.trim())) {
    const n = Number(value.trim())
    return Number.isInteger(n) && n >= 0 ? n : undefined
  }
  return undefined
}

function numberedFileName(base: string, index: number | undefined): string {
  const n = (index ?? 0) + 1
  return `${base}${n}`
}

/** Resolve R2 prefix + file base name for CMS static page uploads. */
export function resolveCmsPageUploadTarget(input: {
  page: CmsPageId
  section: string
  index?: number
  slot?: string | null
}): { prefix: string; fileBaseName: string } | null {
  const section = input.section.trim().toLowerCase()
  const slot = typeof input.slot === "string" ? input.slot.trim().toLowerCase() : ""

  if (input.page === "home-page") {
    const homeSections: Record<string, { prefix: string; nameBase: string }> = {
      services: { prefix: "home-page/services", nameBase: "Services" },
      process: { prefix: "home-page/process", nameBase: "Process" },
      reviews: { prefix: "home-page/reviews", nameBase: "Reviews" },
      hospitals: { prefix: "home-page/hospitals", nameBase: "Hospitals" },
      certifications: { prefix: "home-page/certifications", nameBase: "Certifications" },
    }
    const config = homeSections[section]
    if (!config) return null
    return {
      prefix: config.prefix,
      fileBaseName: numberedFileName(config.nameBase, input.index),
    }
  }

  if (section === "hero") {
    return {
      prefix: input.page,
      fileBaseName: "heroimage",
    }
  }

  if (input.page === "hospitals-page" && section === "certifications") {
    const n = (input.index ?? 0) + 1
    if (slot === "logo") {
      return {
        prefix: "hospitals-page/certifications",
        fileBaseName: `CertificationsLogo${n}`,
      }
    }
    return {
      prefix: "hospitals-page/certifications",
      fileBaseName: `Certifications${n}`,
    }
  }

  return null
}

/** Shared POST handler for CMS page image uploads (home, procedures-page, blog, …). */
export async function handleCmsPageImageUpload(req: NextRequest, page: CmsPageId) {
  try {
    const sectionParam =
      req.nextUrl.searchParams.get("section")?.trim().toLowerCase() ??
      ""
    const indexParam = parseUploadIndex(req.nextUrl.searchParams.get("index"))
    const slotParam = req.nextUrl.searchParams.get("slot")

    const rawBody = await req.json()
    const uploadValidation = validateImageUploadRequest(rawBody)
    if (!uploadValidation.ok) {
      return NextResponse.json({ error: uploadValidation.error }, { status: 400 })
    }

    const body = uploadValidation.body
    const sectionFromBody =
      typeof body.section === "string" ? body.section.trim().toLowerCase() : ""
    const section = sectionParam || sectionFromBody
    if (!section) {
      return NextResponse.json({ error: "Upload section is required" }, { status: 400 })
    }

    const index =
      indexParam ??
      parseUploadIndex(body.fileIndex) ??
      parseUploadIndex(body.index)
    const slot =
      (typeof slotParam === "string" && slotParam.trim()) ||
      (typeof body.slot === "string" && body.slot.trim()) ||
      null

    const target = resolveCmsPageUploadTarget({ page, section, index, slot })
    if (!target) {
      return NextResponse.json({ error: "Invalid upload section" }, { status: 400 })
    }

    const dataUri = uploadValidation.dataUri
    const sizeBytes = getApproximateDataUriSizeInBytes(dataUri)
    if (sizeBytes > MAX_IMAGE_SIZE_BYTES) {
      return NextResponse.json({ error: "Image size must be 1 MB or less" }, { status: 400 })
    }

    const { url, mediaKey } = await uploadImage(dataUri, {
      prefix: target.prefix,
      fileBaseName: target.fileBaseName,
    })

    const canonicalUrl = canonicalPublicMediaUrl(url, mediaKey)
    return NextResponse.json(
      { url: canonicalUrl, publicId: mediaKey, public_id: mediaKey },
      { status: 200 }
    )
  } catch (err) {
    console.error(`[${page}/upload-image] error:`, err)
    return NextResponse.json({ error: "Upload failed" }, { status: 500 })
  }
}
