// Refer to the Prisma schema docs: https://pris.ly/d/prisma-schema

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["interactiveTransactions"]
}

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

// Necessary for NextAuth.
model Account {
  id                String  @id @default(cuid())
  userId            String
  type              String
  provider          String
  providerAccountId String
  refresh_token     String? @db.Text
  access_token      String? @db.Text
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String? @db.Text
  session_state     String?
  user              User    @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

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

model User {
  id                            String                         @id @default(cuid())
  name                          String?
  email                         String?                        @unique
  emailVerified                 DateTime?
  image                         String?
  accounts                      Account[]
  sessions                      Session[]
  todos                         Todo[]
  resumesResumes                ResumesResume[]
  resumesStars                  ResumesStar[]
  resumesComments               ResumesComment[]
  resumesCommentVotes           ResumesCommentVote[]
  questionsQuestions            QuestionsQuestion[]
  questionsQuestionEncounters   QuestionsQuestionEncounter[]
  questionsQuestionVotes        QuestionsQuestionVote[]
  questionsQuestionComments     QuestionsQuestionComment[]
  questionsQuestionCommentVotes QuestionsQuestionCommentVote[]
  questionsAnswers              QuestionsAnswer[]
  questionsAnswerVotes          QuestionsAnswerVote[]
  questionsAnswerComments       QuestionsAnswerComment[]
  questionsAnswerCommentVotes   QuestionsAnswerCommentVote[]
  OffersProfile                 OffersProfile[]
  offersDiscussion              OffersReply[]
  questionsLists                QuestionsList[]
}

enum Vote {
  UPVOTE
  DOWNVOTE
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime

  @@unique([identifier, token])
}

model Todo {
  id        String     @id @default(cuid())
  userId    String
  text      String     @db.Text
  status    TodoStatus @default(INCOMPLETE)
  createdAt DateTime   @default(now())
  updatedAt DateTime   @updatedAt
  user      User       @relation(fields: [userId], references: [id], onDelete: Cascade)
}

enum TodoStatus {
  INCOMPLETE
  COMPLETE
}

model Company {
  id          String   @id @default(cuid())
  name        String   @db.Text
  slug        String   @unique
  description String?  @db.Text
  logoUrl     String?
  website     String?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  questionsQuestionEncounter QuestionsQuestionEncounter[]
  OffersExperience           OffersExperience[]
  OffersOffer                OffersOffer[]
}

model Country {
  id                          String                       @id
  name                        String                       @unique
  code                        String                       @unique
  // The higher the value of the ranking, the higher it appears in the search results.
  ranking                     Int?                         @default(0)
  states                      State[]
  questionsQuestionEncounters QuestionsQuestionEncounter[]
  ResumesResume               ResumesResume[]
}

model State {
  id                          String                       @id
  name                        String
  countryId                   String
  cities                      City[]
  country                     Country                      @relation(fields: [countryId], references: [id])
  questionsQuestionEncounters QuestionsQuestionEncounter[]

  @@unique([name, countryId])
}

model City {
  id                          String                       @id
  name                        String
  stateId                     String
  state                       State                        @relation(fields: [stateId], references: [id])
  questionsQuestionEncounters QuestionsQuestionEncounter[]
  OffersExperience            OffersExperience[]
  OffersOffer                 OffersOffer[]

  @@unique([name, stateId])
}

// Start of Resumes project models.
// Add Resumes project models here, prefix all models with "Resumes",
// use camelCase for field names, and try to name them consistently
// across all models in this file.
model ResumesResume {
  id             String           @id @default(cuid())
  userId         String
  title          String           @db.Text
  // TODO: Update role, experience, location to use Enums
  role           String           @db.Text
  experience     String           @db.Text
  locationId     String
  url            String
  additionalInfo String?          @db.Text
  isResolved     Boolean          @default(false)
  createdAt      DateTime         @default(now())
  updatedAt      DateTime         @updatedAt
  user           User             @relation(fields: [userId], references: [id], onDelete: Cascade)
  location       Country          @relation(fields: [locationId], references: [id], onDelete: Cascade)
  stars          ResumesStar[]
  comments       ResumesComment[]
}

model ResumesStar {
  id        String        @id @default(cuid())
  userId    String
  resumeId  String
  createdAt DateTime      @default(now())
  resume    ResumesResume @relation(fields: [resumeId], references: [id], onDelete: Cascade)
  user      User          @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([userId, resumeId])
}

model ResumesComment {
  id          String               @id @default(cuid())
  userId      String
  resumeId    String
  parentId    String?
  description String               @db.Text
  section     ResumesSection
  createdAt   DateTime             @default(now())
  updatedAt   DateTime             @updatedAt
  resume      ResumesResume        @relation(fields: [resumeId], references: [id], onDelete: Cascade)
  votes       ResumesCommentVote[]
  user        User                 @relation(fields: [userId], references: [id], onDelete: Cascade)
  parent      ResumesComment?      @relation("parentComment", fields: [parentId], references: [id])
  children    ResumesComment[]     @relation("parentComment")
}

enum ResumesSection {
  GENERAL
  EDUCATION
  EXPERIENCE
  PROJECTS
  SKILLS
}

model ResumesCommentVote {
  id        String         @id @default(cuid())
  userId    String
  commentId String
  value     Vote
  createdAt DateTime       @default(now())
  updatedAt DateTime       @updatedAt
  comment   ResumesComment @relation(fields: [commentId], references: [id], onDelete: Cascade)
  user      User           @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([userId, commentId])
}

// End of Resumes project models.

// Start of Offers project models.
// Add Offers project models here, prefix all models with "Offer",
// use camelCase for field names, and try to name them consistently
// across all models in this file.

model OffersProfile {
  id          String   @id @default(cuid())
  profileName String   @unique
  createdAt   DateTime @default(now())

  background OffersBackground?

  editToken String

  discussion OffersReply[]

  offers OffersOffer[]

  users User[]

  analysis OffersAnalysis?
}

model OffersBackground {
  id String @id @default(cuid())

  totalYoe     Int                 @default(0)
  specificYoes OffersSpecificYoe[]

  experiences OffersExperience[]

  educations OffersEducation[]

  profile         OffersProfile @relation(fields: [offersProfileId], references: [id], onDelete: Cascade)
  offersProfileId String        @unique
}

model OffersSpecificYoe {
  id String @id @default(cuid())

  yoe    Int
  domain String

  background   OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
  backgroundId String
}

model OffersExperience {
  id String @id @default(cuid())

  company   Company? @relation(fields: [companyId], references: [id])
  companyId String?

  jobType JobType?
  title   String?

  // Add more fields
  durationInMonths Int?
  location         City?   @relation(fields: [cityId], references: [id])
  cityId           String?

  // FULLTIME fields
  level               String?
  totalCompensation   OffersCurrency? @relation("ExperienceTotalCompensation", fields: [totalCompensationId], references: [id])
  totalCompensationId String?         @unique

  // INTERN fields
  monthlySalary   OffersCurrency? @relation("ExperienceMonthlySalary", fields: [monthlySalaryId], references: [id])
  monthlySalaryId String?         @unique

  background   OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
  backgroundId String
}

model OffersCurrency {
  id        String   @id @default(cuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  value    Float
  currency String

  baseValue    Float
  baseCurrency String @default("USD")

  // Experience
  OffersExperienceTotalCompensation OffersExperience? @relation("ExperienceTotalCompensation")
  OffersExperienceMonthlySalary     OffersExperience? @relation("ExperienceMonthlySalary")

  // Full Time
  OffersTotalCompensation OffersFullTime? @relation("OfferTotalCompensation")
  OffersBaseSalary        OffersFullTime? @relation("OfferBaseSalary")
  OffersBonus             OffersFullTime? @relation("OfferBonus")
  OffersStocks            OffersFullTime? @relation("OfferStocks")

  // Intern
  OffersMonthlySalary OffersIntern?
}

enum JobType {
  INTERN
  FULLTIME
}

model OffersEducation {
  id    String  @id @default(cuid())
  type  String?
  field String?

  school    String?
  startDate DateTime?
  endDate   DateTime?

  background   OffersBackground @relation(fields: [backgroundId], references: [id], onDelete: Cascade)
  backgroundId String
}

model OffersReply {
  id        String   @id @default(cuid())
  createdAt DateTime @default(now())
  message   String

  replyingToId String?
  replyingTo   OffersReply?  @relation("ReplyThread", fields: [replyingToId], references: [id])
  replies      OffersReply[] @relation("ReplyThread")

  profile   OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
  profileId String

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

model OffersOffer {
  id String @id @default(cuid())

  profile   OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
  profileId String

  company   Company @relation(fields: [companyId], references: [id])
  companyId String

  location            City     @relation(fields: [cityId], references: [id])
  cityId              String
  monthYearReceived   DateTime
  negotiationStrategy String
  comments            String

  jobType JobType

  offersIntern   OffersIntern? @relation(fields: [offersInternId], references: [id], onDelete: Cascade)
  offersInternId String?       @unique

  offersFullTime   OffersFullTime? @relation(fields: [offersFullTimeId], references: [id], onDelete: Cascade)
  offersFullTimeId String?         @unique

  offersAnalysis     OffersAnalysis?      @relation("HighestOverallOffer")
  offersAnalysisUnit OffersAnalysisUnit[]
  OffersAnalysisUnit OffersAnalysisUnit[] @relation("Analysed Offer")
}

model OffersIntern {
  id String @id @default(cuid())

  title           String
  internshipCycle String
  startYear       Int
  monthlySalary   OffersCurrency @relation(fields: [monthlySalaryId], references: [id], onDelete: Cascade)
  monthlySalaryId String         @unique

  OffersOffer OffersOffer?
}

model OffersFullTime {
  id                  String          @id @default(cuid())
  title               String
  level               String
  totalCompensation   OffersCurrency  @relation("OfferTotalCompensation", fields: [totalCompensationId], references: [id], onDelete: Cascade)
  totalCompensationId String          @unique
  baseSalary          OffersCurrency? @relation("OfferBaseSalary", fields: [baseSalaryId], references: [id], onDelete: Cascade)
  baseSalaryId        String?         @unique
  bonus               OffersCurrency? @relation("OfferBonus", fields: [bonusId], references: [id], onDelete: Cascade)
  bonusId             String?         @unique
  stocks              OffersCurrency? @relation("OfferStocks", fields: [stocksId], references: [id], onDelete: Cascade)
  stocksId            String?         @unique

  OffersOffer OffersOffer?
}

model OffersAnalysis {
  id        String   @id @default(cuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  profile   OffersProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
  profileId String        @unique

  overallHighestOffer OffersOffer @relation("HighestOverallOffer", fields: [offerId], references: [id], onDelete: Cascade)
  offerId             String      @unique

  // OVERALL
  overallAnalysis       OffersAnalysisUnit @relation("OverallAnalysis", fields: [overallAnalysisUnitId], references: [id], onDelete: Cascade)
  overallAnalysisUnitId String

  companyAnalysis OffersAnalysisUnit[] @relation("CompanyAnalysis")
}

model OffersAnalysisUnit {
  id String @id @default(cuid())

  analysedOffer   OffersOffer @relation("Analysed Offer", fields: [analysedOfferId], references: [id], onDelete: Cascade)
  analysedOfferId String

  percentile        Float
  noOfSimilarOffers Int
  topSimilarOffers  OffersOffer[]

  offersAnalysisOverall OffersAnalysis[] @relation("OverallAnalysis")
  offersAnalysisCompany OffersAnalysis[] @relation("CompanyAnalysis")
}

// End of Offers project models.

// Start of Questions project models.
// Add Questions project models here, prefix all models with "Questions",
// use camelCase for field names, and try to name them consistently
// across all models in this file.

enum QuestionsQuestionType {
  CODING
  SYSTEM_DESIGN
  BEHAVIORAL
  THEORY
}

model QuestionsQuestion {
  id            String                @id @default(cuid())
  userId        String?
  content       String                @db.Text
  questionType  QuestionsQuestionType
  lastSeenAt    DateTime?
  upvotes       Int                   @default(0)
  numEncounters Int                   @default(0)
  createdAt     DateTime              @default(now())
  updatedAt     DateTime              @updatedAt

  user                         User?                        @relation(fields: [userId], references: [id], onDelete: SetNull)
  encounters                   QuestionsQuestionEncounter[]
  votes                        QuestionsQuestionVote[]
  comments                     QuestionsQuestionComment[]
  answers                      QuestionsAnswer[]
  questionsListQuestionEntries QuestionsListQuestionEntry[]

  @@index([lastSeenAt, id])
  @@index([numEncounters, id])
  @@index([upvotes, id])
}

model QuestionsQuestionEncounter {
  id         String   @id @default(cuid())
  questionId String
  userId     String?
  companyId  String?
  countryId  String?
  stateId    String?
  cityId     String?
  role       String   @db.Text
  seenAt     DateTime
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  country  Country?          @relation(fields: [countryId], references: [id], onDelete: SetNull)
  state    State?            @relation(fields: [stateId], references: [id], onDelete: SetNull)
  city     City?             @relation(fields: [cityId], references: [id], onDelete: SetNull)
  company  Company?          @relation(fields: [companyId], references: [id], onDelete: SetNull)
  user     User?             @relation(fields: [userId], references: [id], onDelete: SetNull)
  question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
}

model QuestionsQuestionVote {
  id         String   @id @default(cuid())
  questionId String
  userId     String?
  vote       Vote
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

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

  @@unique([questionId, userId])
}

model QuestionsQuestionComment {
  id         String   @id @default(cuid())
  questionId String
  userId     String?
  upvotes    Int      @default(0)
  content    String   @db.Text
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  user     User?                          @relation(fields: [userId], references: [id], onDelete: SetNull)
  question QuestionsQuestion              @relation(fields: [questionId], references: [id], onDelete: Cascade)
  votes    QuestionsQuestionCommentVote[]

  @@index([updatedAt, id])
  @@index([upvotes, id])
}

model QuestionsQuestionCommentVote {
  id                String   @id @default(cuid())
  questionCommentId String
  userId            String?
  vote              Vote
  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt

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

  @@unique([questionCommentId, userId])
}

model QuestionsAnswer {
  id         String   @id @default(cuid())
  questionId String
  userId     String?
  content    String   @db.Text
  upvotes    Int      @default(0)
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  user     User?                    @relation(fields: [userId], references: [id], onDelete: SetNull)
  question QuestionsQuestion        @relation(fields: [questionId], references: [id], onDelete: Cascade)
  votes    QuestionsAnswerVote[]
  comments QuestionsAnswerComment[]

  @@index([updatedAt, id])
  @@index([upvotes, id])
}

model QuestionsAnswerVote {
  id        String   @id @default(cuid())
  answerId  String
  userId    String?
  vote      Vote
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

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

  @@unique([answerId, userId])
}

model QuestionsAnswerComment {
  id        String   @id @default(cuid())
  answerId  String
  userId    String?
  content   String   @db.Text
  upvotes   Int      @default(0)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  user   User?                        @relation(fields: [userId], references: [id], onDelete: SetNull)
  answer QuestionsAnswer              @relation(fields: [answerId], references: [id], onDelete: Cascade)
  votes  QuestionsAnswerCommentVote[]

  @@index([updatedAt, id])
  @@index([upvotes, id])
}

model QuestionsAnswerCommentVote {
  id              String   @id @default(cuid())
  answerCommentId String
  userId          String?
  vote            Vote
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt

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

  @@unique([answerCommentId, userId])
}

model QuestionsList {
  id        String   @id @default(cuid())
  userId    String
  name      String   @db.VarChar(256)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

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

  @@unique([userId, name])
}

model QuestionsListQuestionEntry {
  id         String   @id @default(cuid())
  listId     String
  questionId String
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  list     QuestionsList     @relation(fields: [listId], references: [id], onDelete: Cascade)
  question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)

  @@unique([listId, questionId])
}

// End of Questions project models.