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

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

// ==================== 挖矿配置 ====================

// 挖矿全局配置
model MiningConfig {
  id                    String    @id @default(uuid())
  totalShares           Decimal   @db.Decimal(30, 8) // 总积分股数量 (100.02B)
  distributionPool      Decimal   @db.Decimal(30, 8) // 分配池 (200M)
  remainingDistribution Decimal   @db.Decimal(30, 8) // 剩余可分配
  halvingPeriodYears    Int       @default(2) // 减半周期（年）
  currentEra            Int       @default(1) // 当前纪元
  eraStartDate          DateTime // 当前纪元开始日期
  minuteDistribution    Decimal   @db.Decimal(30, 18) // 每分钟分配量
  isActive              Boolean   @default(false) // 是否已激活挖矿
  activatedAt           DateTime? // 激活时间
  createdAt             DateTime  @default(now())
  updatedAt             DateTime  @updatedAt

  @@map("mining_configs")
}

// 减半纪元记录
model MiningEra {
  id                  String    @id @default(uuid())
  eraNumber           Int       @unique
  startDate           DateTime
  endDate             DateTime?
  initialDistribution Decimal   @db.Decimal(30, 8) // 纪元初始可分配量
  totalDistributed    Decimal   @default(0) @db.Decimal(30, 8) // 已分配量
  minuteDistribution  Decimal   @db.Decimal(30, 18) // 每分钟分配量
  isActive            Boolean   @default(true)
  createdAt           DateTime  @default(now())

  @@map("mining_eras")
}

// ==================== 用户挖矿账户 ====================

// 用户挖矿账户
model MiningAccount {
  id                String    @id @default(uuid())
  accountSequence   String    @unique
  totalMined        Decimal   @default(0) @db.Decimal(30, 8) // 总挖到的积分股
  availableBalance  Decimal   @default(0) @db.Decimal(30, 8) // 可用余额
  frozenBalance     Decimal   @default(0) @db.Decimal(30, 8) // 冻结余额
  totalContribution Decimal   @default(0) @db.Decimal(30, 8) // 当前算力（从 contribution-service 同步）
  lastSyncedAt      DateTime? // 最后同步算力时间
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt

  records      MiningRecord[]
  transactions MiningTransaction[]

  @@index([totalContribution(sort: Desc)])
  @@map("mining_accounts")
}

// 挖矿记录（分钟级别）
model MiningRecord {
  id                 String   @id @default(uuid())
  accountSequence    String
  miningMinute       DateTime // 挖矿分钟（精确到分钟）
  contributionRatio  Decimal  @db.Decimal(30, 18) // 当时的算力占比
  totalContribution  Decimal  @db.Decimal(30, 8) // 当时的总算力
  minuteDistribution Decimal  @db.Decimal(30, 18) // 当分钟总分配量
  minedAmount        Decimal  @db.Decimal(30, 18) // 挖到的数量
  createdAt          DateTime @default(now())

  account MiningAccount @relation(fields: [accountSequence], references: [accountSequence])

  @@unique([accountSequence, miningMinute])
  @@index([miningMinute])
  @@map("mining_records")
}

// 挖矿交易流水
model MiningTransaction {
  id              String  @id @default(uuid())
  accountSequence String
  type            String // MINE, FREEZE, UNFREEZE, TRANSFER_OUT, TRANSFER_IN, BURN
  amount          Decimal @db.Decimal(30, 8)
  balanceBefore   Decimal @db.Decimal(30, 8)
  balanceAfter    Decimal @db.Decimal(30, 8)
  referenceId     String? // 关联ID（如交易ID、划转ID）
  referenceType   String? // 关联类型

  // 交易对手方信息
  counterpartyType       String? @map("counterparty_type") // USER, POOL, SYSTEM
  counterpartyAccountSeq String? @map("counterparty_account_seq") // 对手方账户序列号
  counterpartyUserId     String? @map("counterparty_user_id") // 对手方用户ID

  // 详细备注（包含完整交易信息，格式: "划转到用户[U123456]"）
  memo        String?  @db.Text
  description String? // 保留兼容旧字段
  createdAt   DateTime @default(now())

  account MiningAccount @relation(fields: [accountSequence], references: [accountSequence])

  @@index([accountSequence, createdAt(sort: Desc)])
  @@index([type])
  @@index([counterpartyAccountSeq])
  @@index([counterpartyUserId])
  @@map("mining_transactions")
}

