// TypeMaster AI - Prisma Schema
// MySQL Database for cPanel hosting

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

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

// ========================
// USER & AUTH
// ========================

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String    @unique
  emailVerified DateTime?
  image         String?
  password      String? // hashed, null for OAuth users

  // Gamification
  xp      Int     @default(0)
  level   Int     @default(1)
  country String?
  city    String?
  bio     String? @db.Text

  // Settings
  soundEnabled   Boolean @default(true)
  musicEnabled   Boolean @default(false)
  theme          String  @default("dark")
  keyboardLayout String  @default("qwerty")

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

  // Relations
  accounts       Account[]
  sessions       Session[]
  typingSessions TypingSession[]
  achievements   UserAchievement[]
  aiReports      AIReport[]
  progress       Progress[]
  statistics     Statistics?
  rankEntries    RankEntry[]

  @@map("users")
}

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?

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

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

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

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime

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

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

  @@map("sessions")
}

model VerificationToken {
  identifier String
  token      String
  expires    DateTime

  @@unique([identifier, token])
  @@map("verification_tokens")
}

// ========================
// EXERCISES
// ========================

enum ExerciseCategory {
  BEGINNER
  INTERMEDIATE
  ADVANCED
  CHALLENGE
}

enum ExerciseDifficulty {
  LETTERS
  SYLLABLES
  SIMPLE_WORDS
  PHRASES
  PUNCTUATION
  NUMBERS
  FULL_TEXTS
  PROGRAMMING
  PROFESSIONAL
  TIME_RACE
  EXTREME_ACCURACY
  BLIND_TYPING
}

model Exercise {
  id            String             @id @default(cuid())
  title         String
  description   String?            @db.Text
  content       String             @db.LongText
  category      ExerciseCategory
  difficulty    ExerciseDifficulty
  language      String             @default("pt-BR")
  timeLimit     Int? // seconds, null = no limit
  isAIGenerated Boolean            @default(false)
  isActive      Boolean            @default(true)

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

  typingSessions TypingSession[]

  @@map("exercises")
}

// ========================
// TYPING SESSIONS
// ========================

model TypingSession {
  id         String  @id @default(cuid())
  userId     String
  exerciseId String?

  // Performance metrics
  wpm      Float // words per minute
  cpm      Float // chars per minute
  accuracy Float // 0-100 percentage
  rawWpm   Float // wpm before accuracy correction
  duration Int // seconds

  // Error data (JSON: {char: errorCount})
  errorMap Json @default("{}")

  // Timing data (JSON: array of keypress intervals in ms)
  keystrokeData Json @default("[]")

  // Anti-cheat
  isSuspicious     Boolean @default(false)
  suspiciousReason String? @db.Text
  focusLostCount   Int     @default(0)
  pasteAttempts    Int     @default(0)

  // XP earned
  xpEarned Int @default(0)

  createdAt DateTime @default(now())

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

  @@index([userId])
  @@index([createdAt])
  @@map("typing_sessions")
}

// ========================
// ACHIEVEMENTS
// ========================

enum AchievementType {
  SPEED
  ACCURACY
  CONSISTENCY
  VOLUME
  STREAK
  SPECIAL
}

model Achievement {
  id          String          @id @default(cuid())
  name        String
  description String          @db.Text
  icon        String
  type        AchievementType
  xpReward    Int             @default(0)

  // Condition (JSON: {type, value})
  condition Json

  isActive  Boolean  @default(true)
  createdAt DateTime @default(now())

  userAchievements UserAchievement[]

  @@map("achievements")
}

model UserAchievement {
  id            String   @id @default(cuid())
  userId        String
  achievementId String
  unlockedAt    DateTime @default(now())

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

  @@unique([userId, achievementId])
  @@map("user_achievements")
}

// ========================
// RANKING
// ========================

enum RankPeriod {
  WEEKLY
  MONTHLY
  ALLTIME
}

model RankEntry {
  id     String     @id @default(cuid())
  userId String
  period RankPeriod

  wpm      Float
  accuracy Float
  sessions Int
  xp       Int

  rank Int

  periodStart DateTime
  periodEnd   DateTime
  updatedAt   DateTime @updatedAt

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

  @@unique([userId, period, periodStart])
  @@index([period, wpm])
  @@map("rank_entries")
}

// ========================
// AI REPORTS
// ========================

model AIReport {
  id     String @id @default(cuid())
  userId String

  // Analysis (JSON: {problematicKeys, slowKeys, errorSequences})
  analysis Json

  // Generated exercise content
  generatedExercise String? @db.LongText

  // Coach message
  coachMessage String @db.Text

  // Performance insights
  insights Json @default("[]")

  createdAt DateTime @default(now())

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

  @@index([userId, createdAt])
  @@map("ai_reports")
}

// ========================
// PROGRESS (Daily XP History)
// ========================

model Progress {
  id     String @id @default(cuid())
  userId String

  date     DateTime @db.Date
  xpEarned Int      @default(0)
  wpmAvg   Float    @default(0)
  accuracy Float    @default(0)
  sessions Int      @default(0)

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

  @@unique([userId, date])
  @@index([userId, date])
  @@map("progress")
}

// ========================
// STATISTICS (Aggregate)
// ========================

model Statistics {
  id     String @id @default(cuid())
  userId String @unique

  totalSessions    Int @default(0)
  totalWords       Int @default(0)
  totalChars       Int @default(0)
  totalTimeSeconds Int @default(0)

  bestWpm      Float @default(0)
  avgWpm       Float @default(0)
  bestAccuracy Float @default(0)
  avgAccuracy  Float @default(0)

  currentStreak  Int       @default(0)
  longestStreak  Int       @default(0)
  lastActiveDate DateTime?

  updatedAt DateTime @updatedAt

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

  @@map("statistics")
}
