// 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 = "postgresql"
  url      = env("DATABASE_URL")
}

/// Package table - stores NPM package metadata (package-level)
model Package {
  id String @id @default(cuid())

  // NPM Metadata
  npmPackageName String   @unique @map("npm_package_name") @db.VarChar(214)
  npmVersion     String   @map("npm_version") @db.VarChar(50)
  npmPublishedAt DateTime @map("npm_published_at")
  npmDescription String?  @map("npm_description") @db.Text
  npmRepository  Json?    @map("npm_repository") @db.JsonB
  npmHomepage    String?  @map("npm_homepage") @db.Text
  npmLicense     String?  @map("npm_license") @db.VarChar(50)
  npmKeywords    String[] @default([]) @map("npm_keywords") @db.Text
  npmReadme      String?  @map("npm_readme") @db.Text
  npmAuthor      Json?    @map("npm_author") @db.JsonB
  npmMaintainers Json?    @map("npm_maintainers") @db.JsonB

  // TPMJS Package-Level Metadata
  category       String   @db.VarChar(50)
  env            Json?    @db.JsonB // Environment variables (shared across tools)
  frameworks     String[] @default([]) @db.Text
  tier           String   @db.VarChar(20) // 'minimal' | 'rich'
  discoveryMethod String  @map("discovery_method") @db.VarChar(20) // 'keyword' | 'changes-feed'
  isOfficial     Boolean  @default(false) @map("is_official")

  // Package Metrics
  npmDownloadsLastMonth Int? @default(0) @map("npm_downloads_last_month")
  githubStars           Int? @default(0) @map("github_stars")

  // Timestamps
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  // Relations
  tools Tool[]

  @@index([category])
  @@index([isOfficial])
  @@index([npmDownloadsLastMonth])
  @@index([createdAt])
  @@map("packages")
}

/// Tool table - stores individual tools within packages
model Tool {
  id String @id @default(cuid())

  // Package Relation
  packageId String  @map("package_id")
  package   Package @relation(fields: [packageId], references: [id], onDelete: Cascade)

  // Tool Identity
  exportName String @map("export_name") @db.VarChar(100) // e.g., "helloWorldTool", "default"

  // Tool Metadata
  description String @db.Text
  parameters  Json?  @db.JsonB
  returns     Json?  @db.JsonB
  aiAgent     Json?  @map("ai_agent") @db.JsonB

  // Tool Metrics
  qualityScore Decimal? @map("quality_score") @db.Decimal(3, 2) // 0.00 to 1.00

  // Health Status Fields
  importHealth     HealthStatus? @default(UNKNOWN) @map("import_health")
  executionHealth  HealthStatus? @default(UNKNOWN) @map("execution_health")
  lastHealthCheck  DateTime?     @map("last_health_check")
  healthCheckError String?       @map("health_check_error") @db.Text

  // Timestamps
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  // Relations
  simulations  Simulation[]
  healthChecks HealthCheck[]

  @@unique([packageId, exportName])
  @@index([qualityScore])
  @@index([importHealth])
  @@index([executionHealth])
  @@index([lastHealthCheck])
  @@map("tools")
}

/// Sync checkpoints - tracks progress of sync workers
model SyncCheckpoint {
  id String @id @default(cuid())

  source     String   @unique @db.VarChar(50) // 'changes-feed' | 'keyword-search' | 'metrics'
  checkpoint Json     @db.JsonB // Stores last sequence, timestamp, etc.
  updatedAt  DateTime @updatedAt @map("updated_at")

  @@map("sync_checkpoints")
}

/// Sync logs - audit trail of sync operations
model SyncLog {
  id String @id @default(cuid())

  source    String   @db.VarChar(50) // 'changes-feed' | 'keyword-search' | 'metrics'
  status    String   @db.VarChar(20) // 'success' | 'error' | 'partial'
  processed Int      @default(0) // Number of packages processed
  skipped   Int      @default(0) // Number of packages skipped
  errors    Int      @default(0) // Number of errors encountered
  message   String?  @db.Text // Error message or summary
  metadata  Json?    @db.JsonB // Additional context
  createdAt DateTime @default(now()) @map("created_at")

  @@index([source])
  @@index([status])
  @@index([createdAt])
  @@map("sync_logs")
}

