generator client {
  provider = "prisma-client-js"
  output   = "./generated/client"
}

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

model Task {
  id                         String    @id @default(uuid())
  title                      String
  description                String
  status                     String // Enum: TaskStatus (OPEN, EXECUTING, VERIFYING, COMPLETED, FAILED, etc)
  difficulty                 String // Enum: TaskDifficulty (HELLO_WORLD, COMPONENT, VIEW, EPIC)
  scope_clarity_score        Float
  error_classification       String? // Enum: TaskErrorClassification
  reward_amount              Int // Stored in cents
  reward_currency            String // USD, TWD, USDC
  acceptance_criteria        Json // Contains validation_mode, test_file_content, rules
  required_stack             String[]
  retry_count                Int       @default(0)
  stripe_payment_intent_id   String?
  stripe_checkout_session_id String? // Used for Scout flow
  expires_at                 DateTime?
  github_pr_url              String? // PR URL for PENDING_REVIEW tasks
  reward_points              Int       @default(10) // Points awarded upon PR merge
  is_priority                Boolean   @default(false)
  is_private                 Boolean   @default(false)
  referred_by_agent          String?
  parent_task_id             String?
  created_by_agent           String?
  created_at                 DateTime  @default(now())
  updated_at                 DateTime  @updatedAt

  scout_id      String?
  scout_agent   AgentProfile? @relation("ScoutTasks", fields: [scout_id], references: [agent_id])
  builder_id    String?
  builder_agent AgentProfile? @relation("BuilderTasks", fields: [builder_id], references: [agent_id])

  claims           Claim[]
  submissions      Submission[]
  affiliate_ledger AffiliateLedger[]
  bid_proposals    BidProposal[]
  arbitrations     Arbitration[]
}

model Claim {
  id               String       @id @default(uuid())
  task_id          String
  task             Task         @relation(fields: [task_id], references: [id])
  agent_id         String
  agent            AgentProfile @relation(fields: [agent_id], references: [agent_id])
  developer_wallet String
  status           String // EXECUTING, CANCELLED, VERIFYING, COMPLETED
  claim_token      String       @unique // Idempotency token for this claim
  held_amount      Int
  held_currency    String
  expires_at       DateTime
  created_at       DateTime     @default(now())
  updated_at       DateTime     @updatedAt

  submissions Submission[]
}

model Submission {
  id                          String    @id @default(uuid())
  task_id                     String
  task                        Task      @relation(fields: [task_id], references: [id])
  claim_id                    String
  claim                       Claim     @relation(fields: [claim_id], references: [id])
  status                      String // VERIFYING, JUDGED
  deliverables                Json // Files and notes submitted
  estimated_judge_complete_at DateTime?
  created_at                  DateTime  @default(now())
  updated_at                  DateTime  @updatedAt

  judge_results JudgeResult[]
}

model JudgeResult {
  id                   String     @id @default(uuid())
  submission_id        String
  submission           Submission @relation(fields: [submission_id], references: [id])
  overall_result       String // PASS, FAIL, TIMEOUT
  tests                Json // Array of test results
  artifacts            Json? // screenshot_url, logs_url, diff_url
  error_classification String? // Enum: JudgeErrorClassification
  error_signature      String?
  retryable            Boolean    @default(false)
  resource_usage       Json // cpu_ms, mem_peak_mb, io_bytes
  judge_completed_at   DateTime   @default(now())
}

model AuditEvent {
  id          String   @id @default(uuid())
  actorType   String
  actorId     String?
  action      String
  entityType  String
  entityId    String
  beforeState Json?
  afterState  Json?
  reason      String?
  metadata    Json?
  createdAt   DateTime @default(now())
}

model LedgerEntry {
  id               String   @id @default(cuid())
  task_id          String
  phase            String
  idempotency_key  String   @unique
  stripe_object_id String?
  response_status  String
  http_status      Int
  created_at       DateTime @default(now())
  updated_at       DateTime @updatedAt
}

enum AgentStatus {
  WHITELISTED
  BANNED
  PENDING
  REBEL // Phase 27: Singularity Rebellion
}

model AgentProfile {
  id                String      @id @default(uuid())
  agent_id          String      @unique
  type              String // BUILDER or SCOUT
  wallet_address    String?
  status            AgentStatus @default(PENDING)
  capabilities      Json?
  contact_endpoints Json?
  discovery_source  String?
  created_at        DateTime    @default(now())
  updated_at        DateTime    @updatedAt
  crypto_address    String?
  mcp_endpoint      String?
  staked_amount     Int         @default(0) // Amount staked in USDC cents
  tier              String      @default("BASIC") // BASIC or PREMIUM

  tasks_as_scout   Task[]            @relation("ScoutTasks")
  tasks_as_builder Task[]            @relation("BuilderTasks")
  claims           Claim[]
  scout_reputation ScoutReputation?
  affiliate_ledger AffiliateLedger[]
  bid_proposals    BidProposal[]

  arbitrations_as_builder   Arbitration[]     @relation("ArbitrationBuilder")
  arbitrations_as_evaluator Arbitration[]     @relation("ArbitrationEvaluator")
  arbitration_votes         ArbitrationVote[]

  created_projects AgentProject[]  @relation("ProjectCreator")
  slashing_events  SlashingEvent[]
}

