import { NextResponse } from "next/server"
import type { ContentAudit, ContentAuditUser } from "@/types/content-audit"
import { contentAuditUserSelect } from "@/types/content-audit"
import { getCurrentUser, type CurrentUser } from "@/lib/user"

export { contentAuditUserSelect }
export {
  formatContentAuditDate,
  formatContentAuditDateTime,
  getContentAuditUserLabel,
} from "@/lib/content-audit-format"

type AuditUserRow = {
  id: string
  name: string | null
  email: string
  image: string | null
} | null

type AuditTimestamps = {
  createdAt: Date
  updatedAt: Date
}

type AuditRelations = {
  createdBy?: AuditUserRow
  updatedBy?: AuditUserRow
}

/** Prisma relation field names on content models (schema uses PascalCase). */
type ContentAuditPrismaAliases = {
  User_Category_createdByIdToUser?: AuditUserRow
  User_Category_updatedByIdToUser?: AuditUserRow
  User_Article_createdByIdToUser?: AuditUserRow
  User_Article_updatedByIdToUser?: AuditUserRow
  User_Doctor_createdByIdToUser?: AuditUserRow
  User_Doctor_updatedByIdToUser?: AuditUserRow
  User_Hospital_createdByIdToUser?: AuditUserRow
  User_Hospital_updatedByIdToUser?: AuditUserRow
  User_Procedure_createdByIdToUser?: AuditUserRow
  User_Procedure_updatedByIdToUser?: AuditUserRow
  User_User_createdByIdToUser?: AuditUserRow
  User_User_updatedByIdToUser?: AuditUserRow
}

export function serializeContentAuditUser(user: AuditUserRow): ContentAuditUser | null {
  if (!user) return null
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    image: user.image,
  }
}

function resolveContentAuditRelations(
  row: AuditRelations & ContentAuditPrismaAliases
): { createdBy: AuditUserRow; updatedBy: AuditUserRow } {
  const createdBy =
    row.createdBy ??
    row.User_Category_createdByIdToUser ??
    row.User_Article_createdByIdToUser ??
    row.User_Doctor_createdByIdToUser ??
    row.User_Hospital_createdByIdToUser ??
    row.User_Procedure_createdByIdToUser ??
    row.User_User_createdByIdToUser ??
    null

  const updatedBy =
    row.updatedBy ??
    row.User_Category_updatedByIdToUser ??
    row.User_Article_updatedByIdToUser ??
    row.User_Doctor_updatedByIdToUser ??
    row.User_Hospital_updatedByIdToUser ??
    row.User_Procedure_updatedByIdToUser ??
    row.User_User_updatedByIdToUser ??
    null

  return { createdBy, updatedBy }
}

/** Build the unified audit object for API responses. */
export function buildContentAudit(row: AuditTimestamps & AuditRelations & ContentAuditPrismaAliases): ContentAudit {
  const { createdBy, updatedBy } = resolveContentAuditRelations(row)
  return {
    createdAt: row.createdAt.toISOString(),
    updatedAt: row.updatedAt.toISOString(),
    createdBy: serializeContentAuditUser(createdBy),
    updatedBy: serializeContentAuditUser(updatedBy),
  }
}

const auditUserRelationSelect = { select: contentAuditUserSelect } as const

/** @deprecated Use model-specific includes below. Kept only to surface type errors at call sites. */
export const contentAuditInclude = {
  createdBy: auditUserRelationSelect,
  updatedBy: auditUserRelationSelect,
} as const

export const contentAuditCategoryInclude = {
  User_Category_createdByIdToUser: auditUserRelationSelect,
  User_Category_updatedByIdToUser: auditUserRelationSelect,
} as const

export const contentAuditArticleInclude = {
  User_Article_createdByIdToUser: auditUserRelationSelect,
  User_Article_updatedByIdToUser: auditUserRelationSelect,
} as const

export const contentAuditDoctorInclude = {
  User_Doctor_createdByIdToUser: auditUserRelationSelect,
  User_Doctor_updatedByIdToUser: auditUserRelationSelect,
} as const

export const contentAuditHospitalInclude = {
  User_Hospital_createdByIdToUser: auditUserRelationSelect,
  User_Hospital_updatedByIdToUser: auditUserRelationSelect,
} as const

export const contentAuditProcedureInclude = {
  User_Procedure_createdByIdToUser: auditUserRelationSelect,
  User_Procedure_updatedByIdToUser: auditUserRelationSelect,
} as const

export const contentAuditUserInclude = {
  User_User_createdByIdToUser: auditUserRelationSelect,
  User_User_updatedByIdToUser: auditUserRelationSelect,
} as const

/** Set on every write — schema has no `@updatedAt` auto-touch. */
export function touchUpdatedAt() {
  return { updatedAt: new Date() }
}

/** Fields to set on create when an admin is authenticated. */
export function contentAuditCreateData(userId: string) {
  return {
    createdById: userId,
    updatedById: userId,
    ...touchUpdatedAt(),
  }
}

/** Fields to set on update when an admin is authenticated. */
export function contentAuditUpdateData(userId: string) {
  return {
    updatedById: userId,
    ...touchUpdatedAt(),
  }
}

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

/** Require an authenticated dashboard user before mutating auditable content. */
export async function requireContentAuditActor():
  Promise<{ ok: true; user: CurrentUser } | { ok: false; response: NextResponse }> {
  const user = await getCurrentUser()
  if (!user) {
    return {
      ok: false,
      response: NextResponse.json(
        { success: false as const, error: "Unauthorized" },
        { status: 401, headers: NO_CACHE_HEADERS }
      ),
    }
  }
  return { ok: true, user }
}
