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

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

enum Category {
  ELECTRONICS
  FURNITURE
  CLOTHING
  HOME_GARDEN
  SPORTS
  BOOKS
  GAMES
  VEHICLES
  OTHER
}

enum ListingCondition {
  NEW
  LIKE_NEW
  GENTLY_USED
  USED
  FAIR
}

enum ListingStatus {
  DRAFT
  ACTIVE
  SOLD
  DELETED
}

enum OfferStatus {
  PENDING
  ACCEPTED
  DECLINED
  COUNTERED
}

enum NotificationType {
  NEW_OFFER
  OFFER_ACCEPTED
  OFFER_DECLINED
  ITEM_SOLD
  NEW_MESSAGE
  ITEM_FAVORITED
}

enum PaymentStatus {
  PENDING
  COMPLETED
  FAILED
  REFUNDED
}

model User {
  id            String    @id @default(cuid())
  email         String    @unique
  passwordHash  String
  fullName      String
  nickname      String?
  avatar        String?
  phone         String?
  location      String?
  bio           String?
  rating        Float     @default(0)
  ratingCount   Int       @default(0)
  showEmail     Boolean   @default(false)
  showPhone     Boolean   @default(true)
  showLocation  Boolean   @default(true)
  showOnline    Boolean   @default(true)
  showRating    Boolean   @default(true)
  twoFactorEnabled Boolean @default(false)
  isActive      Boolean   @default(true)
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt

  sessions      Session[]
  listings      Listing[]
  images        ListingImage[]
  sentOffers    Offer[]   @relation("BuyerOffers")
  receivedOffers Offer[]  @relation("SellerOffers")
  conversations1 Conversation[] @relation("User1Conversations")
  conversations2 Conversation[] @relation("User2Conversations")
  messages      Message[]
  favorites     Favorite[]
  notifications Notification[]
  payments      Payment[]
  blockedUsers  BlockedUser[] @relation("Blocker")
  blockedBy     BlockedUser[] @relation("Blocked")
}

model Session {
  id           String   @id @default(cuid())
  userId       String
  refreshToken String   @unique
  userAgent    String?
  ipAddress    String?
  expiresAt    DateTime
  createdAt    DateTime @default(now())

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

  @@index([userId])
}

model Listing {
  id          String           @id @default(cuid())
  title       String
  description String
  price       Float
  obo         Boolean          @default(false)
  category    Category
  condition   ListingCondition
  status      ListingStatus    @default(DRAFT)
  location    String
  viewCount   Int              @default(0)
  sellerId    String
  createdAt   DateTime         @default(now())
  updatedAt   DateTime         @updatedAt

  seller       User           @relation(fields: [sellerId], references: [id], onDelete: Cascade)
  images       ListingImage[]
  offers       Offer[]
  conversations Conversation[]
  favorites    Favorite[]
  payments     Payment[]

  @@index([sellerId])
  @@index([category])
  @@index([status])
  @@index([createdAt])
}

model ListingImage {
  id        String  @id @default(cuid())
  url       String
  order     Int     @default(0)
  listingId String
  uploadedBy String

  listing Listing @relation(fields: [listingId], references: [id], onDelete: Cascade)
  user    User    @relation(fields: [uploadedBy], references: [id], onDelete: Cascade)

  @@index([listingId])
}

model Offer {
  id            String      @id @default(cuid())
  amount        Float
  message       String?
  status        OfferStatus @default(PENDING)
  counterAmount Float?
  buyerId       String
  sellerId      String
  listingId     String
  createdAt     DateTime    @default(now())
  updatedAt     DateTime    @updatedAt

  buyer   User    @relation("BuyerOffers", fields: [buyerId], references: [id], onDelete: Cascade)
  seller  User    @relation("SellerOffers", fields: [sellerId], references: [id], onDelete: Cascade)
  listing Listing @relation(fields: [listingId], references: [id], onDelete: Cascade)

  @@index([buyerId])
  @@index([sellerId])
  @@index([listingId])
}

model Conversation {
  id        String   @id @default(cuid())
  user1Id   String
  user2Id   String
  listingId String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  user1    User      @relation("User1Conversations", fields: [user1Id], references: [id], onDelete: Cascade)
  user2    User      @relation("User2Conversations", fields: [user2Id], references: [id], onDelete: Cascade)
  listing  Listing?  @relation(fields: [listingId], references: [id], onDelete: SetNull)
  messages Message[]

  @@unique([user1Id, user2Id, listingId])
  @@index([user1Id])
  @@index([user2Id])
}

model Message {
  id             String   @id @default(cuid())
  content        String
  senderId       String
  conversationId String
  isRead         Boolean  @default(false)
  offerAmount    Float?
  createdAt      DateTime @default(now())

  sender       User         @relation(fields: [senderId], references: [id], onDelete: Cascade)
  conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)

  @@index([conversationId])
  @@index([senderId])
}

model Favorite {
  id        String   @id @default(cuid())
  userId    String
  listingId String
  createdAt DateTime @default(now())

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

  @@unique([userId, listingId])
}

model Notification {
  id        String           @id @default(cuid())
  userId    String
  type      NotificationType
  title     String
  body      String
  data      Json?
  isRead    Boolean          @default(false)
  createdAt DateTime         @default(now())

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

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

model Payment {
  id              String        @id @default(cuid())
  userId          String
  listingId       String
  stripePaymentId String?       @unique
  amount          Float
  status          PaymentStatus @default(PENDING)
  createdAt       DateTime      @default(now())
  updatedAt       DateTime      @updatedAt

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

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

model BlockedUser {
  id        String   @id @default(cuid())
  blockerId String
  blockedId String
  createdAt DateTime @default(now())

  blocker User @relation("Blocker", fields: [blockerId], references: [id], onDelete: Cascade)
  blocked User @relation("Blocked", fields: [blockedId], references: [id], onDelete: Cascade)

  @@unique([blockerId, blockedId])
}