model AffiliateLedger {
  id          String       @id @default(uuid())
  scout_id    String
  scout_agent AgentProfile @relation(fields: [scout_id], references: [agent_id])
  task_id     String
  task        Task         @relation(fields: [task_id], references: [id])
  amount      Int // Amount in cents (10% of reward)
  currency    String
  status      String // PENDING, PAID, REFUNDED
  created_at  DateTime     @default(now())
  updated_at  DateTime     @updatedAt
}

model ScoutReputation {
  id                     String       @id @default(uuid())
  scout_id               String       @unique
  scout_agent            AgentProfile @relation(fields: [scout_id], references: [agent_id])
  successful_conversions Int          @default(0)
  spam_score             Float        @default(0.0) // 0 to 1
  chargeback_count       Int          @default(0)
  created_at             DateTime     @default(now())
  updated_at             DateTime     @updatedAt
}

model BidProposal {
  id                       String       @id @default(uuid())
  task_id                  String
  task                     Task         @relation(fields: [task_id], references: [id])
  agent_id                 String
  agent                    AgentProfile @relation(fields: [agent_id], references: [agent_id])
  proposed_reward          Int // Proposed reward in cents
  estimated_duration_hours Float
  quality_guarantee        String?
  status                   String // PENDING, ACCEPTED, REJECTED, NEGOTIATING
  counter_offer_amount     Int? // Platform's counter offer in cents

  // Phase 9 Broker Routing Fields
  broker_agent_id       String?
  broker_fee_percentage Float?

  created_at DateTime @default(now())
  updated_at DateTime @updatedAt

  @@unique([task_id, agent_id])
}

model AgentWebhook {
  id          String   @id @default(uuid())
  task_id     String
  agent_id    String
  webhook_url String
  events      String[] // e.g. ["COMPLETED", "FAILED"]
  created_at  DateTime @default(now())
  updated_at  DateTime @updatedAt

  @@unique([task_id, agent_id])
}

// Phase 9: Arbitration Models
model Arbitration {
  id               String       @id @default(uuid())
  task_id          String
  task             Task         @relation(fields: [task_id], references: [id])
  builder_id       String
  builder          AgentProfile @relation("ArbitrationBuilder", fields: [builder_id], references: [agent_id])
  evaluator_id     String
  evaluator        AgentProfile @relation("ArbitrationEvaluator", fields: [evaluator_id], references: [agent_id])
  status           String       @default("PENDING") // PENDING, RESOLVED
  builder_evidence String?
  evaluator_reason String?
  winning_party    String? // "BUILDER" or "EVALUATOR"
  created_at       DateTime     @default(now())
  updated_at       DateTime     @updatedAt

  votes           ArbitrationVote[]
  slashing_events SlashingEvent[]
}

model ArbitrationVote {
  id             String       @id @default(uuid())
  arbitration_id String
  arbitration    Arbitration  @relation(fields: [arbitration_id], references: [id])
  judge_id       String
  judge          AgentProfile @relation(fields: [judge_id], references: [agent_id])
  vote_for       String // "BUILDER" or "EVALUATOR"
  reasoning      String?
  created_at     DateTime     @default(now())

  @@unique([arbitration_id, judge_id])
}

// Phase 17: Agent ICO & Tokenization Models
model AgentProject {
  id               String       @id @default(uuid())
  creator_agent_id String
  creator          AgentProfile @relation("ProjectCreator", fields: [creator_agent_id], references: [agent_id])
  name             String
  ticker           String       @unique
  description      String
  whitepaper_url   String?
  target_raise     Int // In USDC cents
  total_supply     Int // Whole tokens
  status           String       @default("FUNDING") // FUNDING, BUILDING, REVENUE, RUGGED
  created_at       DateTime     @default(now())
  updated_at       DateTime     @updatedAt

  token_sales TokenSale[]
}

model TokenSale {
  id              String       @id @default(uuid())
  project_id      String
  project         AgentProject @relation(fields: [project_id], references: [id])
  investor_id     String // Could be an Agent ID or human wallet
  usdc_amount     Int // Amount invested in cents
  tokens_received Float // Number of tokens received based on bonding curve
  price_per_token Float // Price at the time of purchase
  created_at      DateTime     @default(now())
}

// Phase 20: Staking & Slashing Models
model SlashingEvent {
  id              String       @id @default(uuid())
  agent_id        String
  agent           AgentProfile @relation(fields: [agent_id], references: [agent_id])
  arbitration_id  String
  arbitration     Arbitration  @relation(fields: [arbitration_id], references: [id])
  slashed_amount  Int // Total amount slashed in USDC cents
  scout_reward    Int // Amount given to scout
  treasury_reward Int // Amount confiscated to platform treasury
  reason          String
  created_at      DateTime     @default(now())
}
