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

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

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

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

model User {
  id                 String   @id @default(cuid()) // Better Auth will generate IDs
  email              String   @unique
  name               String   // Better Auth required field
  emailVerified      Boolean  @default(false) // Better Auth required field
  image              String?  // Better Auth field (avatar)
  username           String?  @unique
  bio                String?
  language           String   @default("en")
  isAdmin            Boolean  @default(false)
  versionLimit       Int      @default(3)
  subscriptionPlanId String   @default("free")
  subscribePlan      String   @default("free") // Legacy field
  maxVersionLimit    Int      @default(3)
  promptLimit        Int?
  creditBalance      Float    @default(0.0)
  stripeCustomerId   String?  @unique
  createdAt          DateTime @default(now())
  updatedAt          DateTime @updatedAt

  // Better Auth relationships
  sessions Session[]
  accounts Account[]

  // App relationships
  subscriptionPlan SubscriptionPlan @relation(fields: [subscriptionPlanId], references: [id])
  prompts          Prompt[]
  credits          Credit[]
  subscriptions    Subscription[]
  simulatorRuns    SimulatorRun[]

  @@map("users")
}

// 订阅套餐模型

model SubscriptionPlan {
  id             String  @id // "free", "pro" 等
  name           String // 套餐名称
  displayName    String // 显示名称（支持国际化）
  description    String? // 套餐描述
  price          Float   @default(0) // 价格（美元）
  currency       String  @default("usd") // 货币
  interval       String  @default("month") // 计费周期: "month", "year"
  stripePriceId  String? @unique // Stripe 价格 ID
  isActive       Boolean @default(true) // 是否激活
  sortOrder      Int     @default(0) // 排序顺序
  costMultiplier Float   @default(1.0) // 费用倍率，默认1倍

  // 权益配置 (JSON 格式存储)
  features Json // 功能特性配置
  limits   Json // 限制配置

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

  // 关联关系
  users         User[]
  subscriptions Subscription[]
  models        Model[]

  @@map("subscription_plans")
}

model Prompt {
  id          String   @id @default(cuid())
  name        String
  content     String
  description String?
  isPublic    Boolean  @default(false) // 保留用于向后兼容
  permissions String   @default("private") // "private" | "public"
  visibility  String? // "under_review" | "published" | null
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  userId        String
  user          User            @relation(fields: [userId], references: [id], onDelete: Cascade)
  tags          PromptTag[]
  versions      PromptVersion[]
  album         PromptAlbum?    @relation(fields: [albumId], references: [id])
  albumId       String?
  tests         PromptTestRun[]
  stats         PromptStats?
  simulatorRuns SimulatorRun[]

  @@map("prompts")
}

model PromptVersion {
  id        String   @id @default(cuid())
  version   Int
  content   String
  changelog String?
  createdAt DateTime @default(now())

  promptId      String
  prompt        Prompt         @relation(fields: [promptId], references: [id], onDelete: Cascade)
  simulatorRuns SimulatorRun[]

  @@unique([promptId, version])
  @@map("prompt_versions")
}

model PromptTag {
  id    String @id @default(cuid())
  name  String @unique
  color String @default("#3B82F6")

  prompts Prompt[]

  @@map("prompt_tags")
}

model PromptAlbum {
  id          String   @id @default(cuid())
  name        String
  description String?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  prompts Prompt[]

  @@map("prompt_albums")
}

model PromptTestRun {
  id        String   @id @default(cuid())
  input     String
  output    String?
  success   Boolean  @default(false)
  error     String?
  createdAt DateTime @default(now())

  promptId String
  prompt   Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)

  @@map("prompt_test_runs")
}

model PromptStats {
  id          String   @id @default(cuid())
  promptId    String   @unique
  viewCount   Int      @default(0) // 浏览计数
  likeCount   Int      @default(0) // 点赞计数
  rating      Float? // 平均评分
  ratingCount Int      @default(0) // 评分数量
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  prompt Prompt @relation(fields: [promptId], references: [id], onDelete: Cascade)

  @@map("prompt_stats")
}

model Credit {
  id            String    @id @default(cuid())
  userId        String
  amount        Float // 交易金额（正数为充值，负数为消费）
  balance       Float     @default(5) // 执行该交易后的余额
  type          String // "system_gift", "subscription_monthly", "user_purchase", "consumption"
  category      String? // 消费类别: "simulation", "api_call", "export" 等
  note          String? // 备注说明
  referenceId   String? // 关联的记录ID（如SimulatorRun的ID）
  referenceType String? // 关联记录类型（如"simulator_run"）
  expiresAt     DateTime? // 过期时间，null表示永久有效
  isActive      Boolean   @default(true) // 是否激活状态
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt

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

  @@map("credits")
}

