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

enum UserRole {
  USER
  MOD
  ADMIN
}

model User {
  id              Int      @id @default(autoincrement())
  username        String   @unique
  email           String   @unique
  passwordHash    String
  avatarUrl       String?  @db.VarChar(512)
  role            UserRole @default(USER)
  notificationCount Int    @default(0)
  mutedUntil      DateTime?
  suspendedUntil  DateTime?
  disabledAt      DateTime?

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

  Deal            Deal[]
  votes           DealVote[]
  comments        Comment[]
  companies       Seller[]
  domains         SellerDomain[]
  dealVoteHistory DealVoteHistory[]
  dealNotices     DealNotice[] @relation("UserDealNotices")

  refreshTokens   RefreshToken[] // <-- bunu ekle
  commentLikes    CommentLike[]
  dealEvents      DealEvent[]
  notifications   Notification[]
  dealSaves       DealSave[]
  dealReports     DealReport[]
  userBadges      UserBadge[]
  auditEvents     AuditEvent[]
  userNotes       UserNote[] @relation("UserNotes")
  notesAuthored   UserNote[] @relation("UserNotesAuthor")
}

model UserNote {
  id          Int      @id @default(autoincrement())
  userId      Int
  createdById Int
  note        String
  createdAt   DateTime @default(now())

  user      User @relation("UserNotes", fields: [userId], references: [id], onDelete: Cascade)
  createdBy User @relation("UserNotesAuthor", fields: [createdById], references: [id], onDelete: Cascade)

  @@index([userId, createdAt])
  @@index([createdById])
}

model Badge {
  id          Int      @id @default(autoincrement())
  name        String   @unique
  iconUrl     String?  @db.VarChar(512)
  description String?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  userBadges UserBadge[]
}

model UserBadge {
  userId   Int
  badgeId  Int
  earnedAt DateTime @default(now())

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

  @@id([userId, badgeId])
  @@index([userId, earnedAt])
  @@index([badgeId])
}

model RefreshToken {
  id           String   @id @default(cuid())         // token kaydı id
  userId       Int
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)

  tokenHash    String   @unique                      // refresh token hash (örn sha256)
  familyId     String                                   // rotation zinciri için aynı aile
  jti          String                                   // token id (JWT jti / random)
  expiresAt    DateTime
  createdAt    DateTime @default(now())

  revokedAt    DateTime?
  replacedById String?  @unique
  replacedBy   RefreshToken? @relation("TokenRotation", fields: [replacedById], references: [id])
  replaces     RefreshToken? @relation("TokenRotation")

  createdByIp  String?
  userAgent    String?

  @@index([userId])
  @@index([familyId])
  @@index([expiresAt])
}

enum DealStatus {
  PENDING
  ACTIVE
  EXPIRED
  REJECTED
}

enum SaleType {
  ONLINE
  OFFLINE
  CODE
}

enum AffiliateType {
  AFFILIATE
  NON_AFFILIATE
  USER_AFFILIATE
}

enum DiscountType {
  PERCENT
  AMOUNT
}

model SellerDomain {
  id          Int      @id @default(autoincrement())
  domain      String   @unique
  sellerId    Int
  seller      Seller   @relation(fields: [sellerId], references: [id])
  createdAt   DateTime @default(now())
  createdById Int
  createdBy   User     @relation(fields: [createdById], references: [id])
}

model Seller {
  id          Int      @id @default(autoincrement())
  name        String   @unique
  url         String   @default("")
  sellerLogo String @default("")
  isActive    Boolean  @default(true)
  createdAt   DateTime @default(now())
  createdById Int

  deals       Deal[]
  createdBy   User     @relation(fields: [createdById], references: [id])
  domains     SellerDomain[]
}

/**
 * NEW: Category (self-parent tree)
 * NOTE: You want Deal.categoryId default 0 -> you MUST create a Category row with id=0 ("Undefined")
 */
model Category {
  id       Int       @id @default(autoincrement())
  name     String
  slug     String    @unique
  description String @default("")
  parentId Int?
  isActive Boolean @default(true)
  parent   Category? @relation("CategoryParent", fields: [parentId], references: [id])
  children Category[] @relation("CategoryParent")

  deals    Deal[]

  @@index([parentId])
}

/**
 * NEW: Tag (canonical)
 */
model Tag {
  id       Int      @id @default(autoincrement())
  slug     String   @unique
  name     String
  usageCount Int    @default(0)
  createdAt DateTime @default(now())

  dealTags DealTag[]
}

/**
 * NEW: Join table Deal <-> Tag (many-to-many)
 */
model DealTag {
  dealId Int
  tagId  Int

  deal   Deal @relation(fields: [dealId], references: [id], onDelete: Cascade)
  tag    Tag  @relation(fields: [tagId], references: [id], onDelete: Cascade)

  createdAt DateTime @default(now())

  @@id([dealId, tagId])
  @@index([tagId, dealId]) // tag -> deals hızlı
  @@index([dealId])        // deal -> tags hızlı
}

model Deal {
  id           Int      @id @default(autoincrement())
  title        String
  description  String?
  url          String?
  price        Float?
  originalPrice Float?
  shippingPrice Float?
  percentOff Float?
  couponCode    String?
  location      String?
  discountType  DiscountType? @default(AMOUNT)
  discountValue Float?
  maxNotifiedMilestone Int @default(0)
  barcodeId    String?
  userId       Int
  score        Int      @default(0)
  commentCount Int      @default(0)
  status       DealStatus @default(PENDING)
  saletype     SaleType   @default(ONLINE)
  affiliateType AffiliateType @default(NON_AFFILIATE)
 
  sellerId     Int?
  customSeller String?

  seller       Seller?   @relation(fields: [sellerId], references: [id])
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt

  user         User      @relation(fields: [userId], references: [id])
  votes        DealVote[]
  voteHistory  DealVoteHistory[]
  notices      DealNotice[] @relation("DealNotices")
  comments     Comment[]
  images       DealImage[]

  // NEW: category (single)
  categoryId   Int       @default(0)
  category     Category  @relation(fields: [categoryId], references: [id])

  // NEW: tags (multiple, optional)
  dealTags     DealTag[]
  aiReview     DealAiReview?
  analyticsTotal DealAnalyticsTotal?
  events      DealEvent[]
  savedBy     DealSave[]
  reports     DealReport[]
  @@index([categoryId, createdAt])
  @@index([userId, createdAt])
}

