// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

type Link {
  title String
  url   String
}

model Game {
  id           String    @id @default(auto()) @map("_id") @db.ObjectId
  title        String
  platform     String?
  status       GameStatus
  dateAdded    DateTime  @default(now())
  dateStarted  DateTime?
  dateCompleted DateTime?
  dateFinished DateTime?
  rating       Int?      @db.Int @default(0)
  notes        String?
  coverImage   String?
  tags         String[]
  links        Link[]
  series       String?
  seriesOrder  Int?      @db.Int
  timeSpent    Int?      @db.Int
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
  comments     Comment[]
}

enum GameStatus {
  PLAYING
  COMPLETED
  BACKLOG
  RETIRED
}

model Book {
  id           String    @id @default(auto()) @map("_id") @db.ObjectId
  title        String
  author       String
  isbn         String?
  status       BookStatus
  dateAdded    DateTime  @default(now())
  dateStarted  DateTime?
  dateFinished DateTime?
  rating       Int?      @db.Int @default(0)
  notes        String?
  coverImage   String?
  tags         String[]
  links        Link[]
  series       String?
  seriesOrder  Int?      @db.Int
  timeSpent    Int?      @db.Int
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
  comments     Comment[]
}

enum BookStatus {
  READING
  FINISHED
  TO_READ
  RETIRED
}

model Music {
  id           String    @id @default(auto()) @map("_id") @db.ObjectId
  title        String
  artist       String
  type         MusicType
  status       MusicStatus
  dateAdded    DateTime  @default(now())
  dateStarted  DateTime?
  dateCompleted DateTime?
  dateFinished DateTime?
  rating       Int?      @db.Int @default(0)
  notes        String?
  coverArt     String?
  tags         String[]
  links        Link[]
  timeSpent    Int?      @db.Int
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
  comments     Comment[]
}

enum MusicType {
  ALBUM
  SINGLE
  EP
}

enum MusicStatus {
  LISTENING
  COMPLETED
  WANT_TO_LISTEN
  RETIRED
}

model Art {
  id           String    @id @default(auto()) @map("_id") @db.ObjectId
  title        String
  artist       String
  description  String?
  imageUrl     String
  tags         String[]
  links        Link[]
  dateAdded    DateTime  @default(now())
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
  comments     Comment[]
}

model Show {
  id           String     @id @default(auto()) @map("_id") @db.ObjectId
  title        String
  type         ShowType
  status       ShowStatus
  dateAdded    DateTime   @default(now())
  dateStarted  DateTime?
  dateCompleted DateTime?
  dateFinished DateTime?
  rating       Int?       @db.Int @default(0)
  notes        String?
  coverImage   String?
  tags         String[]
  links        Link[]
  timeSpent    Int?       @db.Int
  createdAt    DateTime   @default(now())
  updatedAt    DateTime   @updatedAt
  comments     Comment[]
}

enum ShowType {
  TV_SERIES
  ANIME
  FILM
  DOCUMENTARY
}

enum ShowStatus {
  WATCHING
  COMPLETED
  WANT_TO_WATCH
  RETIRED
}

model Manga {
  id           String      @id @default(auto()) @map("_id") @db.ObjectId
  title        String
  author       String
  status       MangaStatus
  dateAdded    DateTime    @default(now())
  dateStarted  DateTime?
  dateCompleted DateTime?
  dateFinished DateTime?
  rating       Int?        @db.Int @default(0)
  notes        String?
  coverImage   String?
  tags         String[]
  links        Link[]
  timeSpent    Int?        @db.Int
  createdAt    DateTime    @default(now())
  updatedAt    DateTime    @updatedAt
  comments     Comment[]
}

enum MangaStatus {
  READING
  COMPLETED
  WANT_TO_READ
  RETIRED
}

enum PrimaryBadge {
  STAFF
  MOD
  VIP
  DISCORD
}

model User {
  id            String         @id @default(auto()) @map("_id") @db.ObjectId
  discordId     String         @unique
  username      String
  email         String         @unique
  avatar        String?
  slug          String?
  displayName   String?
  bio           String?
  profilePublic Boolean        @default(true)
  primaryBadge  PrimaryBadge?
  website       String?
  discordServer String?
  bluesky       String?
  github        String?
  linkedin      String?
  twitch        String?
  youtube       String?
  isAdmin       Boolean        @default(false)
  isBanned      Boolean        @default(false)
  inDiscord     Boolean        @default(false)
  isVip         Boolean        @default(false)
  isMod         Boolean        @default(false)
  isStaff       Boolean        @default(false)
  achievementPoints Int         @default(0)
  currentStreak     Int         @default(0)
  lastStreakCheck   DateTime?
  createdAt     DateTime       @default(now())
  updatedAt     DateTime       @updatedAt
  comments         Comment[]
  suggestions      Suggestion[]
  likes            Like[]
  refreshTokens    RefreshToken[]
  reportsMade           ProfileReport[] @relation("Reporter")
  reportsReceived       ProfileReport[] @relation("ReportedUser")
  reportsReviewed       ProfileReport[] @relation("Reviewer")
  commentReportsMade    CommentReport[] @relation("CommentReporter")
  commentReportsReviewed CommentReport[] @relation("CommentReviewer")
  userAchievements      UserAchievement[]

  @@index([slug], map: "User_slug_key")
}

