// ============================================================
//  Sistem Informasi Pendaftaran Mahasiswa Baru (PMB)
//  Prisma Schema — MySQL
// ============================================================

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

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

// ============================================================
//  ENUMS
// ============================================================

enum Role {
  student
  admin
  super_admin
}

enum Jurusan {
  Teknik_Informatika
  Sistem_Informasi
  Manajemen
  Akuntansi
}

enum DocumentType {
  ktp
  ijazah
  kk
  foto
  sehat
  skl
  raport
}

enum StatusPendaftaran {
  pending
  processing
  accepted
  rejected
}

enum PaymentStatus {
  pending
  paid
  failed
}

enum RegStatus {
  draft
  submitted
  under_review
  approved
  rejected
}

enum SenderType {
  student
  admin
}

// ============================================================
//  MODELS
// ============================================================

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique @db.VarChar(255)
  password  String   @db.VarChar(255)
  role      Role     @default(student)
  nim       String?  @db.VarChar(20)
  isActive  Boolean  @default(true) @map("is_active")
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  profile               Profile?
  educationHistory      EducationHistory[]
  documents             Document[]
  payments              Payment[]
  registrationStatus    RegistrationStatus?
  passwordResets        PasswordReset[]
  activities            Activity[]
  messages              Message[]
  notifications         Notification[]
  verifiedDocuments     Document[]        @relation("DocumentVerifier")
  updatedRegistrations  RegistrationStatus[] @relation("RegistrationUpdater")

  @@index([role], map: "idx_users_role")
  @@map("users")
}

model Profile {
  id                Int               @id @default(autoincrement())
  userId            Int               @unique @map("user_id")
  fullName          String            @db.VarChar(255)
  phoneNumber       String?           @db.VarChar(20)
  address           String?
  asalSekolah       String?           @db.VarChar(255)
  jurusan           Jurusan?
  statusPendaftaran StatusPendaftaran @default(pending) @map("status_pendaftaran")
  angkatan          Int?
  tempatLahir       String?           @db.VarChar(255) @map("tempat_lahir")
  tanggalLahir      DateTime?         @db.Date @map("tanggal_lahir")
  jenisKelamin      String?           @db.VarChar(20) @map("jenis_kelamin")
  createdAt         DateTime          @default(now()) @map("created_at")
  updatedAt         DateTime          @updatedAt @map("updated_at")

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

  @@map("profiles")
}

model EducationHistory {
  id          Int      @id @default(autoincrement())
  userId      Int      @map("user_id")
  jenjang     String?
  namaSekolah String?
  tahunLulus  Int?
  nilaiUjian  Float?
  createdAt   DateTime @default(now()) @map("created_at")

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

  @@index([userId], map: "idx_edu_user")
  @@map("education_history")
}

model Document {
  id            Int          @id @default(autoincrement())
  userId        Int          @map("user_id")
  documentType  DocumentType
  originalName  String?      @db.VarChar(255)
  filePath      String       @db.VarChar(255)
  fileSize      Int?         @map("file_size")
  mimeType      String?      @db.VarChar(100)
  isVerified    Boolean      @default(false) @map("is_verified")
  adminNote     String?
  verifiedById  Int?         @map("verified_by")
  verifiedAt    DateTime?    @map("verified_at")
  createdAt     DateTime     @default(now()) @map("created_at")
  updatedAt     DateTime     @updatedAt @map("updated_at")

  user     User   @relation(fields: [userId], references: [id], onDelete: Cascade)
  verifier User?  @relation("DocumentVerifier", fields: [verifiedById], references: [id], onDelete: SetNull)

  @@unique([userId, documentType], map: "uk_doc_user_type")
  @@map("documents")
}

model Payment {
  id            Int           @id @default(autoincrement())
  userId        Int           @map("user_id")
  amount        Decimal       @db.Decimal(10, 2)
  paymentStatus PaymentStatus @default(pending) @map("payment_status")
  paymentMethod String?       @db.VarChar(50)
  transactionId String?       @db.VarChar(100)
  paidAt        DateTime?
  createdAt     DateTime      @default(now()) @map("created_at")
  updatedAt     DateTime      @updatedAt @map("updated_at")

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

  @@index([userId], map: "idx_pay_user")
  @@map("payments")
}

model RegistrationStatus {
  id                 Int       @id @default(autoincrement())
  userId             Int       @unique @map("user_id")
  status             RegStatus @default(draft)
  lastStepCompleted  Int       @default(0) @map("last_step_completed")
  adminComment       String?
  updatedById        Int?      @map("updated_by")
  updatedAt          DateTime  @updatedAt @map("updated_at")

  user    User   @relation(fields: [userId], references: [id], onDelete: Cascade)
  updater User?  @relation("RegistrationUpdater", fields: [updatedById], references: [id], onDelete: SetNull)

  @@map("registration_status")
}

model PasswordReset {
  id        Int      @id @default(autoincrement())
  email     String   @db.VarChar(255)
  token     String   @db.VarChar(255)
  expiresAt DateTime @map("expires_at")
  used      Boolean  @default(false)
  createdAt DateTime @default(now()) @map("created_at")

  @@index([email], map: "idx_reset_email")
  @@index([token], map: "idx_reset_token")
  @@index([expiresAt], map: "idx_reset_expires")
  @@map("password_resets")
}

model Activity {
  id          Int      @id @default(autoincrement())
  userId      Int?
  description String
  status      String?  @db.VarChar(20)
  createdAt   DateTime @default(now()) @map("created_at")

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

  @@index([createdAt], map: "idx_act_created")
  @@map("activities")
}

model Announcement {
  id        Int      @id @default(autoincrement())
  title     String   @db.VarChar(255)
  body      String   @db.Text
  author    String?  @db.VarChar(100)
  pinned    Boolean  @default(false)
  published Boolean  @default(true)
  date      DateTime @default(now()) @db.Timestamp
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  @@map("announcements")
}

model Message {
  id         Int        @id @default(autoincrement())
  userId     Int        @map("user_id")
  adminId    Int?       @map("admin_id")
  message    String     @db.Text
  senderType SenderType @map("sender_type")
  createdAt  DateTime   @default(now()) @map("created_at")

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

  @@index([userId], map: "idx_msg_user")
  @@index([createdAt], map: "idx_msg_created")
  @@map("messages")
}

model Notification {
  id        Int      @id @default(autoincrement())
  userId    Int      @map("user_id")
  title     String   @db.VarChar(255)
  message   String   @db.Text
  isRead    Boolean  @default(false) @map("is_read")
  createdAt DateTime @default(now()) @map("created_at")

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

  @@index([userId, isRead], map: "idx_notif_user_read")
  @@map("notifications")
}

model Settings {
  id        Int      @id @default(autoincrement())
  key       String   @unique @db.VarChar(100)
  value     String?  @db.Text
  updatedAt DateTime @updatedAt @map("updated_at")

  @@map("settings")
}

model Program {
  id           Int      @id @default(autoincrement())
  name         String   @db.VarChar(255)
  accreditation String? @db.VarChar(50)
  description  String?  @db.Text
  quota        Int      @default(0)
  isActive     Boolean  @default(true) @map("is_active")
  createdAt    DateTime @default(now()) @map("created_at")
  updatedAt    DateTime @updatedAt @map("updated_at")

  @@map("programs")
}