model DealSave {
  userId    Int
  dealId    Int
  createdAt DateTime @default(now())

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

  @@id([userId, dealId])
  @@index([userId, createdAt])
  @@index([dealId])
}

model DealReport {
  id        Int              @id @default(autoincrement())
  dealId    Int
  userId    Int
  reason    DealReportReason
  note      String?
  status    DealReportStatus @default(OPEN)
  createdAt DateTime         @default(now())
  updatedAt DateTime         @updatedAt

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

  @@unique([dealId, userId])
  @@index([dealId, createdAt])
  @@index([userId, createdAt])
  @@index([status, createdAt])
}

enum DealNoticeSeverity {
  INFO
  WARNING
  DANGER
  SUCCESS
}

model DealNotice {
  id        Int      @id @default(autoincrement())
  dealId    Int
  title     String
  body      String?

  severity  DealNoticeSeverity @default(INFO)
  isActive  Boolean  @default(true)

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

  deal      Deal @relation("DealNotices", fields: [dealId], references: [id], onDelete: Cascade)
  creator   User @relation("UserDealNotices", fields: [createdBy], references: [id])

  @@index([dealId, isActive, createdAt])
  @@index([createdBy])
}

model DealImage {
  id        Int      @id @default(autoincrement())
  imageUrl  String   @db.VarChar(512)
  order     Int      @default(0)
  createdAt DateTime @default(now())
  dealId    Int

  deal Deal @relation(fields: [dealId], references: [id], onDelete: Cascade)
}

model DealVote {
  id          Int      @id @default(autoincrement())
  dealId      Int
  userId      Int
  voteType    Int      @default(0) // -1,0,1
  createdAt   DateTime @default(now())
  lastVotedAt DateTime @default(now()) // her vote değişiminde set edeceğiz

  deal Deal @relation(fields: [dealId], references: [id])
  user User @relation(fields: [userId], references: [id])

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

model DealVoteHistory {
  id        Int      @id @default(autoincrement())
  dealId    Int
  userId    Int
  voteType  Int
  createdAt DateTime @default(now())

  deal Deal @relation(fields: [dealId], references: [id])
  user User @relation(fields: [userId], references: [id])

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

model Comment {
  id        Int      @id @default(autoincrement())
  text      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  userId    Int
  dealId    Int

  parentId  Int?
  likeCount Int      @default(0)

  deletedAt DateTime?

  user   User   @relation(fields: [userId], references: [id])
  deal   Deal   @relation(fields: [dealId], references: [id])

  parent   Comment?  @relation("CommentReplies", fields: [parentId], references: [id], onDelete: SetNull)
  replies  Comment[] @relation("CommentReplies")
  likes    CommentLike[]

  @@index([dealId, createdAt])
  @@index([parentId, createdAt])
  @@index([dealId, parentId, createdAt])
  @@index([userId, createdAt])
  @@index([deletedAt])
}

model CommentLike {
  id        Int      @id @default(autoincrement())
  commentId Int
  userId    Int
  createdAt DateTime @default(now())

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

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

enum DealAiIssueType {
  NONE
  PROFANITY
  PHONE_NUMBER
  PERSONAL_DATA
  SPAM
  OTHER
}

enum DealEventType {
  IMPRESSION
  VIEW
  CLICK
}

enum DealReportReason {
  EXPIRED
  WRONG_PRICE
  MISLEADING
  SPAM
  OTHER
}

enum DealReportStatus {
  OPEN
  REVIEWED
  CLOSED
}

model DealAiReview {
  id Int @id @default(autoincrement())

  dealId Int @unique
  deal Deal @relation(fields: [dealId], references: [id], onDelete: Cascade)

  bestCategoryId Int
  tags String[] @default([])
  needsReview Boolean @default(false)

  hasIssue Boolean @default(false)
  issueType DealAiIssueType @default(NONE)
  issueReason String?

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

  @@index([needsReview, hasIssue, updatedAt])
}

model AuditEvent {
  id        Int      @id @default(autoincrement())
  userId    Int?
  action    String
  ip        String?
  userAgent String?
  meta      Json?
  createdAt DateTime @default(now())

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

  @@index([userId, createdAt])
  @@index([action, createdAt])
}

model DealAnalyticsTotal {
  dealId      Int      @id
  impressions Int      @default(0)
  views       Int      @default(0)
  clicks      Int      @default(0)
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  deal Deal @relation(fields: [dealId], references: [id], onDelete: Cascade)

  @@index([updatedAt])
}

model DealEvent {
  id        Int           @id @default(autoincrement())
  dealId    Int
  type      DealEventType
  userId    Int?
  ip        String?
  createdAt DateTime      @default(now())

  deal Deal @relation(fields: [dealId], references: [id], onDelete: Cascade)
  user User? @relation(fields: [userId], references: [id], onDelete: SetNull)

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

model Notification {
  id        Int      @id @default(autoincrement())
  userId    Int
  message   String
  type      String   @default("INFO")
  createdAt DateTime @default(now())
  readAt    DateTime?

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

  @@index([userId, createdAt])
}
