generator client {
  provider      = "prisma-client-js"
  output        = "../app/generated/prisma"
  binaryTargets = ["native", "windows", "linux-musl", "debian-openssl-1.0.x"]
}

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

model AcademicYear {
  id          String             @id @default(uuid())
  startYear   Int
  endYear     Int
  isCurrent   Boolean            @default(false)
  createdAt   DateTime           @default(now())
  updatedAt   DateTime           @updatedAt
  assessments Assessment[]
  exams       Exam[]
  results     Result[]
  promotions  StudentPromotion[]

  @@unique([startYear, endYear])
}

model StudentPromotion {
  id                String          @id @default(uuid())
  studentId         String
  academicYearId    String
  fromGradeId       String
  toGradeId         String?
  firstSemesterAvg  Float?
  secondSemesterAvg Float?
  overallAverage    Float?
  passedSubjects    Int?
  failedSubjects    Int?
  totalSubjects     Int?
  status            PromotionStatus @default(PENDING)
  promotedAt        DateTime?
  remarks           String?
  createdAt         DateTime        @default(now())
  updatedAt         DateTime        @updatedAt
  academicYear      AcademicYear    @relation(fields: [academicYearId], references: [id])
  fromGrade         Grade           @relation("FromGrade", fields: [fromGradeId], references: [id])
  student           Student         @relation(fields: [studentId], references: [id])
  toGrade           Grade?          @relation("ToGrade", fields: [toGradeId], references: [id])

  @@unique([studentId, academicYearId])
}

model User {
  id                String   @id @default(uuid())
  username          String   @unique
  email             String?  @unique
  password          String
  role              role
  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt
  isPasswordChanged Boolean  @default(false)
  admin             Admin?   @relation("UserAdmin")
  student           Student? @relation("UserStudent")
  teacher           Teacher? @relation("UserTeacher")
}

model Admin {
  id          String     @id @default(uuid())
  firstName   String
  middleName  String
  lastName    String
  sex         UserSex?
  phone       String?
  nationality String
  region      String
  zone        String
  woreda      String
  city        String?
  kebele      String?
  img         String?
  status      UserStatus @default(ACTIVE)
  createdAt   DateTime   @default(now())
  updatedAt   DateTime   @updatedAt
  userId      String?    @unique
  user        User?      @relation("UserAdmin", fields: [userId], references: [id])
}

model Teacher {
  id          String         @id @default(uuid())
  userId      String?        @unique
  firstName   String
  middleName  String
  lastName    String
  sex         UserSex?
  phone       String?
  nationality String
  region      String
  zone        String
  woreda      String
  city        String?
  img         String?
  status      UserStatus     @default(ACTIVE)
  createdAt   DateTime       @default(now())
  updatedAt   DateTime       @updatedAt
  subjects    ClassSubject[]
  user        User?          @relation("UserTeacher", fields: [userId], references: [id])
}

model Student {
  id           String             @id @default(uuid())
  userId       String?            @unique
  firstName    String
  middleName   String
  lastName     String
  phone        String?
  sex          UserSex?
  birthday     DateTime
  nationality  String
  region       String
  zone         String
  woreda       String
  city         String?
  kebele       String?
  img          String?
  status       UserStatus         @default(ACTIVE)
  gradeId      String
  classId      String
  createdAt    DateTime           @default(now())
  updatedAt    DateTime           @updatedAt
  results      Result[]
  class        Class              @relation(fields: [classId], references: [id])
  grade        Grade              @relation(fields: [gradeId], references: [id])
  user         User?              @relation("UserStudent", fields: [userId], references: [id], onDelete: Cascade)
  studentExams StudentExam[]
  promotions   StudentPromotion[]
}

model Grade {
  id             String             @id @default(uuid())
  level          Int                @unique
  createdAt      DateTime           @default(now())
  updatedAt      DateTime           @updatedAt
  classes        Class[]
  students       Student[]
  promotionsFrom StudentPromotion[] @relation("FromGrade")
  promotionsTo   StudentPromotion[] @relation("ToGrade")
}

model Class {
  id        String         @id @default(uuid())
  name      String         @unique
  gradeId   String
  createdAt DateTime       @default(now())
  updatedAt DateTime       @updatedAt
  grade     Grade          @relation(fields: [gradeId], references: [id])
  subjects  ClassSubject[]
  ExamClass ExamClass[]
  students  Student[]
}

model Subject {
  id          String         @id @default(uuid())
  name        String
  createdAt   DateTime       @default(now())
  updatedAt   DateTime       @updatedAt
  assessments Assessment[]   @relation("AssessmentSubject")
  classes     ClassSubject[]
  exams       Exam[]
}

