// 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")
}

// ============================================
// Core Models
// ============================================

model User {
  id            String    @id @default(uuid())
  email         String    @unique
  password      String
  firstName     String?
  lastName      String?
  isActive      Boolean   @default(true)
  
  // Core Relations
  roles         UserRole[]
  refreshTokens RefreshToken[]
  
  // Video SaaS Relations
  projects          Project[]
  subscriptions     Subscription[]
  creditTransactions CreditTransaction[]
  templateUsages    TemplateUsage[]
  notifications     Notification[]
  preferences       UserPreference?
  
  // Multi-tenancy (optional)
  tenantId      String?
  tenant        Tenant?   @relation(fields: [tenantId], references: [id])
  
  // Timestamps & Soft Delete
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  deletedAt     DateTime?

  @@index([email])
  @@index([tenantId])
}

model Role {
  id          String       @id @default(uuid())
  name        String       @unique
  description String?
  isSystem    Boolean      @default(false)
  
  // Relations
  users       UserRole[]
  permissions RolePermission[]
  
  // Timestamps & Soft Delete
  createdAt   DateTime     @default(now())
  updatedAt   DateTime     @updatedAt
  deletedAt   DateTime?

  @@index([name])
}

model Permission {
  id          String           @id @default(uuid())
  name        String           @unique
  description String?
  resource    String           // e.g., "users", "posts"
  action      String           // e.g., "create", "read", "update", "delete"
  
  // Relations
  roles       RolePermission[]
  
  // Timestamps
  createdAt   DateTime         @default(now())
  updatedAt   DateTime         @updatedAt

  @@unique([resource, action])
  @@index([resource])
}

