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

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

model User {
  id            Int       @id @default(autoincrement())
  username      String?   @unique
  name          String
  email         String    @unique
  emailVerified DateTime?
  image         String?
  description   String?   @db.VarChar(256)

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

  usernameUpdatedAt DateTime?
  imageUpdatedAt    DateTime?

  accounts Account[]
  sessions Session[]
  miis     Mii[]
  likes    Like[]

  reportsAuthored Report[]     @relation("ReportAuthor")
  reports         Report[]     @relation("ReportTargetCreator")
  punishments     Punishment[]

  @@map("users")
}

model Account {
  userId            Int
  type              String
  provider          String
  providerAccountId String
  refresh_token     String?
  access_token      String?
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String?
  session_state     String?

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

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@id([provider, providerAccountId])
  @@map("accounts")
}

model Session {
  sessionToken String   @unique
  userId       Int
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)

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

  @@map("sessions")
}

model Mii {
  id          Int      @id @default(autoincrement())
  userId      Int
  name        String   @db.VarChar(64)
  imageCount  Int      @default(0)
  tags        String[]
  description String?  @db.VarChar(256)

  firstName      String
  lastName       String
  gender         MiiGender?
  islandName     String
  allowedCopying Boolean?

  createdAt DateTime @default(now())

  user    User   @relation(fields: [userId], references: [id], onDelete: Cascade)
  likedBy Like[]

  punishmentId Int?
  punishments  MiiPunishment[]

  @@map("miis")
}

model Like {
  userId Int
  miiId  Int

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  mii  Mii  @relation(fields: [miiId], references: [id], onDelete: Cascade)

  @@id([userId, miiId])
  @@map("likes")
}

model Report {
  id         Int          @id @default(autoincrement())
  reportType ReportType
  status     ReportStatus @default(OPEN)
  targetId   Int

  reason      ReportReason
  reasonNotes String?

  createdAt DateTime @default(now())

  // note: this refers to the person who made the report
  authorId  Int?
  author    User? @relation("ReportAuthor", fields: [authorId], references: [id])
  creatorId Int?
  creator   User? @relation("ReportTargetCreator", fields: [creatorId], references: [id])

  @@map("reports")
}

model MiiPunishment {
  punishmentId Int
  miiId        Int
  reason       String

  punishment Punishment @relation(fields: [punishmentId], references: [id], onDelete: Cascade)
  mii        Mii        @relation(fields: [miiId], references: [id], onDelete: Cascade)

  @@id([punishmentId, miiId])
  @@map("mii_punishments")
}

model Punishment {
  id       Int            @id @default(autoincrement())
  userId   Int
  type     PunishmentType
  returned Boolean        @default(false)

  notes         String
  reasons       String[]
  violatingMiis MiiPunishment[]

  expiresAt DateTime?
  createdAt DateTime  @default(now())

  user User @relation(fields: [userId], references: [id])

  @@map("punishments")
}

enum MiiGender {
  MALE
  FEMALE
}

enum ReportType {
  MII
  USER
}

enum ReportReason {
  INAPPROPRIATE
  SPAM
  COPYRIGHT
  OTHER
}

enum ReportStatus {
  OPEN
  RESOLVED
  DISMISSED
}

enum PunishmentType {
  WARNING
  TEMP_EXILE
  PERM_EXILE
}
