import { descriptionFromBody } from "@/lib/category-db"
import { Prisma } from "@prisma/client"

export const ARTICLE_ENTITY_TYPE = "article"
export const ARTICLE_LOCALES = ["en", "ar", "tr"] as const
export type ArticleLocale = (typeof ARTICLE_LOCALES)[number]

export type ArticleTranslationPayload = {
  title: string
  subTitle: string | null
  author: string
  content: string
  faqHeading?: string
  overview: Prisma.InputJsonValue
  faq: Prisma.InputJsonValue
  tags: string[]
  conversionCard?: Prisma.InputJsonValue | null
  trustCard?: Prisma.InputJsonValue | null
  images?: Prisma.InputJsonValue | null
}

type ArticleTranslationLike = {
  locale: string
  title: string | null
  subTitle: string | null
  author: string | null
  content: string | null
  faqHeading?: string | null
  overview: unknown
  faq: unknown
  tags: unknown
  conversionCard?: unknown
  trustCard?: unknown
}

export function parseArticleLocale(raw: string | null): ArticleLocale {
  if (raw === "ar" || raw === "tr" || raw === "en") return raw
  return "en"
}

export function parseArticleTranslationInput(value: unknown): ArticleTranslationPayload {
  if (!value || typeof value !== "object") {
    return { title: "", subTitle: null, author: "", content: "", faqHeading: "", overview: {}, faq: [], tags: [], conversionCard: null, trustCard: null, images: [] }
  }
  const source = value as Record<string, unknown>
  return {
    title: typeof source.title === "string" ? source.title.trim() : "",
    subTitle: descriptionFromBody(source.subTitle),
    author: typeof source.author === "string" ? source.author.trim() : "",
    faqHeading: typeof source.faqHeading === "string" ? source.faqHeading.trim() : "",
    content: typeof source.content === "string" ? source.content : "",
    overview: source.overview as Prisma.InputJsonValue ?? {},
    faq: Array.isArray(source.faq) ? (source.faq as Prisma.InputJsonValue) : ([] as Prisma.InputJsonValue),
    tags: Array.isArray(source.tags)
      ? source.tags.filter((t): t is string => typeof t === "string").map((t) => t.trim()).filter((t) => t !== "")
      : [],
    conversionCard: source.conversionCard as Prisma.InputJsonValue ?? null,
    trustCard: source.trustCard as Prisma.InputJsonValue ?? null,
    images: Array.isArray(source.images) ? (source.images as Prisma.InputJsonValue) : ([] as Prisma.InputJsonValue),
  }
}

export function parseArticlePayloadTranslations(payload: Record<string, unknown>) {
  const root =
    payload.translations && typeof payload.translations === "object"
      ? (payload.translations as Record<string, unknown>)
      : {}
  const en = parseArticleTranslationInput(root.en)
  const ar = parseArticleTranslationInput(root.ar)
  const tr = parseArticleTranslationInput(root.tr)

  if (!en.title) {
    en.title = typeof payload.title === "string" ? payload.title.trim() : ""
    if (en.subTitle === null) {
      en.subTitle = descriptionFromBody(payload.subTitle)
    }
  }
  if (!en.author) {
    en.author = typeof payload.author === "string" ? payload.author.trim() : ""
  }
  if (en.tags.length === 0 && Array.isArray(payload.tags)) {
    en.tags = payload.tags
      .filter((t): t is string => typeof t === "string")
      .map((t) => t.trim())
      .filter((t) => t !== "")
  }
  // fallback for cards: if translations.en doesn't include them, use top-level payload
  if (en.conversionCard === null || en.conversionCard === undefined) {
    en.conversionCard = payload.conversionCard as Prisma.InputJsonValue ?? null
  }
  if (en.trustCard === null || en.trustCard === undefined) {
    en.trustCard = payload.trustCard as Prisma.InputJsonValue ?? null
  }
  // fallback for faq heading
  if (!en.faqHeading) {
    en.faqHeading = typeof payload.faqHeading === "string" ? payload.faqHeading.trim() : ""
  }

  return { en, ar, tr }
}

