import { buildContentAudit } from "@/lib/content-audit"
import type { CategoryApiRecord } from "@/types/category-api"

export const CATEGORY_ENTITY_TYPE = "category"
export const CATEGORY_LOCALES = ["en", "ar", "tr"] as const
export type CategoryLocale = (typeof CATEGORY_LOCALES)[number]

type TranslationLike = {
  locale: string
  name: string | null
  description: string | null
}

type CategoryRow = {
  id: string
  name: string
  slug: string
  description: string | null
  color: string
  iconKey?: string | null
  isVisible: boolean
  createdAt: Date
  updatedAt: Date
  createdBy?: {
    id: string
    name: string | null
    email: string
    image: string | null
  } | null
  updatedBy?: {
    id: string
    name: string | null
    email: string
    image: string | null
  } | null
}

function cleanName(value: unknown): string {
  if (typeof value !== "string") return ""
  return value.trim()
}

export function normalizeDescription(value: unknown): string | null {
  if (typeof value !== "string") return null
  const t = value.trim()
  return t === "" ? null : t
}

function emptyTranslations() {
  return {
    en: { name: "", description: null as string | null },
    ar: { name: "", description: null as string | null },
    tr: { name: "", description: null as string | null },
  }
}

export function buildCategoryTranslations(
  baseRow: Pick<CategoryRow, "name" | "description">,
  translationRows: TranslationLike[]
) {
  const translations = emptyTranslations()
  for (const row of translationRows) {
    if (row.locale !== "en" && row.locale !== "ar" && row.locale !== "tr") continue
    translations[row.locale] = {
      name: cleanName(row.name),
      description: normalizeDescription(row.description),
    }
  }

  if (!translations.en.name) {
    translations.en = {
      name: cleanName(baseRow.name),
      description: normalizeDescription(baseRow.description),
    }
  }

  return translations
}

export function resolveLocalizedCategory(
  translations: ReturnType<typeof buildCategoryTranslations>,
  locale: string
) {
  const preferred = locale === "ar" || locale === "tr" || locale === "en" ? locale : "en"
  const localized = translations[preferred]
  if (localized.name) return localized
  return translations.en
}

export type CategoryRelationCounts = {
  articles: number
  doctors: number
  hospitals: number
  procedures: number
}

export function normalizeCategoryRelationCounts(
  counts: number | CategoryRelationCounts = 0
): CategoryRelationCounts {
  if (typeof counts === "number") {
    return { articles: counts, doctors: 0, hospitals: 0, procedures: 0 }
  }
  return {
    articles: counts.articles ?? 0,
    doctors: counts.doctors ?? 0,
    hospitals: counts.hospitals ?? 0,
    procedures: counts.procedures ?? 0,
  }
}

export function categoryRelationCountsFromRow(row: {
  _count: {
    Article: number
    Doctor: number
    Hospital: number
    Procedure: number
  }
}): CategoryRelationCounts {
  return {
    articles: row._count.Article,
    doctors: row._count.Doctor,
    hospitals: row._count.Hospital,
    procedures: row._count.Procedure,
  }
}

export function toCategoryApiRecord(
  row: CategoryRow,
  counts: number | CategoryRelationCounts = 0,
  locale = "en",
  translationRows: TranslationLike[] = []
): CategoryApiRecord {
  const translations = buildCategoryTranslations(row, translationRows)
  const localized = resolveLocalizedCategory(translations, locale)
  const relationCounts = normalizeCategoryRelationCounts(counts)

  return {
    id: row.id,
    name: localized.name || row.name,
    slug: row.slug,
    description: localized.description,
    color: row.color,
    iconKey: row.iconKey ?? null,
    isVisible: row.isVisible,
    articleCount: relationCounts.articles,
    doctorCount: relationCounts.doctors,
    hospitalCount: relationCounts.hospitals,
    procedureCount: relationCounts.procedures,
    createdAt: row.createdAt.toISOString(),
    translations,
    audit: buildContentAudit(row),
  }
}

export function descriptionFromBody(value: unknown): string | null {
  return normalizeDescription(value)
}