// ==================== 挖矿统计 ====================

// 每分钟挖矿统计
model MinuteMiningStat {
  id                String   @id @default(uuid())
  minute            DateTime @unique
  totalContribution Decimal  @db.Decimal(30, 8) // 参与挖矿的总算力
  totalDistributed  Decimal  @db.Decimal(30, 18) // 该分钟分配的总量
  participantCount  Int // 参与者数量
  burnAmount        Decimal  @default(0) @db.Decimal(30, 8) // 该分钟销毁量
  createdAt         DateTime @default(now())

  @@index([minute(sort: Desc)])
  @@map("minute_mining_stats")
}

// 每日挖矿统计
model DailyMiningStat {
  id                  String   @id @default(uuid())
  date                DateTime @unique @db.Date
  totalContribution   Decimal  @db.Decimal(30, 8)
  totalDistributed    Decimal  @db.Decimal(30, 8)
  totalBurned         Decimal  @db.Decimal(30, 8)
  participantCount    Int
  avgContributionRate Decimal  @db.Decimal(10, 8) // 平均算力利用率
  createdAt           DateTime @default(now())

  @@map("daily_mining_stats")
}

// ==================== 销毁机制 ====================

// 黑洞账户
model BlackHole {
  id             String    @id @default(uuid())
  totalBurned    Decimal   @default(0) @db.Decimal(30, 8) // 已销毁总量
  targetBurn     Decimal   @db.Decimal(30, 8) // 目标销毁量 (10B)
  remainingBurn  Decimal   @db.Decimal(30, 8) // 剩余待销毁
  lastBurnMinute DateTime?
  createdAt      DateTime  @default(now())
  updatedAt      DateTime  @updatedAt

  records BurnRecord[]

  @@map("black_holes")
}

// 销毁记录
model BurnRecord {
  id              String   @id @default(uuid())
  blackHoleId     String
  burnMinute      DateTime
  burnAmount      Decimal  @db.Decimal(30, 18)
  remainingTarget Decimal  @db.Decimal(30, 8) // 销毁后剩余目标

  // 来源信息（从哪个池/用户销毁）
  sourceType       String? @map("source_type") // CIRCULATION_POOL, USER, SYSTEM
  sourceAccountSeq String? @map("source_account_seq") // 来源账户序列号
  sourceUserId     String? @map("source_user_id") // 来源用户ID

  // 详细备注
  memo      String?  @db.Text
  createdAt DateTime @default(now())

  blackHole BlackHole @relation(fields: [blackHoleId], references: [id])

  @@unique([blackHoleId, burnMinute])
  @@index([burnMinute])
  @@index([sourceAccountSeq])
  @@map("burn_records")
}

// ==================== 价格相关 ====================

// 价格快照（每分钟）
model PriceSnapshot {
  id                   String   @id @default(uuid())
  snapshotTime         DateTime @unique
  price                Decimal  @db.Decimal(30, 18) // 当时价格
  sharePool            Decimal  @db.Decimal(30, 8) // 股池
  blackHoleAmount      Decimal  @db.Decimal(30, 8) // 黑洞数量
  circulationPool      Decimal  @db.Decimal(30, 8) // 流通池
  effectiveDenominator Decimal  @db.Decimal(30, 8) // 有效分母
  createdAt            DateTime @default(now())

  @@index([snapshotTime(sort: Desc)])
  @@map("price_snapshots")
}

// ==================== 池账户系统 ====================

// 池账户类型枚举
enum PoolAccountType {
  SHARE_POOL // 积分股池 - 总股池
  BLACK_HOLE_POOL // 黑洞积分股池 - 销毁池
  CIRCULATION_POOL // 流通积分股池 - 流通池
}

// 池账户交易类型枚举
enum PoolTransactionType {
  // 积分股池操作
  MINING_DISTRIBUTE // 挖矿分配（股池 -> 用户）
  FEE_COLLECT // 手续费收取（用户 -> 股池）
  INITIAL_INJECT // 初始注入

