import type { Prisma } from "@prisma/client"
import { buildDoctorTranslations, parseDoctorListFieldFromDb, unwrapDoctorLongTextJson } from "@/lib/doctor-db"
import { normalizePersistedMediaUrls } from "@/lib/normalize-persisted-media-urls"

export type PublicDoctor = {
  name: string
  slug: string
  category: string
  doctorImage: string
  rating: number
  reviewCount: number
  description: string
  experienceYears: number
  casesCount: string
  successRate: string
  nationalities: string
  languages: string[]
  tags: string[]
  featuredDoctor: boolean
  doctorStatement: string
  biography: string
  biographyHeading?: { title: string; subtitle: string } | null
  credentials: {
    education: string[]
    certifications: string[]
    researchPublications: string[]
    internationalExperience: string[]
  }
  credentialsHeading?: { title: string; subtitle: string } | null
  specialties: Array<{
    title: string
    description: string
    iconKey: string
  }>
  specialtiesHeading?: { title: string; subtitle: string } | null
  beforeAfter: Array<{
    image: string
    procedureType: string
    grafts: string
    monthsPostOp: number | null
    age: number | null
    satisfaction: number | null
  }>
  beforeAfterHeading?: { eyebrow: string; title: string; subtitle: string } | null
  reviews: Array<{
    patientName: string
    country: string
    treatment: string
    date: string
    content: string
    rating: number | null
  }>
  reviewsHeading?: { title: string; subtitle: string } | null
  faq: Array<{
    question: string
    answer: string
  }>
  faqHeading?: { title: string; subtitle: string } | null
  translations: ReturnType<typeof buildDoctorTranslations>
}

function parseStringList(value: unknown): string[] {
  if (!Array.isArray(value)) return []
  return value
    .filter((item): item is string => typeof item === "string")
    .map((item) => item.trim())
    .filter((item) => item !== "")
}

function parseCredentialsJson(value: unknown): PublicDoctor["credentials"] {
  value = unwrapDoctorLongTextJson(value)
  if (!value || typeof value !== "object") {
    return {
      education: [],
      certifications: [],
      researchPublications: [],
      internationalExperience: [],
    }
  }
  const source = value as {
    education?: unknown
    certifications?: unknown
    researchPublications?: unknown
    internationalExperience?: unknown
  }
  return {
    education: parseStringList(source.education),
    certifications: parseStringList(source.certifications),
    researchPublications: parseStringList(source.researchPublications),
    internationalExperience: parseStringList(source.internationalExperience),
  }
}

function parseSpecialtiesJson(value: unknown): PublicDoctor["specialties"] {
  value = unwrapDoctorLongTextJson(value)
  if (!Array.isArray(value)) return []
  return value
    .map((item) => {
      if (!item || typeof item !== "object") return null
      const source = item as { title?: unknown; description?: unknown; iconKey?: unknown; text?: unknown }
      const titleRaw = typeof source.title === "string" ? source.title : typeof source.text === "string" ? source.text : ""
      const title = titleRaw.trim()
      const description = typeof source.description === "string" ? source.description.trim() : ""
      const iconKey = typeof source.iconKey === "string" ? source.iconKey.trim() : ""
      if (!title || !iconKey || !description) return null
      return { title, description, iconKey }
    })
    .filter((item): item is PublicDoctor["specialties"][number] => item !== null)
}

function parseBeforeAfterJson(value: unknown): PublicDoctor["beforeAfter"] {
  value = unwrapDoctorLongTextJson(value)
  if (!Array.isArray(value)) return []
  return value
    .map((item) => {
      if (!item || typeof item !== "object") return null
      const source = item as {
        image?: unknown
        procedureType?: unknown
        grafts?: unknown
        monthsPostOp?: unknown
        age?: unknown
        satisfaction?: unknown
      }
      const image = typeof source.image === "string" ? source.image.trim() : ""
      const procedureType = typeof source.procedureType === "string" ? source.procedureType.trim() : ""
      if (!image || !procedureType) return null
      const grafts = typeof source.grafts === "string" ? source.grafts.trim() : ""
      const monthsPostOp = typeof source.monthsPostOp === "number" ? source.monthsPostOp : null
      const age = typeof source.age === "number" ? source.age : null
      const satisfaction = typeof source.satisfaction === "number" ? source.satisfaction : null
      return { image, procedureType, grafts, monthsPostOp, age, satisfaction }
    })
    .filter((item): item is PublicDoctor["beforeAfter"][number] => item !== null)
}

function parseReviewsJson(value: unknown): PublicDoctor["reviews"] {
  value = unwrapDoctorLongTextJson(value)
  if (!Array.isArray(value)) return []
  return value
    .map((item) => {
      if (!item || typeof item !== "object") return null
      const source = item as {
        patientName?: unknown
        country?: unknown
        treatment?: unknown
        date?: unknown
        content?: unknown
        rating?: unknown
      }
      const patientName = typeof source.patientName === "string" ? source.patientName.trim() : ""
      const country = typeof source.country === "string" ? source.country.trim() : ""
      const treatment = typeof source.treatment === "string" ? source.treatment.trim() : ""
      const content = typeof source.content === "string" ? source.content.trim() : ""
      if (!patientName || !country || !treatment || !content) return null
      const date = typeof source.date === "string" ? source.date.trim() : ""
      const rating = typeof source.rating === "number" ? source.rating : null
      return { patientName, country, treatment, date, content, rating }
    })
    .filter((item): item is PublicDoctor["reviews"][number] => item !== null)
}