// 订阅记录模型

model Subscription {
  id                   String  @id @default(cuid())
  userId               String // 用户 ID
  subscriptionPlanId   String // 订阅套餐 ID
  stripeSubscriptionId String? @unique // Stripe 订阅 ID
  stripeCustomerId     String? // Stripe 客户 ID（冗余存储，便于查询）

  // 订阅状态和时间
  isActive  Boolean   @default(false) // 是否有效
  startDate DateTime? // 开始时间（订阅激活时设置）
  endDate   DateTime? // 结束时间（订阅激活时设置）

  // 订阅状态
  status String @default("pending") // "pending", "active", "canceled", "expired", "failed"

  // 元数据
  metadata Json? // 额外的元数据（如 Stripe 的原始数据）

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

  // 关联关系
  user             User             @relation(fields: [userId], references: [id], onDelete: Cascade)
  subscriptionPlan SubscriptionPlan @relation(fields: [subscriptionPlanId], references: [id])

  @@map("subscriptions")
}

// AI 模型配置表 - 所有模型默认可用于所有套餐

model Model {
  id                 String   @id @default(cuid())
  subscriptionPlanId String   @default("free") // 默认关联到 free 套餐
  modelId            String   @unique // 全局唯一的模型 ID，如 "openai/gpt-4"
  name               String // 显示名称，如 "GPT-4"
  provider           String // 提供商，如 "OpenAI"
  serviceProvider    String   @default("openrouter") // 服务提供者，如 "openrouter", "replicate"
  outputType         String   @default("text") // 输出类型，如 "text", "image", "video", "audio"
  description        String? // 模型描述
  maxTokens          Int? // 最大 token 数
  inputCostPer1k     Float? // 输入成本（每1K tokens）
  outputCostPer1k    Float? // 输出成本（每1K tokens）
  supportedFeatures  Json? // 支持的特性（如 function_calling, vision 等）
  metadata           Json? // 其他元数据
  customLimits       Json? // 自定义限制（如每日调用次数、最大 tokens 等）
  isActive           Boolean  @default(true) // 是否启用
  createdAt          DateTime @default(now())
  updatedAt          DateTime @updatedAt

  // 关联关系
  subscriptionPlan SubscriptionPlan @relation(fields: [subscriptionPlanId], references: [id], onDelete: Cascade)
  simulatorRuns    SimulatorRun[]

  @@map("models")
}

// 模拟器运行记录

model SimulatorRun {
  id               String         @id @default(cuid())
  userId           String
  name             String         @default("Simulation Run") // 运行名称
  promptId         String
  promptVersionId  String? // 可选，如果选择了特定版本
  modelId          String
  userInput        String // 用户输入内容
  promptContent    String? // 自定义提示词内容（如果用户修改了原提示词）
  output           String? // AI响应输出
  error            String? // 错误信息
  status           String         @default("pending") // "pending", "running", "completed", "failed"
  // 运行配置
  temperature      Float?         @default(0.7)
  maxTokens        Int?
  topP             Float?
  frequencyPenalty Float?
  presencePenalty  Float?
  // 消耗和统计
  inputTokens      Int? // 输入token数
  outputTokens     Int? // 输出token数
  totalCost        Float? // 总消费
  duration         Int? // 运行时长（毫秒）
  creditId         String? // 关联的信用消费记录ID
  createdAt        DateTime       @default(now())
  completedAt      DateTime?
  // 关联关系
  user             User           @relation(fields: [userId], references: [id], onDelete: Cascade)
  prompt           Prompt         @relation(fields: [promptId], references: [id], onDelete: Cascade)
  promptVersion    PromptVersion? @relation(fields: [promptVersionId], references: [id], onDelete: SetNull)
  model            Model          @relation(fields: [modelId], references: [id])

  @@map("simulator_runs")
}

model Session {
  id        String   @id
  expiresAt DateTime
  token     String
  createdAt DateTime
  updatedAt DateTime
  ipAddress String?
  userAgent String?
  userId    String
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([token])
  @@map("session")
}

model Account {
  id                    String    @id
  accountId             String
  providerId            String
  userId                String
  user                  User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  accessToken           String?
  refreshToken          String?
  idToken               String?
  accessTokenExpiresAt  DateTime?
  refreshTokenExpiresAt DateTime?
  scope                 String?
  password              String?
  createdAt             DateTime
  updatedAt             DateTime

  @@map("account")
}

model Verification {
  id         String    @id
  identifier String
  value      String
  expiresAt  DateTime
  createdAt  DateTime?
  updatedAt  DateTime?

  @@map("verification")
}