export function buildArticleTranslations(
  base: {
    title: string
    subTitle: string | null
    author: string
    content: string
    contentHeading?: string
    faqHeading?: string
    overview: unknown
    faq: unknown
    tags: unknown
    conversionCard?: unknown
    trustCard?: unknown
  },
  rows: ArticleTranslationLike[]
) {
  const translations = {
    en: { title: "", subTitle: null as string | null, author: "", content: "", faqHeading: "" as string, overview: {} as Prisma.InputJsonValue, faq: [] as Prisma.InputJsonValue, tags: [] as string[], conversionCard: null as Prisma.InputJsonValue | null, trustCard: null as Prisma.InputJsonValue | null },
    ar: { title: "", subTitle: null as string | null, author: "", content: "", faqHeading: "" as string, overview: {} as Prisma.InputJsonValue, faq: [] as Prisma.InputJsonValue, tags: [] as string[], conversionCard: null as Prisma.InputJsonValue | null, trustCard: null as Prisma.InputJsonValue | null },
    tr: { title: "", subTitle: null as string | null, author: "", content: "", faqHeading: "" as string, overview: {} as Prisma.InputJsonValue, faq: [] as Prisma.InputJsonValue, tags: [] as string[], conversionCard: null as Prisma.InputJsonValue | null, trustCard: null as Prisma.InputJsonValue | null },
  }

  for (const row of rows) {
    if (row.locale !== "en" && row.locale !== "ar" && row.locale !== "tr") continue
    translations[row.locale] = {
      title: typeof row.title === "string" ? row.title.trim() : "",
      subTitle: descriptionFromBody(row.subTitle),
      author: typeof row.author === "string" ? row.author.trim() : "",
      content: typeof row.content === "string" ? row.content : "",
      faqHeading: typeof row.faqHeading === "string" ? row.faqHeading : "",
      overview: parseArticleStoredJson(row.overview, {}) as Prisma.InputJsonValue,
      faq: parseArticleStoredJson(row.faq, []) as Prisma.InputJsonValue,
      tags: parseArticleTagsFromDb(row.tags),
      conversionCard: parseArticleStoredJson(row.conversionCard, null) as Prisma.InputJsonValue | null,
      trustCard: parseArticleStoredJson(row.trustCard, null) as Prisma.InputJsonValue | null,
    }
  }

  if (!translations.en.title) {
    translations.en = {
      title: base.title.trim(),
      subTitle: descriptionFromBody(base.subTitle),
      author: base.author.trim(),
      content: base.content,
      faqHeading: base.faqHeading ?? "",
      overview: parseArticleStoredJson(base.overview, {}) as Prisma.InputJsonValue,
      faq: parseArticleStoredJson(base.faq, []) as Prisma.InputJsonValue,
      tags: parseArticleTagsFromDb(base.tags),
      conversionCard: parseArticleStoredJson(base.conversionCard, null) as Prisma.InputJsonValue | null,
      trustCard: parseArticleStoredJson(base.trustCard, null) as Prisma.InputJsonValue | null,
    }
  }

  return translations
}

export function resolveLocalizedArticle(
  translations: ReturnType<typeof buildArticleTranslations>,
  locale: string
) {
  const preferred = parseArticleLocale(locale)
  if (translations[preferred].title) return translations[preferred]
  return translations.en
}

function resolveArticleDisplayField(
  translations: ReturnType<typeof buildArticleTranslations>,
  field: "title" | "author"
): string {
  for (const locale of ARTICLE_LOCALES) {
    const value = translations[locale][field].trim()
    if (value) return value
  }
  return ""
}

/** Admin list display: English title, then Arabic, then Turkish. */
export function resolveArticleDisplayTitle(
  translations: ReturnType<typeof buildArticleTranslations>
): string {
  return resolveArticleDisplayField(translations, "title")
}

/** Admin list display: English author, then Arabic, then Turkish. */
export function resolveArticleDisplayAuthor(
  translations: ReturnType<typeof buildArticleTranslations>
): string {
  return resolveArticleDisplayField(translations, "author")
}

/** Read JSON stored in Prisma `String` / `LongText` columns (legacy rows may already be objects in memory). */
export function parseArticleStoredJson<T>(raw: unknown, fallback: T): T {
  if (raw === null || raw === undefined) return fallback
  if (typeof raw === "string") {
    const t = raw.trim()
    if (!t) return fallback
    try {
      return JSON.parse(t) as T
    } catch {
      return fallback
    }
  }
  if (typeof raw === "object") return raw as T
  return fallback
}

export function parseArticleTagsFromDb(raw: unknown): string[] {
  const parsed = parseArticleStoredJson(raw, [] as unknown[])
  if (!Array.isArray(parsed)) return []
  return parsed.filter((t): t is string => typeof t === "string")
}

/** Overview object stored as JSON text (Article.overview is required). */
export function serializeArticleOverviewForDb(value: unknown): string {
  if (value === null || value === undefined) return "{}"
  if (typeof value === "string") {
    const t = value.trim()
    if (!t) return "{}"
    try {
      JSON.parse(t)
      return t
    } catch {
      return JSON.stringify(value)
    }
  }
  return JSON.stringify(value)
}

/** FAQ list stored as JSON text. */
export function serializeArticleFaqForDb(value: unknown): string {
  if (typeof value === "string") {
    const t = value.trim()
    if (!t) return "[]"
    try {
      const p = JSON.parse(t)
      return JSON.stringify(Array.isArray(p) ? p : [])
    } catch {
      return "[]"
    }
  }
  if (!Array.isArray(value)) return "[]"
  return JSON.stringify(value)
}

export function serializeArticleTagsForDb(tags: string[]): string {
  return JSON.stringify(tags)
}

/**
 * Optional JSON in `String? @db.LongText` (conversion/trust cards).
 * Never use Prisma.JsonNull/DbNull here — those are enums and break String fields.
 */
export function serializeArticleLongTextJsonField(value: unknown): string | null {
  if (value === null || value === undefined) return null
  if (value === Prisma.JsonNull || value === Prisma.DbNull) return null
  if (typeof value === "string") {
    const t = value.trim()
    return t === "" ? null : t
  }
  if (typeof value === "object") return JSON.stringify(value)
  return null
}
