// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

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

model User {
  id                 String    @id @default(cuid())
  email              String    @unique
  passwordHash       String
  name               String?
  isAdmin            Boolean   @default(false)
  lastLoginAt        DateTime?
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt

  // Relations
  sessions           Session[]
  exercises          Exercise[]
  workouts           Workout[]
  programs           Program[]
  equipment          Equipment[]
  contentItems       ContentItem[]
  aiSuggestions      AISuggestion[]
  userPreferences    UserPreferences?

  @@index([email])
}

model Session {
  id                 String    @id @default(cuid())
  userId             String
  token              String    @unique
  expiresAt          DateTime
  createdAt          DateTime  @default(now())

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

  @@index([userId])
  @@index([token])
}

model Exercise {
  id                 String    @id @default(cuid())
  userId             String
  name               String
  description        String?
  muscleGroups       String    // JSON array stored as text: ["chest", "triceps"]
  type               String    // barbell, dumbbell, machine, cable, bodyweight, cardio, kettlebell, other
  inputFields        String    @default("[\"sets\",\"reps\",\"weight\"]") // JSON array: sets, reps, weight, duration, distance, calories
  defaultWeightUnit  String?   // null = use user pref; "kg" for kettlebells, etc.
  isCustom           Boolean   @default(false)
  createdAt          DateTime  @default(now())

  // Relations
  user               User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  setLogs            SetLog[]
  programExercises   ProgramExercise[]

  @@unique([userId, name])
  @@index([userId])
  @@index([type])
}

model Workout {
  id                 String    @id @default(cuid())
  userId             String
  date               DateTime
  name               String?
  notes              String?
  durationMinutes    Int?
  difficulty         Int?      // 1-10 scale
  caloriesBurned     Int?
  deletedAt          DateTime?
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt

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

  @@index([userId])
  @@index([date])
  @@index([deletedAt])
}

model SetLog {
  id                 String    @id @default(cuid())
  workoutId          String
  exerciseId         String
  setNumber          Int
  reps               Int?
  weight             Float?
  weightUnit         String    @default("lbs")
  rpe                Int?      // Rate of Perceived Exertion (1-10)
  durationSeconds    Int?      // for timed exercises (assault bike, jump rope, planks)
  distance           Float?    // for distance-based exercises
  distanceUnit       String?   // "mi", "km", "m"
  calories           Int?      // for cardio machines that report calories
  customMetrics      String?   // JSON map for dynamic custom metrics (e.g. {"watts":"157"})
  notes              String?
  createdAt          DateTime  @default(now())

  // Relations
  workout            Workout   @relation(fields: [workoutId], references: [id], onDelete: Cascade)
  exercise           Exercise  @relation(fields: [exerciseId], references: [id], onDelete: Cascade)

  @@index([workoutId])
  @@index([exerciseId])
}

model Program {
  id                 String    @id @default(cuid())
  userId             String
  name               String
  description        String?
  type               String    // hypertrophy, strength, power, endurance, recovery
  durationWeeks      Int
  startDate          DateTime
  endDate            DateTime?
  isActive           Boolean   @default(false)
  aiGenerated        Boolean   @default(false)
  aiNotes            String?
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt

  // Relations
  user               User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  weeks              ProgramWeek[]
  aiSuggestions      AISuggestion[]

  @@index([userId])
  @@index([isActive])
}

model ProgramWeek {
  id                 String    @id @default(cuid())
  programId          String
  weekNumber         Int
  phase              String?
  description        String?
  createdAt          DateTime  @default(now())

  // Relations
  program            Program   @relation(fields: [programId], references: [id], onDelete: Cascade)
  days               ProgramDay[]

  @@unique([programId, weekNumber])
  @@index([programId])
}

model ProgramDay {
  id                 String    @id @default(cuid())
  weekId             String
  dayOfWeek          Int       // 0-6 (Sunday-Saturday)
  name               String?
  description        String?
  createdAt          DateTime  @default(now())

  // Relations
  week               ProgramWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
  exercises          ProgramExercise[]

  @@unique([weekId, dayOfWeek])
  @@index([weekId])
}

model ProgramExercise {
  id                 String    @id @default(cuid())
  dayId              String
  exerciseId         String
  order              Int
  sets               Int?
  repsMin            Int?
  repsMax            Int?
  rpe                Int?
  restSeconds        Int?
  notes              String?
  createdAt          DateTime  @default(now())

  // Relations
  day                ProgramDay @relation(fields: [dayId], references: [id], onDelete: Cascade)
  exercise           Exercise  @relation(fields: [exerciseId], references: [id], onDelete: Cascade)

  @@unique([dayId, order])
  @@index([dayId])
  @@index([exerciseId])
}

model Equipment {
  id                 String    @id @default(cuid())
  userId             String
  name               String
  type               String    // rack, barbell, dumbbell, plate, bench, etc.
  quantity           Int
  weight             Float?    // for plates, dumbbells, etc.
  weightUnit         String    @default("lbs")
  notes              String?
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt

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

  @@unique([userId, name])
  @@index([userId])
}

model ContentItem {
  id                 String    @id @default(cuid())
  userId             String
  title              String
  source             String    // pdf_upload, youtube, manual_entry
  sourceUrl          String?
  content            String?
  fullText           String?   // Full searchable text
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt

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

  @@index([userId])
  @@index([source])
}

model ContentChunk {
  id                 String    @id @default(cuid())
  contentItemId      String
  chunkNumber        Int
  text               String
  pageNumber         Int?
  timestamp          Float?    // For video timestamps
  createdAt          DateTime  @default(now())

  // Relations
  contentItem        ContentItem @relation(fields: [contentItemId], references: [id], onDelete: Cascade)

  @@index([contentItemId])
}

model AISuggestion {
  id                 String    @id @default(cuid())
  userId             String
  programId          String?
  type               String    // exercise_recommendation, workout_adjustment, program_optimization, etc.
  suggestion         String
  priority           Int       // 1-5 scale
  accepted           Boolean?
  source             String    // rules, claude
  metadata           String?   // JSON metadata
  createdAt          DateTime  @default(now())

  // Relations
  user               User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  program            Program?  @relation(fields: [programId], references: [id], onDelete: SetNull)

  @@index([userId])
  @@index([programId])
  @@index([type])
}

/// Singleton row keyed on id=1. Holds instance-wide settings that aren't
/// tied to any single user (multi-user signup gate, feature flags, etc.).
/// Use `getInstanceSettings()` from lib/instanceSettings.ts to read; it
/// upserts the row defensively on first read so callers never see null.
model InstanceSettings {
  id            Int      @id @default(1)
  signupsOpen   Boolean  @default(false)
  updatedAt     DateTime @updatedAt
}

model UserPreferences {
  id                 String    @id @default(cuid())
  userId             String    @unique
  theme              String    @default("system") // light, dark, system
  defaultWeightUnit  String    @default("lbs")
  defaultRestSeconds Int       @default(90)
  enableClaudeAI     Boolean   @default(false)
  claudeApiKey       String?
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt

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

  @@index([userId])
}
