generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}

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

model User {
  id                     String          @id @default(cuid())
  email                  String          @unique
  username               String          @unique
  passwordhash           String
  createdAt              DateTime        @default(now())
  messages               Message[]
  session                Session[]
  channels               Channel[]       @relation("ChannelToUser")
  Reactions              Reaction[]      @relation("ReactionToUser")
  roles                  Role[]          @relation("RoleToUser")
  servers                Server[]        @relation("ServerToUser")
  incomingFriendRequests friendRequest[] @relation("FriendRequestToUser")
  outgoingFriendRequests friendRequest[] @relation("UserToFriendRequest")
  friends                User[]          @relation("UserToFriends")

  // This second "side" of the UserFriends relation exists solely 
  // to satisfy prisma's requirements; we won't access it directly.
  symmetricFriends User[] @relation("UserToFriends")
}

model friendRequest {
  id          String @id @default(cuid())
  sender      User   @relation(fields: [senderId], references: [id], name: "UserToFriendRequest")
  recipient   User   @relation(fields: [recipientId], references: [id], name: "FriendRequestToUser")
  senderId    String
  recipientId String
  status      String @default("sent")
}

model Server {
  id           String       @id @default(cuid())
  name         String
  createdAt    DateTime     @default(now())
  channels     Channel[]
  InviteCode   InviteCode[]
  roles        Role[]
  participants User[]       @relation("ServerToUser")
}

model Role {
  id            String  @id @default(cuid())
  name          String
  administrator Boolean @default(false)
  owner         Boolean @default(false)
  serverId      String?
  server        Server? @relation(fields: [serverId], references: [id])
  users         User[]  @relation("RoleToUser")
}

model Channel {
  id             String    @id @default(cuid())
  name           String
  serverId       String?
  DM             Boolean   @default(false)
  server         Server?   @relation(fields: [serverId], references: [id])
  messages       Message[]
  dmParticipants User[]    @relation("ChannelToUser")
}

model Message {
  id        String       @id @default(cuid())
  body      String
  userId    String
  channelId String
  createdAt DateTime     @default(now())
  updatedAt DateTime     @updatedAt
  invites   InviteCode[]
  channel   Channel      @relation(fields: [channelId], references: [id])
  creator   User         @relation(fields: [userId], references: [id])
  reactions Reaction[]
}

model InviteCode {
  id         String    @id @default(cuid())
  expires    Boolean   @default(false)
  expiryDate DateTime?
  maxUses    Int       @default(0)
  serverId   String
  messageId  String?
  message    Message?  @relation(fields: [messageId], references: [id])
  server     Server    @relation(fields: [serverId], references: [id])
}

model Session {
  id     String @id @default(cuid())
  token  String @unique
  userId String
  user   User   @relation(fields: [userId], references: [id])
}

model Reaction {
  id        String   @id @default(cuid())
  emoji     String
  // count     Int
  messageId String?
  Message   Message? @relation(fields: [messageId], references: [id])
  users     User[]   @relation("ReactionToUser")

  @@unique([emoji, messageId])
}
