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

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

enum RoleScope {
  SYSTEM
  ROOM
}

enum FriendStatus {
  PENDING
  ACCEPTED
  DECLINED
  BLOCKED
}

enum RoomVisibility {
  PUBLIC
  FRIENDS
  ROLE_RESTRICTED
  EXPLICIT
}

enum MediaProvider {
  YOUTUBE
  TWITCH
  DIRECT
  UNKNOWN
}

model User {
  id           String        @id @default(cuid())
  username     String        @unique
  passwordHash String
  displayName  String?
  createdAt    DateTime      @default(now())
  updatedAt    DateTime      @updatedAt
  roles        UserRole[]
  ownedRooms   Room[]        @relation("RoomOwner")
  sentFriends  Friendship[]  @relation("FriendRequester")
  gotFriends   Friendship[]  @relation("FriendReceiver")
  roomMembers  RoomMember[]
  submitted    MediaSource[]
}

model Role {
  id          String           @id @default(cuid())
  name        String           @unique
  description String?
  scope       RoleScope        @default(SYSTEM)
  createdAt   DateTime         @default(now())
  users       UserRole[]
  permissions RolePermission[]
}

model Permission {
  id          String           @id @default(cuid())
  key         String           @unique
  description String?
  roles       RolePermission[]
}

model UserRole {
  userId String
  roleId String
  user   User   @relation(fields: [userId], references: [id], onDelete: Cascade)
  role   Role   @relation(fields: [roleId], references: [id], onDelete: Cascade)

  @@id([userId, roleId])
}

model RolePermission {
  roleId       String
  permissionId String
  role         Role       @relation(fields: [roleId], references: [id], onDelete: Cascade)
  permission   Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)

  @@id([roleId, permissionId])
}

model Friendship {
  id          String       @id @default(cuid())
  requesterId String
  receiverId  String
  status      FriendStatus @default(PENDING)
  createdAt   DateTime     @default(now())
  updatedAt   DateTime     @updatedAt
  requester   User         @relation("FriendRequester", fields: [requesterId], references: [id], onDelete: Cascade)
  receiver    User         @relation("FriendReceiver", fields: [receiverId], references: [id], onDelete: Cascade)

  @@unique([requesterId, receiverId])
}

model Room {
  id            String          @id @default(cuid())
  slug          String          @unique
  name          String
  ownerId       String?
  visibility    RoomVisibility  @default(FRIENDS)
  currentState  Json?
  createdAt     DateTime        @default(now())
  updatedAt     DateTime        @updatedAt
  owner         User?           @relation("RoomOwner", fields: [ownerId], references: [id], onDelete: SetNull)
  members       RoomMember[]
  mediaSources  MediaSource[]
}

model RoomMember {
  roomId    String
  userId    String
  canManage Boolean @default(false)
  room      Room    @relation(fields: [roomId], references: [id], onDelete: Cascade)
  user      User    @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@id([roomId, userId])
}

model MediaSource {
  id          String        @id @default(cuid())
  roomId      String
  submitterId String?
  provider    MediaProvider
  originalUrl String
  playbackUrl String
  title       String?
  createdAt   DateTime      @default(now())
  room        Room          @relation(fields: [roomId], references: [id], onDelete: Cascade)
  submitter   User?         @relation(fields: [submitterId], references: [id], onDelete: SetNull)
}