// Many-to-many: User <-> Role
model UserRole {
  id        String   @id @default(uuid())
  userId    String
  roleId    String
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  role      Role     @relation(fields: [roleId], references: [id], onDelete: Cascade)
  createdAt DateTime @default(now())

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

// Many-to-many: Role <-> Permission
model RolePermission {
  id           String     @id @default(uuid())
  roleId       String
  permissionId String
  role         Role       @relation(fields: [roleId], references: [id], onDelete: Cascade)
  permission   Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
  createdAt    DateTime   @default(now())

  @@unique([roleId, permissionId])
  @@index([roleId])
  @@index([permissionId])
}

// ============================================
// Authentication
// ============================================

model RefreshToken {
  id        String   @id @default(uuid())
  token     String   @unique
  userId    String
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  expiresAt DateTime
  createdAt DateTime @default(now())

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

// ============================================
// Multi-tenancy (Optional)
// ============================================

model Tenant {
  id        String    @id @default(uuid())
  name      String
  slug      String    @unique
  isActive  Boolean   @default(true)
  
  // Relations
  users     User[]
  
  // Timestamps & Soft Delete
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  deletedAt DateTime?

  @@index([slug])
}

// ============================================
// i18n / Translations (Optional - DB driven)
// ============================================

model Translation {
  id        String   @id @default(uuid())
  key       String
  locale    String   // e.g., "en", "tr", "de"
  value     String
  namespace String   @default("common") // e.g., "common", "errors", "validation"
  
  // Timestamps
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@unique([key, locale, namespace])
  @@index([key])
  @@index([locale])
  @@index([namespace])
}

// ============================================
// Video SaaS — Enums
// ============================================

enum ProjectStatus {
  DRAFT
  GENERATING_SCRIPT
  PENDING
  GENERATING_MEDIA
  RENDERING
  COMPLETED
  FAILED
}

enum AspectRatio {
  PORTRAIT_9_16
  SQUARE_1_1
  LANDSCAPE_16_9
}

// NOT: VideoStyle artık serbest String — enum kaldırıldı.
// Frontend 50+ stil destekliyor, DB enum kısıtlaması kaldırıldı.

enum MediaType {
  VIDEO_CLIP
  AUDIO_NARRATION
  AUDIO_MUSIC
  SUBTITLE
  THUMBNAIL
  FINAL_VIDEO
}

enum TransitionType {
  CUT
  FADE
  DISSOLVE
  SLIDE_LEFT
  SLIDE_RIGHT
  SLIDE_UP
  ZOOM_IN
  ZOOM_OUT
  WIPE
}

enum RenderJobStatus {
  QUEUED
  PROCESSING
  COMPLETED
  FAILED
  CANCELLED
}

enum RenderStage {
  VIDEO_GENERATION
  TTS_GENERATION
  MUSIC_GENERATION
  AMBIENT_GENERATION
  MEDIA_MERGE
  SUBTITLE_OVERLAY
  FINALIZATION
  UPLOAD
}

enum SourceType {
  MANUAL
  X_TWEET
  YOUTUBE
  DOCUMENT
}

// ============================================
// Video SaaS — Project & Scenes
// ============================================

model Project {
  id              String        @id @default(uuid())
  title           String        @db.VarChar(200)
  description     String?       @db.VarChar(1000)
  prompt          String        @db.VarChar(2000)
  
  // AI Generated Script
  scriptJson      Json?         // Gemini API raw JSON output
  scriptVersion   Int           @default(0)
  
  // Configuration
  language        String        @default("tr") @db.VarChar(5) // ISO 639-1
  aspectRatio     AspectRatio   @default(PORTRAIT_9_16)
  videoStyle      String        @default("CINEMATIC") @db.VarChar(50)
  cinematicReference String?    @db.VarChar(200)
  targetDuration  Int           @default(60) // saniye
  
  // SEO & Social Content (skill-enhanced)
  seoKeywords     String[]      // Hedeflenen SEO anahtar kelimeler
  seoTitle        String?       @db.VarChar(200)
  seoDescription  String?       @db.VarChar(500)
  seoSchemaJson   Json?         // VideoObject structured data
  socialContent   Json?         // { youtubeTitle, tiktokCaption, instagramCaption, twitterText }
  referenceUrl    String?       @db.VarChar(500)
  
  // İçerik Kaynağı
  sourceType      SourceType    @default(MANUAL) // MANUAL, X_TWEET, YOUTUBE
  sourceTweetData Json?         // X/Twitter tweet verisi (id, author, metrics, media)
  
  // Processing
  status          ProjectStatus @default(DRAFT)
  progress        Int           @default(0)  // 0-100
  errorMessage    String?
  
  // Output
  finalVideoUrl   String?
  thumbnailUrl    String?
  
  // Stats
  creditsUsed     Int           @default(0)
  viewCount       Int           @default(0)
  
  // Template Support
  isTemplate      Boolean       @default(false)
  templateId      String?       // Hangi şablondan klonlandı?
  template        Template?     @relation("ClonedFrom", fields: [templateId], references: [id])
  
  // Relations
  userId          String
  user            User          @relation(fields: [userId], references: [id], onDelete: Cascade)
  scenes          Scene[]
  mediaAssets     MediaAsset[]
  renderJobs      RenderJob[]
  templateEntry   Template?     @relation("SourceProject")
  
  // Timestamps & Soft Delete
  createdAt       DateTime      @default(now())
  updatedAt       DateTime      @updatedAt
  completedAt     DateTime?
  deletedAt       DateTime?

  @@index([userId])
  @@index([status])
  @@index([sourceType])
  @@index([isTemplate])
  @@index([createdAt])
}

model Scene {
  id              String         @id @default(uuid())
  order           Int            // Sahne sırası (1, 2, 3...)
  title           String?        @db.VarChar(200)
  
  // Content
  narrationText   String         @db.Text // Hedef dildeki anlatım metni
  visualPrompt    String         @db.Text // İngilizce — Higgsfield AI prompt
  subtitleText    String?        @db.Text // Ekranda görünecek altyazı
  
  // Timing
  duration        Float          @default(5.0) // saniye
  transitionType  TransitionType @default(CUT)
  
  // Relations
  projectId       String
  project         Project        @relation(fields: [projectId], references: [id], onDelete: Cascade)
  mediaAssets     MediaAsset[]
  
  // Timestamps
  createdAt       DateTime       @default(now())
  updatedAt       DateTime       @updatedAt

  @@index([projectId])
  @@index([order])
}

// ============================================
// Video SaaS — Media & Render
// ============================================

model MediaAsset {
  id           String    @id @default(uuid())
  type         MediaType
  
  // Storage
  s3Key        String?   // Cloudflare R2 / S3 object key
  s3Bucket     String?   @db.VarChar(100)
  url          String?   // Public CDN URL
  
  // Metadata
  fileName     String?   @db.VarChar(255)
  mimeType     String?   @db.VarChar(100)
  sizeBytes    BigInt?
  durationMs   Int?      // Medya süresi (video/audio için)
  
  // AI Provider Info
  aiProvider   String?   @db.VarChar(50) // higgsfield, elevenlabs, suno
  aiJobId      String?   // Dış API job ID'si
  
  // Relations
  projectId    String
  project      Project   @relation(fields: [projectId], references: [id], onDelete: Cascade)
  sceneId      String?   // null = proje genelinde (müzik, final vb.)
  scene        Scene?    @relation(fields: [sceneId], references: [id], onDelete: SetNull)
  
  // Timestamps
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt

  @@index([projectId])
  @@index([sceneId])
  @@index([type])
}

model RenderJob {
  id               String          @id @default(uuid())
  status           RenderJobStatus @default(QUEUED)
  currentStage     RenderStage?
  
  // Queue Info
  queueName        String          @default("video-generation") @db.VarChar(100)
  bullJobId        String?         @db.VarChar(100) // BullMQ job ID
  
  // Retry
  attemptNumber    Int             @default(1)
  maxAttempts      Int             @default(3)
  
  // Processing
  workerHostname   String?         @db.VarChar(100)
  processingTimeMs Int?            // Toplam render süresi
  errorMessage     String?
  
  // Output
  finalVideoUrl    String?
  finalVideoS3Key  String?
  
  // Relations
  projectId        String
  project          Project     @relation(fields: [projectId], references: [id], onDelete: Cascade)
  logs             RenderLog[]
  
  // Timestamps
  createdAt        DateTime    @default(now())
  updatedAt        DateTime    @updatedAt
  startedAt        DateTime?
  completedAt      DateTime?

  @@index([projectId])
  @@index([status])
  @@index([bullJobId])
}

model RenderLog {
  id           String      @id @default(uuid())
  stage        RenderStage
  level        String      @default("info") @db.VarChar(10) // info, warn, error
  message      String      @db.Text
  durationMs   Int?        // Bu aşamanın süresi
  metadata     Json?       // Ek JSON veri
  
  // Relations
  renderJobId  String
  renderJob    RenderJob   @relation(fields: [renderJobId], references: [id], onDelete: Cascade)
  
  // Timestamps
  createdAt    DateTime    @default(now())

  @@index([renderJobId])
  @@index([stage])
}

// ============================================
// Video SaaS — Template Marketplace
// ============================================

model Template {
  id                String          @id @default(uuid())
  
  // Display
  title             String          @db.VarChar(200)
  description       String?         @db.VarChar(500)
  thumbnailUrl      String?
  previewVideoUrl   String?
  
  // Categorization
  category          String          @default("general") @db.VarChar(50)
  tags              String[]        // PostgreSQL array
  language          String          @default("tr") @db.VarChar(5)
  
  // Source
  originalProjectId String          @unique
  originalProject   Project         @relation("SourceProject", fields: [originalProjectId], references: [id])
  
  // Stats
  usageCount        Int             @default(0)
  rating            Float           @default(0)
  ratingCount       Int             @default(0)
  isFeatured        Boolean         @default(false)
  isPublished       Boolean         @default(true)
  
  // Relations
  clonedProjects    Project[]       @relation("ClonedFrom")
  usages            TemplateUsage[]
  
  // Timestamps
  createdAt         DateTime        @default(now())
  updatedAt         DateTime        @updatedAt

  @@index([category])
  @@index([language])
  @@index([isFeatured])
  @@index([usageCount])
}

model TemplateUsage {
  id               String   @id @default(uuid())
  templateId       String
  template         Template @relation(fields: [templateId], references: [id], onDelete: Cascade)
  userId           String
  user             User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  clonedProjectId  String?  // Oluşturulan projenin ID'si
  
  createdAt        DateTime @default(now())

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

// ============================================
// Video SaaS — Billing & Credits
// ============================================

model Plan {
  id              String         @id @default(uuid())
  name            String         @unique @db.VarChar(50) // free, pro, business
  displayName     String         @db.VarChar(100)
  description     String?        @db.VarChar(500)
  
  // Pricing
  monthlyPrice    Int            @default(0)     // cent cinsinden (1900 = $19)
  yearlyPrice     Int?                            // Yıllık indirimli fiyat
  currency        String         @default("usd") @db.VarChar(3)
  
  // Limits
  monthlyCredits  Int            @default(3)
  maxDuration     Int            @default(30)     // saniye
  maxResolution   String         @default("720p") @db.VarChar(10)
  maxProjects     Int            @default(5)
  
  // Stripe
  stripePriceId       String?    @db.VarChar(100)
  stripeYearlyPriceId String?    @db.VarChar(100)
  
  // Features
  features        Json?          // { "templates": true, "priorityQueue": false, ... }
  isActive        Boolean        @default(true)
  sortOrder       Int            @default(0)
  
  // Relations
  subscriptions   Subscription[]
  
  // Timestamps
  createdAt       DateTime       @default(now())
  updatedAt       DateTime       @updatedAt

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

model Subscription {
  id                    String   @id @default(uuid())
  status                String   @default("active") @db.VarChar(20) // active, canceled, past_due, trialing
  
  // Stripe
  stripeSubscriptionId  String?  @unique @db.VarChar(100)
  stripeCustomerId      String?  @db.VarChar(100)
  
  // Billing Cycle
  currentPeriodStart    DateTime?
  currentPeriodEnd      DateTime?
  cancelAtPeriodEnd     Boolean  @default(false)
  
  // Relations
  userId                String
  user                  User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  planId                String
  plan                  Plan     @relation(fields: [planId], references: [id])
  
  // Timestamps
  createdAt             DateTime @default(now())
  updatedAt             DateTime @updatedAt
  canceledAt            DateTime?

  @@index([userId])
  @@index([planId])
  @@index([stripeSubscriptionId])
  @@index([status])
}

model CreditTransaction {
  id          String   @id @default(uuid())
  amount      Int      // Pozitif: ekleme, Negatif: harcama
  type        String   @db.VarChar(30) // grant, usage, refund, bonus
  description String?  @db.VarChar(200)
  
  // Relations
  userId      String
  user        User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  projectId   String?  // Hangi projede harcandı
  
  // Balance Snapshot
  balanceAfter Int     @default(0)
  
  // Timestamps
  createdAt   DateTime @default(now())

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

// ============================================
// Video SaaS — User Preferences & Notifications
// ============================================

model UserPreference {
  id                String  @id @default(uuid())
  
  // Defaults
  defaultLanguage   String  @default("tr") @db.VarChar(5)
  defaultVideoStyle String  @default("CINEMATIC") @db.VarChar(50)
  defaultDuration   Int     @default(60)
  
  // UI
  theme             String  @default("dark") @db.VarChar(10)
  emailNotifications Boolean @default(true)
  pushNotifications  Boolean @default(true)
  
  // Relations
  userId            String  @unique
  user              User    @relation(fields: [userId], references: [id], onDelete: Cascade)
  
  // Timestamps
  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt

  @@index([userId])
}

model Notification {
  id        String   @id @default(uuid())
  type      String   @db.VarChar(30) // render_complete, render_failed, credit_low, system
  title     String   @db.VarChar(200)
  message   String?  @db.Text
  isRead    Boolean  @default(false)
  metadata  Json?    // { projectId, renderJobId, ... }
  
  // Relations
  userId    String
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  
  // Timestamps
  createdAt DateTime @default(now())
  readAt    DateTime?

  @@index([userId])
  @@index([isRead])
  @@index([createdAt])
}