model ClassSubject {
  id        String  @id @default(uuid())
  classId   String
  subjectId String
  teacherId String
  class     Class   @relation(fields: [classId], references: [id])
  subject   Subject @relation(fields: [subjectId], references: [id])
  teacher   Teacher @relation(fields: [teacherId], references: [id])

  @@unique([classId, subjectId])
}

model Exam {
  id             String         @id @default(uuid())
  title          String
  date           DateTime?
  startTime      DateTime?
  endTime        DateTime?
  duration       Int?
  value          Int?
  status         ExamStatus     @default(DRAFT)
  semester       Semester
  academicYearId String
  subjectId      String
  createdAt      DateTime       @default(now())
  updatedAt      DateTime       @updatedAt
  academicYear   AcademicYear   @relation(fields: [academicYearId], references: [id])
  subject        Subject        @relation(fields: [subjectId], references: [id])
  ExamClass      ExamClass[]
  questions      ExamQuestion[]
  results        Result[]
  studentExams   StudentExam[]
}

model ExamQuestion {
  id             String          @id @default(uuid())
  examId         String
  question       String
  type           QuestionType    @default(MULTIPLE_CHOICE)
  options        String?
  correctAnswer  String?
  value          Int?            @default(1)
  createdAt      DateTime        @default(now())
  updatedAt      DateTime        @updatedAt
  exam           Exam            @relation(fields: [examId], references: [id])
  studentAnswers StudentAnswer[]
}

model StudentExam {
  id               String          @id @default(uuid())
  examId           String
  studentId        String
  startTime        DateTime?
  endTime          DateTime?
  status           StudExamStatus
  totalScore       Int?
  timeSpent        Int?
  maxPossibleScore Int?
  activeSessionId  String?
  lastActive       DateTime?
  answers          StudentAnswer[]
  exam             Exam            @relation(fields: [examId], references: [id])
  student          Student         @relation(fields: [studentId], references: [id])

  @@unique([examId, studentId])
}

model StudentAnswer {
  id            String       @id @default(uuid())
  studentExamId String
  questionId    String
  answer        String?
  isCorrect     Boolean?
  pointsEarned  Int?
  skipped       Boolean      @default(false)
  answeredAt    DateTime     @default(now())
  status        AnswerStatus @default(NOT_ANSWERED)
  question      ExamQuestion @relation(fields: [questionId], references: [id])
  studentExam   StudentExam  @relation(fields: [studentExamId], references: [id])

  @@unique([studentExamId, questionId])
}

model Assessment {
  id             String       @id @default(uuid())
  title          String
  dueDate        DateTime
  value          Int?         @default(1)
  semester       Semester
  academicYearId String
  subjectId      String
  classId        String
  assessmentType String       @default("ASSIGNMENT")
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  academicYear   AcademicYear @relation(fields: [academicYearId], references: [id])
  subject        Subject      @relation("AssessmentSubject", fields: [subjectId], references: [id])
  results        Result[]
}

model Result {
  id             String       @id @default(uuid())
  studentId      String
  examId         String?
  assessmentId   String?
  semester       Semester
  academicYearId String
  score          Int?
  maxScore       Int?
  percentage     Float?
  grade          String?
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  gradeLevel     Int?
  classId        String?
  academicYear   AcademicYear @relation(fields: [academicYearId], references: [id])
  assessment     Assessment?  @relation(fields: [assessmentId], references: [id])
  exam           Exam?        @relation(fields: [examId], references: [id])
  student        Student      @relation(fields: [studentId], references: [id])

  @@unique([studentId, examId])
}

model ExamClass {
  id      String @id @default(uuid())
  examId  String
  classId String
  class   Class  @relation(fields: [classId], references: [id])
  exam    Exam   @relation(fields: [examId], references: [id])

  @@unique([examId, classId])
}

model ServiceStatus {
  id        String    @id @default(uuid())
  isRunning Boolean   @default(true)
  pausedAt  DateTime?
  resumedAt DateTime?
  message   String?
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
}

enum UserSex {
  MALE
  FEMALE
}

enum role {
  admin
  teacher
  student
  superadmin
  head
}

enum UserStatus {
  ACTIVE
  INACTIVE
  STOPPED
}

enum ExamStatus {
  DRAFT
  READY
  ONGOING
  FINISHED
}

enum QuestionType {
  MULTIPLE_CHOICE
  TRUE_FALSE
}

enum Semester {
  FIRST
  SECOND
}

enum PromotionStatus {
  PROMOTED
  RETAINED
  PENDING
}

enum StudExamStatus {
  NOT_STARTED
  IN_PROGRESS
  PAUSED
  FINISHED
}

enum AnswerStatus {
  NOT_ANSWERED
  ANSWERED
  REVIEW
}
