import type { Prisma } from "@prisma/client"
import { buildArticleTranslations, parseArticleTagsFromDb } from "@/lib/article-db"
import { normalizePersistedMediaUrls } from "@/lib/normalize-persisted-media-urls"

export type PublicArticle = {
  slug: string
  category: string
  publishDate: string
  title: string
  subTitle: string
  author: string
  readingTime: string
  faqHeading: string
  tags: string[]
  featuredArticle: boolean
  articleImage: string
  articleContent: string
  overview: Record<string, unknown> | unknown[]
  faq: Record<string, unknown> | unknown[]
  conversionCard?: { icon?: string; title?: string; description?: string; primaryButton?: { icon?: string; text?: string; link?: string }; secondaryButton?: { icon?: string; text?: string; link?: string } } | null
  trustCard?: { title?: string; items?: { label: string; value: string }[] } | null
  translations: ReturnType<typeof buildArticleTranslations>
}

export const PUBLIC_ARTICLE_SELECT = {
  id: true,
  slug: true,
  title: true,
  subTitle: true,
  author: true,
  readingTime: true,
  faqHeading: true,
  tags: true,
  isFeatured: true,
  image: true,
  content: true,
  publishDate: true,
  overview: true,
  faq: true,
  conversionCard: true,
  trustCard: true,
  Category: { select: { name: true } },
} satisfies Prisma.ArticleSelect

function toStructuredJson(value: unknown): Record<string, unknown> | unknown[] {
  if (typeof value === "string") {
    const t = value.trim()
    if (!t) return {}
    try {
      const parsed = JSON.parse(t) as unknown
      if (Array.isArray(parsed)) return parsed
      if (parsed && typeof parsed === "object") return parsed as Record<string, unknown>
    } catch {
      /* ignore */
    }
    return {}
  }

  if (Array.isArray(value)) {
    return value
  }

  if (value && typeof value === "object" && !Array.isArray(value)) {
    return value as Record<string, unknown>
  }

  return {}
}

function parseOptionalRecord(value: unknown): Record<string, unknown> | null {
  if (value === null || value === undefined) return null
  if (typeof value === "string") {
    const t = value.trim()
    if (!t) return null
    try {
      const parsed = JSON.parse(t) as unknown
      if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed as Record<string, unknown>
    } catch {
      return null
    }
    return null
  }
  if (typeof value === "object" && !Array.isArray(value)) return value as Record<string, unknown>
  return null
}

type PublicArticleRow = {
  id: string
  slug: string
  title: string
  subTitle: string | null
  author: string
  readingTime: string
  faqHeading: string | null
  tags: unknown
  isFeatured: boolean
  image: string
  content: string
  publishDate: Date
  overview: unknown
  faq: unknown
  conversionCard: unknown
  trustCard: unknown
  Category: { name: string }
}

export function mapToPublicArticle(
  article: PublicArticleRow,
  translations: ReturnType<typeof buildArticleTranslations>
): PublicArticle {

  return normalizePersistedMediaUrls({
    slug: article.slug,
    category: article.Category.name,
    publishDate: article.publishDate.toISOString(),
    title: article.title,
    subTitle: article.subTitle ?? "",
    author: article.author,
    readingTime: article.readingTime,
    faqHeading: article.faqHeading ?? "",
    tags: parseArticleTagsFromDb(article.tags),
    featuredArticle: article.isFeatured,
    articleImage: article.image,
    articleContent: article.content,
    overview: toStructuredJson(article.overview),
    faq: toStructuredJson(article.faq),
    conversionCard: parseOptionalRecord(article.conversionCard) as PublicArticle["conversionCard"],
    trustCard: parseOptionalRecord(article.trustCard) as PublicArticle["trustCard"],
    translations,
  })
}