model Comment {
  id           String          @id @default(auto()) @map("_id") @db.ObjectId
  content      String
  rawContent   String?
  userId       String          @db.ObjectId
  user         User            @relation(fields: [userId], references: [id])
  gameId       String?         @db.ObjectId
  game         Game?           @relation(fields: [gameId], references: [id])
  bookId       String?         @db.ObjectId
  book         Book?           @relation(fields: [bookId], references: [id])
  musicId      String?         @db.ObjectId
  music        Music?          @relation(fields: [musicId], references: [id])
  artId        String?         @db.ObjectId
  art          Art?            @relation(fields: [artId], references: [id])
  showId       String?         @db.ObjectId
  show         Show?           @relation(fields: [showId], references: [id])
  mangaId      String?         @db.ObjectId
  manga        Manga?          @relation(fields: [mangaId], references: [id])
  reports      CommentReport[]
  createdAt    DateTime        @default(now())
  updatedAt    DateTime        @updatedAt
}

model AuditLog {
  id           String       @id @default(auto()) @map("_id") @db.ObjectId
  action       AuditAction
  category     AuditCategory
  userId       String?      @db.ObjectId
  targetUserId String?      @db.ObjectId
  resourceType String?
  resourceId   String?
  details      String?
  userAgent    String?
  success      Boolean      @default(true)
  createdAt    DateTime     @default(now())
}

enum AuditAction {
  LOGIN
  LOGOUT
  LOGIN_FAILED
  COMMENT_CREATE
  COMMENT_UPDATE
  COMMENT_DELETE
  ENTRY_CREATE
  ENTRY_UPDATE
  ENTRY_DELETE
  LIKE
  UNLIKE
  USER_BAN
  USER_UNBAN
  RATE_LIMIT_EXCEEDED
  CSRF_VALIDATION_FAILED
  UNAUTHORIZED_ACCESS
  ACHIEVEMENT_UNLOCKED
}

enum AuditCategory {
  AUTH
  CONTENT
  ADMIN
  SECURITY
}

model Suggestion {
  id               String            @id @default(auto()) @map("_id") @db.ObjectId
  userId           String            @db.ObjectId
  user             User              @relation(fields: [userId], references: [id])
  entityType       SuggestionEntity
  status           SuggestionStatus  @default(UNREVIEWED)
  declineReason    String?

  // Data for the suggested item (stored as JSON)
  title            String
  gameData         Json?
  bookData         Json?
  musicData        Json?
  artData          Json?
  showData         Json?
  mangaData        Json?

  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
}

enum SuggestionEntity {
  GAME
  BOOK
  MUSIC
  ART
  SHOW
  MANGA
}

enum SuggestionStatus {
  UNREVIEWED
  ACCEPTED
  DECLINED
}

model Like {
  id           String    @id @default(auto()) @map("_id") @db.ObjectId
  userId       String    @db.ObjectId
  user         User      @relation(fields: [userId], references: [id])
  entityType   String    // 'book', 'game', 'show', 'manga', 'music', 'art'
  entityId     String    @db.ObjectId
  createdAt    DateTime  @default(now())

  @@unique([userId, entityType, entityId])
}

model RefreshToken {
  id           String    @id @default(auto()) @map("_id") @db.ObjectId
  token        String    @unique
  userId       String    @db.ObjectId
  user         User      @relation(fields: [userId], references: [id])
  expiresAt    DateTime
  createdAt    DateTime  @default(now())

  @@index([userId])
  @@index([expiresAt])
}

enum ReportReason {
  INAPPROPRIATE_CONTENT
  HARASSMENT
  SPAM
  IMPERSONATION
  OFFENSIVE_NAME
  MALICIOUS_LINKS
  OTHER
}

enum ReportStatus {
  PENDING
  REVIEWED
  DISMISSED
  ACTION_TAKEN
}

model ProfileReport {
  id             String        @id @default(auto()) @map("_id") @db.ObjectId
  reportedUserId String        @db.ObjectId
  reportedUser   User          @relation("ReportedUser", fields: [reportedUserId], references: [id])
  reporterId     String        @db.ObjectId
  reporter       User          @relation("Reporter", fields: [reporterId], references: [id])
  reason         ReportReason
  details        String
  status         ReportStatus  @default(PENDING)
  reviewedBy     String?       @db.ObjectId
  reviewer       User?         @relation("Reviewer", fields: [reviewedBy], references: [id])
  reviewNotes    String?
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt

  @@index([reportedUserId])
  @@index([reporterId])
  @@index([status])
}

model CommentReport {
  id              String        @id @default(auto()) @map("_id") @db.ObjectId
  reportedCommentId String      @db.ObjectId
  reportedComment Comment       @relation(fields: [reportedCommentId], references: [id], onDelete: Cascade)
  reporterId      String        @db.ObjectId
  reporter        User          @relation("CommentReporter", fields: [reporterId], references: [id])
  reason          ReportReason
  details         String
  status          ReportStatus  @default(PENDING)
  reviewedBy      String?       @db.ObjectId
  reviewer        User?         @relation("CommentReviewer", fields: [reviewedBy], references: [id])
  reviewNotes     String?
  createdAt       DateTime      @default(now())
  updatedAt       DateTime      @updatedAt

  @@index([reportedCommentId])
  @@index([reporterId])
  @@index([status])
}

model UserAchievement {
  id              String      @id @default(auto()) @map("_id") @db.ObjectId
  userId          String      @db.ObjectId
  user            User        @relation(fields: [userId], references: [id])
  achievementKey  String
  progress        Int         @default(0)
  earned          Boolean     @default(false)
  earnedAt        DateTime?
  createdAt       DateTime    @default(now())
  updatedAt       DateTime    @updatedAt

  @@unique([userId, achievementKey])
  @@index([userId])
  @@index([achievementKey])
  @@index([earned])
}