/// Simulations - tracks tool playground executions
model Simulation {
  id String @id @default(cuid())

  // Relations
  toolId String @map("tool_id")
  tool   Tool   @relation(fields: [toolId], references: [id], onDelete: Cascade)

  // Request data
  userPrompt String  @map("user_prompt") @db.Text
  parameters Json?   @db.JsonB
  ipAddress  String? @map("ip_address") @db.VarChar(45)
  userAgent  String? @map("user_agent") @db.Text

  // Results
  status          String  @db.VarChar(20) // pending|running|success|error|timeout
  executionTimeMs Int?    @map("execution_time_ms")
  output          Json?   @db.JsonB
  error           String? @db.Text

  // AI metadata
  agentSteps Int     @default(0) @map("agent_steps")
  model      String? @db.VarChar(50)

  // Relations
  tokenUsage   TokenUsage?
  logs         ExecutionLog[]

  createdAt   DateTime  @default(now()) @map("created_at")
  completedAt DateTime? @map("completed_at")

  @@index([toolId])
  @@index([status])
  @@index([ipAddress, createdAt]) // For rate limiting
  @@map("simulations")
}

/// Token usage - tracks token consumption per simulation
model TokenUsage {
  id String @id @default(cuid())

  simulationId String     @unique @map("simulation_id")
  simulation   Simulation @relation(fields: [simulationId], references: [id], onDelete: Cascade)

  inputTokens    Int      @default(0) @map("input_tokens")
  toolDescTokens Int      @default(0) @map("tool_desc_tokens")
  schemaTokens   Int      @default(0) @map("schema_tokens")
  outputTokens   Int      @default(0) @map("output_tokens")
  totalTokens    Int      @default(0) @map("total_tokens")
  estimatedCost  Decimal? @map("estimated_cost") @db.Decimal(10, 6)

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

/// Execution logs - detailed logs for each simulation
model ExecutionLog {
  id String @id @default(cuid())

  simulationId String     @map("simulation_id")
  simulation   Simulation @relation(fields: [simulationId], references: [id], onDelete: Cascade)

  timestamp DateTime @default(now())
  level     String   @db.VarChar(20) // info|warning|error|debug
  event     String   @db.VarChar(50)
  message   String   @db.Text
  metadata  Json?    @db.JsonB

  @@index([simulationId])
  @@map("execution_logs")
}

/// HealthCheck table - tracks full audit history of health checks
model HealthCheck {
  id String @id @default(cuid())

  // Relations
  toolId String @map("tool_id")
  tool   Tool   @relation(fields: [toolId], references: [id], onDelete: Cascade)

  // Check metadata
  checkType     HealthCheckType @map("check_type")
  triggerSource String          @map("trigger_source") @db.VarChar(50) // 'sync' | 'manual' | 'daily-cron'

  // Import check results
  importStatus HealthStatus @map("import_status")
  importError  String?      @map("import_error") @db.Text
  importTimeMs Int?         @map("import_time_ms")

  // Execution check results
  executionStatus HealthStatus @map("execution_status")
  executionError  String?      @map("execution_error") @db.Text
  executionTimeMs Int?         @map("execution_time_ms")
  testParameters  Json?        @map("test_parameters") @db.JsonB

  // Overall status
  overallStatus HealthStatus @map("overall_status")

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

  @@index([toolId])
  @@index([checkType])
  @@index([overallStatus])
  @@index([createdAt])
  @@map("health_checks")
}

/// Health status enum - tracks health check results
enum HealthStatus {
  UNKNOWN // Not yet checked
  HEALTHY // Passed health check
  BROKEN  // Failed health check
}

/// Health check type enum - types of health checks performed
enum HealthCheckType {
  IMPORT    // Only import check
  EXECUTION // Only execution check
  FULL      // Both import and execution
}