function parseFaqJson(value: unknown): PublicDoctor["faq"] {
  value = unwrapDoctorLongTextJson(value)
  if (!Array.isArray(value)) return []
  return value
    .map((item) => {
      if (!item || typeof item !== "object") return null
      const source = item as { question?: unknown; answer?: unknown }
      const question = typeof source.question === "string" ? source.question.trim() : ""
      const answer = typeof source.answer === "string" ? source.answer.trim() : ""
      if (!question || !answer) return null
      return { question, answer }
    })
    .filter((item): item is PublicDoctor["faq"][number] => item !== null)
}

export const PUBLIC_DOCTOR_SELECT = {
  id: true,
  name: true,
  slug: true,
  image: true,
  rating: true,
  reviewCount: true,
  description: true,
  experienceYears: true,
  casesCount: true,
  successRate: true,
  nationalities: true,
  languages: true,
  tags: true,
  isFeatured: true,
  Category: { select: { name: true, color: true } },
  // use JSON columns and translations instead of relation fields (models were removed)
  credentialsJson: true,
  credentialsHeadingJson: true,
  specialtiesJson: true,
  specialtiesHeadingJson: true,
  beforeAfterJson: true,
  beforeAfterHeadingJson: true,
  reviewsJson: true,
  reviewsHeadingJson: true,
  faqJson: true,
  faqHeadingJson: true,
  // include admin-related fields so frontends can show status/timestamps when needed
  status: true,
  createdAt: true,
  updatedAt: true,
} as any as Prisma.DoctorSelect

type PublicDoctorRow = Prisma.DoctorGetPayload<{ select: typeof PUBLIC_DOCTOR_SELECT }>

type PublicDoctorTranslationRow = {
  locale: string
  name: string | null
  description: string | null
  credentials: unknown
  biography: string | null
  doctorStatement: string | null
  specialties: unknown
  beforeAfter: unknown
  reviews: unknown
  faq: unknown
  credentialsHeading?: { title: string; subtitle: string } | null
  biographyHeading?: { title: string; subtitle: string } | null
  specialtiesHeading?: { title: string; subtitle: string } | null
  beforeAfterHeading?: { eyebrow: string; title: string; subtitle: string } | null
  reviewsHeading?: { title: string; subtitle: string } | null
  faqHeading?: { title: string; subtitle: string } | null
  tags: unknown
  languages: unknown
}

export function mapToPublicDoctor(
  doctor: PublicDoctorRow,
  translationRows: PublicDoctorTranslationRow[] = []
): PublicDoctor {
  const translations = buildDoctorTranslations(
    {
      name: doctor.name,
      description: doctor.description,
      credentials: doctor.credentialsJson,
      biography: null,
      doctorStatement: null,
      specialties: doctor.specialtiesJson,
      beforeAfter: doctor.beforeAfterJson,
      reviews: doctor.reviewsJson,
      faq: doctor.faqJson,
      tags: doctor.tags,
      languages: doctor.languages,
      credentialsHeading: (doctor as any).credentialsHeadingJson,
      biographyHeading: (doctor as any).biographyHeadingJson,
      specialtiesHeading: (doctor as any).specialtiesHeadingJson,
      beforeAfterHeading: (doctor as any).beforeAfterHeadingJson,
      reviewsHeading: (doctor as any).reviewsHeadingJson,
      faqHeading: (doctor as any).faqHeadingJson,
    },
    translationRows
  )

  const localized = translations.en as any

  return normalizePersistedMediaUrls({
    name: doctor.name,
    slug: doctor.slug ?? "",
    category: doctor.Category.name,
    doctorImage: doctor.image,
    rating: doctor.rating,
    reviewCount: doctor.reviewCount,
    description: doctor.description,
    experienceYears: doctor.experienceYears,
    casesCount: doctor.casesCount,
    successRate: doctor.successRate,
    nationalities: doctor.nationalities,
    languages: parseDoctorListFieldFromDb(doctor.languages),
    tags: parseDoctorListFieldFromDb(doctor.tags),
    featuredDoctor: doctor.isFeatured,
    doctorStatement: localized?.doctorStatement ?? "",
    biography: localized?.biography ?? "",
    biographyHeading: localized?.biographyHeading ?? (doctor as any).biographyHeadingJson ?? null,
    credentials:
      doctor.credentialsJson !== null && doctor.credentialsJson !== undefined
        ? parseCredentialsJson(doctor.credentialsJson)
        : { education: [], certifications: [], researchPublications: [], internationalExperience: [] },
    specialties:
      doctor.specialtiesJson !== null && doctor.specialtiesJson !== undefined
        ? parseSpecialtiesJson(doctor.specialtiesJson)
        : [],
    beforeAfter:
      doctor.beforeAfterJson !== null && doctor.beforeAfterJson !== undefined
        ? parseBeforeAfterJson(doctor.beforeAfterJson)
        : [],
    reviews:
      doctor.reviewsJson !== null && doctor.reviewsJson !== undefined
        ? parseReviewsJson(doctor.reviewsJson)
        : [],
    faq:
      doctor.faqJson !== null && doctor.faqJson !== undefined
        ? parseFaqJson(doctor.faqJson)
        : [],
    faqHeading: (localized?.faqHeading ?? (doctor as any).faqHeadingJson) ?? null,
    credentialsHeading: (localized?.credentialsHeading ?? (doctor as any).credentialsHeadingJson) ?? null,
    specialtiesHeading: (localized?.specialtiesHeading ?? (doctor as any).specialtiesHeadingJson) ?? null,
    beforeAfterHeading: (localized?.beforeAfterHeading ?? (doctor as any).beforeAfterHeadingJson) ?? null,
    reviewsHeading: (localized?.reviewsHeading ?? (doctor as any).reviewsHeadingJson) ?? null,
    translations,
  })
}
