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

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

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

model Song {
  id        Int      @id @default(autoincrement())
  title     String
  artist    String
  filename  String   // Filename in public/uploads
  coverImage String?  // Filename in public/uploads/covers
  releaseYear Int?   // Release year from iTunes
  createdAt DateTime @default(now())
  puzzles   DailyPuzzle[]
  genres    Genre[]
  specials  SpecialSong[]
  averageRating Float    @default(0)
  ratingCount   Int      @default(0)
  excludeFromGlobal Boolean @default(false)
}

model Genre {
  id    Int    @id @default(autoincrement())
  name  Json   // Multilingual: { "de": "Rock", "en": "Rock" }
  subtitle Json? // Multilingual
  active   Boolean @default(true)
  songs Song[]
  dailyPuzzles DailyPuzzle[]
  curatorGenres CuratorGenre[]
  comments CuratorComment[]
}

model Special {
  id          Int           @id @default(autoincrement())
  name        Json          // Multilingual
  subtitle    Json?         // Multilingual
  maxAttempts Int           @default(7)
  unlockSteps String // JSON string: e.g. "[2, 4, 7, 11, 16, 30]"
  createdAt   DateTime      @default(now())
  launchDate  DateTime?
  endDate     DateTime?
  curator     String?
  hidden      Boolean       @default(false)
  songs       SpecialSong[]
  puzzles     DailyPuzzle[]
  news        News[]
  curatorSpecials CuratorSpecial[]
}

model SpecialSong {
  id        Int     @id @default(autoincrement())
  specialId Int
  special   Special @relation(fields: [specialId], references: [id], onDelete: Cascade)
  songId    Int
  song      Song    @relation(fields: [songId], references: [id], onDelete: Cascade)
  startTime Int     @default(0) // Start time in seconds
  order     Int?    // For manual ordering

  @@unique([specialId, songId])
}

model DailyPuzzle {
  id        Int      @id @default(autoincrement())
  date      String   // Format: YYYY-MM-DD
  songId    Int
  song      Song     @relation(fields: [songId], references: [id], onDelete: Cascade)
  genreId   Int?
  genre     Genre?   @relation(fields: [genreId], references: [id])
  specialId Int?
  special   Special? @relation(fields: [specialId], references: [id])
  comments  CuratorComment[]

  @@unique([date, genreId, specialId])
}

model News {
  id          Int      @id @default(autoincrement())
  title       Json     // Multilingual
  content     Json     // Multilingual
  author      String?  // Optional: curator/admin name
  publishedAt DateTime @default(now())
  updatedAt   DateTime @updatedAt
  featured    Boolean  @default(false) // Highlight important news
  specialId   Int?     // Optional: link to a special
  special     Special? @relation(fields: [specialId], references: [id], onDelete: SetNull)
  
  @@index([publishedAt])
}

model PlayerState {
  id          Int      @id @default(autoincrement())
  identifier  String   // UUID des Spielers (für Cross-Domain-Sync)
  genreKey    String   // Genre-Name oder "global" oder "special:<name>"
  gameState   String   // JSON-String des GameState
  statistics  String   // JSON-String der Statistics
  lastPlayed  DateTime @updatedAt
  createdAt   DateTime @default(now())
  
  @@unique([identifier, genreKey])
  @@index([identifier])
}

model Curator {
  id              Int              @id @default(autoincrement())
  username        String           @unique
  passwordHash    String
  isGlobalCurator Boolean         @default(false)
  createdAt       DateTime         @default(now())
  updatedAt       DateTime         @updatedAt

  genres          CuratorGenre[]
  specials        CuratorSpecial[]
  commentRecipients CuratorCommentRecipient[]
}

model CuratorGenre {
  id        Int     @id @default(autoincrement())
  curatorId Int
  genreId   Int

  curator   Curator @relation(fields: [curatorId], references: [id], onDelete: Cascade)
  genre     Genre   @relation(fields: [genreId], references: [id], onDelete: Cascade)

  @@unique([curatorId, genreId])
}

model CuratorSpecial {
  id        Int     @id @default(autoincrement())
  curatorId Int
  specialId Int

  curator   Curator @relation(fields: [curatorId], references: [id], onDelete: Cascade)
  special   Special @relation(fields: [specialId], references: [id], onDelete: Cascade)

  @@unique([curatorId, specialId])
}

model PoliticalStatement {
  id        Int      @id @default(autoincrement())
  locale    String
  text      String
  active    Boolean  @default(true)
  source    String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([locale, active])
}

model CuratorComment {
  id              Int                         @id @default(autoincrement())
  playerIdentifier String
  puzzleId        Int
  puzzle          DailyPuzzle                 @relation(fields: [puzzleId], references: [id], onDelete: Cascade)
  genreId         Int?
  genre           Genre?                      @relation(fields: [genreId], references: [id], onDelete: SetNull)
  message         String
  createdAt       DateTime                    @default(now())
  
  recipients      CuratorCommentRecipient[]

  @@unique([playerIdentifier, puzzleId])
  @@index([genreId])
}

model CuratorCommentRecipient {
  id        Int            @id @default(autoincrement())
  commentId Int
  comment   CuratorComment @relation(fields: [commentId], references: [id], onDelete: Cascade)
  curatorId Int
  curator   Curator        @relation(fields: [curatorId], references: [id], onDelete: Cascade)
  readAt    DateTime?
  archived  Boolean        @default(false)

  @@unique([commentId, curatorId])
  @@index([curatorId])
}