  // 黑洞池操作
  BURN // 销毁（流通池 -> 黑洞）

  // 流通池操作
  USER_TRANSFER_IN // 用户划入（用户 -> 流通池）
  USER_TRANSFER_OUT // 用户划出（流通池 -> 用户）
  TRADE_BUY // 交易买入
  TRADE_SELL // 交易卖出

  // 通用操作
  POOL_TRANSFER // 池间划转
  ADJUSTMENT // 系统调整
}

// 池账户（管理三大池：积分股池、黑洞积分股池、流通积分股池）
model PoolAccount {
  id           String          @id @default(uuid())
  poolType     PoolAccountType @unique @map("pool_type") // 池类型
  name         String // 池名称
  balance      Decimal         @default(0) @db.Decimal(30, 8) // 当前余额
  totalInflow  Decimal         @default(0) @db.Decimal(30, 8) // 累计流入
  totalOutflow Decimal         @default(0) @db.Decimal(30, 8) // 累计流出
  isActive     Boolean         @default(true) @map("is_active")
  description  String?
  createdAt    DateTime        @default(now()) @map("created_at")
  updatedAt    DateTime        @updatedAt @map("updated_at")

  transactions PoolTransaction[]

  @@index([poolType])
  @@map("pool_accounts")
}

// 池账户交易明细（包含交易对手方信息）
model PoolTransaction {
  id              String              @id @default(uuid())
  poolAccountId   String              @map("pool_account_id")
  poolType        PoolAccountType     @map("pool_type")
  transactionType PoolTransactionType @map("transaction_type")

  // 金额信息
  amount        Decimal @db.Decimal(30, 8)
  balanceBefore Decimal @map("balance_before") @db.Decimal(30, 8)
  balanceAfter  Decimal @map("balance_after") @db.Decimal(30, 8)

  // 交易对手方信息（关键：用户ID和账户序列号）
  counterpartyType       String?          @map("counterparty_type") // USER, POOL, SYSTEM, EXTERNAL
  counterpartyAccountSeq String?          @map("counterparty_account_seq") // 对手方账户序列号
  counterpartyUserId     String?          @map("counterparty_user_id") // 对手方用户ID
  counterpartyPoolType   PoolAccountType? @map("counterparty_pool_type") // 如果对手方是池账户

  // 关联信息
  referenceId   String? @map("reference_id") // 关联业务ID（如订单ID、划转ID）
  referenceType String? @map("reference_type") // 关联类型
  txHash        String? @map("tx_hash") // 链上交易哈希（如有）

  // 详细备注（包含完整交易信息）
  // 格式示例: "挖矿分配给用户[U123456], 算力占比0.5%, 分钟2024-01-10 10:30"
  memo String? @db.Text

  // 扩展数据（JSON格式存储更多业务细节）
  metadata Json?

  createdAt DateTime @default(now()) @map("created_at")

  poolAccount PoolAccount @relation(fields: [poolAccountId], references: [id])

  @@index([poolAccountId, createdAt(sort: Desc)])
  @@index([poolType, transactionType])
  @@index([counterpartyAccountSeq])
  @@index([counterpartyUserId])
  @@index([referenceId])
  @@index([createdAt(sort: Desc)])
  @@map("pool_transactions")
}

// ==================== Outbox ====================

enum OutboxStatus {
  PENDING
  PUBLISHED
  FAILED
}

model OutboxEvent {
  id            String       @id @default(uuid())
  aggregateType String       @map("aggregate_type")
  aggregateId   String       @map("aggregate_id")
  eventType     String       @map("event_type")
  payload       Json
  topic         String       @default("mining.events")
  key           String?
  status        OutboxStatus @default(PENDING)
  retryCount    Int          @default(0) @map("retry_count")
  maxRetries    Int          @default(5) @map("max_retries")
  lastError     String?      @map("last_error")
  publishedAt   DateTime?    @map("published_at")
  nextRetryAt   DateTime?    @map("next_retry_at")
  createdAt     DateTime     @default(now()) @map("created_at")

  @@index([status])
  @@index([nextRetryAt])
  @@index([createdAt])
  @@map("outbox_events")
}
