import { NextRequest, NextResponse } from "next/server"
import { prisma } from "@/lib/prisma"
import { requireFrontendServiceToken } from "@/lib/api/public-auth"
import {
  buildProcedureTranslationsForPublic,
  groupProcedureTranslationsByProcedureId,
  localizedProcedureBasicInfo,
  mergeProcedureLocaleWithEnglishFallback,
} from "@/lib/api/public-procedure-translations"
import { parseProcedureLocale } from "@/lib/procedure-db"

export const dynamic = "force-dynamic"
export const revalidate = 0

const NO_CACHE_HEADERS = {
  "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
  Pragma: "no-cache",
  Expires: "0",
}

function parseJsonOr<T>(value: string | null | undefined, fallback: T): T {
  if (!value) return fallback
  try {
    return JSON.parse(value) as T
  } catch {
    return fallback
  }
}

type ProcedureTranslationDelegate = {
  findMany: (args: {
    where: { procedureId: { in: string[] } }
    select: {
      procedureId: true
      locale: true
      name: true
      description: true
      stayCity: true
      overviewJson: true
      countriesComparisonJson: true
      processJson: true
      benefitsJson: true
      beforeAfterSectionJson: true
      doctorsSectionJson: true
      recoveryJson: true
      packageSectionJson: true
      reviewsSectionJson: true
      faqSectionJson: true
      relatedJson: true
      ctaJson: true
      videoSectionJson: true
      basicInfoJson: true
    }
  }) => Promise<Array<{
    procedureId: string
    locale: string
    name: string | null
    description: string | null
    stayCity: string | null
    overviewJson: string | null
    countriesComparisonJson: string | null
    processJson: string | null
    benefitsJson: string | null
    beforeAfterSectionJson: string | null
    doctorsSectionJson: string | null
    recoveryJson: string | null
    packageSectionJson: string | null
    reviewsSectionJson: string | null
    faqSectionJson: string | null
    relatedJson: string | null
    ctaJson: string | null
    videoSectionJson: string | null
      basicInfoJson: string | null
  }>>
}

type ProcedureDelegate = {
  findMany: (args: {
    where: { status: "published" }
    orderBy: { createdAt: "desc" }
    include: { Category: { select: { id: true; name: true; color: true; slug: true; iconKey: true } } }
  }) => Promise<Array<{
    id: string
    slug: string
    name: string
    description: string
    image: string
    imagePublicId: string
    rating: number
    reviewCount: number
    isFeatured: boolean
    status: string
    quickStatsJson: string
    basicInfoJson: string
    overviewJson: string
    countriesComparisonJson: string
    processJson: string
    benefitsJson: string
    beforeAfterSectionJson: string
    doctorsSectionJson: string
    recoveryJson: string
    packageSectionJson: string
    reviewsSectionJson: string
    faqSectionJson: string
    relatedJson: string
    ctaJson: string
    videoSectionJson: string
    createdAt: Date
    updatedAt: Date
    Category: { id: string; name: string; color: string; slug: string; iconKey: string | null } | null
  }>>
}

export async function GET(req: NextRequest) {
  const authError = requireFrontendServiceToken(req)
  if (authError) return authError

  try {
    const locale = parseProcedureLocale(req.nextUrl.searchParams.get("locale"))

    const procedureClient = (prisma as unknown as { procedure?: ProcedureDelegate }).procedure
    const rows = procedureClient ? await procedureClient.findMany({
      where: { status: "published" },
      orderBy: { createdAt: "desc" },
      include: { Category: { select: { id: true, name: true, color: true, slug: true, iconKey: true } } },
    }) : []

    const ids = rows.map((row) => row.id)
    const translationClient = (prisma as unknown as { procedureTranslation?: ProcedureTranslationDelegate }).procedureTranslation
    const allTrRows = ids.length && translationClient
      ? await translationClient.findMany({
          where: { procedureId: { in: ids } },
          select: {
            procedureId: true,
            locale: true,
            name: true,
            description: true,
            stayCity: true,
            overviewJson: true,
            countriesComparisonJson: true,
            processJson: true,
            benefitsJson: true,
            beforeAfterSectionJson: true,
            doctorsSectionJson: true,
            recoveryJson: true,
            packageSectionJson: true,
            reviewsSectionJson: true,
            faqSectionJson: true,
            relatedJson: true,
            ctaJson: true,
            videoSectionJson: true,
            basicInfoJson: true,
          },
        })
      : []

    const byProcedureId = groupProcedureTranslationsByProcedureId(allTrRows)

    return NextResponse.json(
      {
        success: true as const,
        procedures: rows.map((row) => {
          const translations = buildProcedureTranslationsForPublic(row, byProcedureId.get(row.id) ?? [])
          const primary = mergeProcedureLocaleWithEnglishFallback(translations, locale)
          const basicInfo = localizedProcedureBasicInfo(row.basicInfoJson, primary)
          return {
            id: row.id,
            slug: row.slug,
            name: primary.name,
            description: primary.description,
            stayCity: primary.stayCity,
            image: row.image,
            imagePublicId: row.imagePublicId,
            rating: row.rating,
            reviewCount: row.reviewCount,
            isFeatured: row.isFeatured,
            status: row.status,
            locale,
            basicInfo,
            quickStats: parseJsonOr(row.quickStatsJson, [] as unknown[]),
            overview: primary.overview,
            countriesComparison: primary.countriesComparison,
            process: primary.process,
            benefits: primary.benefits,
            beforeAfterSection: primary.beforeAfterSection,
            doctorsSection: primary.doctorsSection,
            recovery: primary.recovery,
            packageSection: primary.packageSection,
            reviewsSection: primary.reviewsSection,
            faqSection: primary.faqSection,
            related: primary.related,
            cta: primary.cta,
            videoSection: primary.videoSection,
            translations,
            category: row.Category,
            createdAt: row.createdAt.toISOString(),
            updatedAt: row.updatedAt.toISOString(),
          }
        }),
      },
      { headers: NO_CACHE_HEADERS }
    )
  } catch (error) {
    console.error("[public/procedures] GET error:", error)
    return NextResponse.json({ success: false as const, error: "Failed to load procedures" }, { status: 500 })
  }
}
