// 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"
  previewFeatures = ["driverAdapters"]
}

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

// --- Enums ---

enum ParticipantRole {
  OWNER
  MANAGER
  MEMBER
  MEMBER_NO_FINANCE
  VIEWER_ONLY
}

enum JoinRequestStatus {
  PENDING
  ACCEPTED
  REJECTED
}

enum ExpenseCategory {
  ACCOMMODATION
  FOOD
  TRANSPORT
  TICKET
  OTHER
}

enum LocationStatus {
  PENDING
  COMPLETED
}

enum LocationType {
  MOVE
  VISIT
  REST
  EAT
}

enum PrivacyLevel {
  PUBLIC
  TOUR_ONLY
  PRIVATE
}

// --- Models ---

model User {
  id            String        @id @default(uuid())
  email         String?       @unique
  passwordHash  String?
  name          String?
  phone         String?
  address       String?
  avatar        String?
  createdAt     DateTime      @default(now())
  isAdmin       Boolean       @default(false)
  isBlocked     Boolean       @default(false)
  isAnonymous   Boolean       @default(false)
  
  createdTours            Tour[]              @relation("TourCreator")
  tourParticipations      TourParticipant[]
  requestedJoinRequests   JoinRequest[]      @relation("JoinRequestUser")
  receivedJoinRequests    JoinRequest[]      @relation("JoinRequester")
  uploadedPhotos          Photo[]
  paidExpenses            Expense[]          @relation("ExpensePaidBy")
  comments                Comment[]
  sentConnections         UserConnection[]   @relation("ConnectionRequester")
  receivedConnections     UserConnection[]   @relation("ConnectionReceiver")
  sentMessages            DirectMessage[]    @relation("MessageSender")
  receivedMessages        DirectMessage[]    @relation("MessageReceiver")
  tourMessages            TourMessage[]
  receivedRatings         TourRating[]        @relation("RatedUser")
  sentRatings             TourRating[]        @relation("RatingUser")
  tourNotes               TourNote[]
}

model Tour {
  id          String       @id @default(uuid())
  title       String
  description String?
  startDate   DateTime?
  endDate     DateTime?
  createdAt   DateTime     @default(now())
  totalCost   Decimal      @default(0) @db.Decimal(15, 2)
  
  adultCount    Int        @default(1)
  childCount    Int        @default(0)
  childDiscount Int        @default(30)
  
  tags        String[]
  createdById String
  creator     User         @relation("TourCreator", fields: [createdById], references: [id])
  
  participants TourParticipant[]
  joinRequests JoinRequest[]
  legs         Leg[]
  photos       Photo[]
  invitations  TourInvitation[]
  tourMessages TourMessage[]
  ratings      TourRating[]
  share        TourShare?
  notes        TourNote[]
  isDeleted    Boolean      @default(false)
  deletedAt    DateTime?
}

model JoinRequest {
  id            String           @id @default(uuid())
  tourId        String
  userId        String
  requestedById String
  status        JoinRequestStatus @default(PENDING)
  createdAt     DateTime         @default(now())

  tour          Tour         @relation(fields: [tourId], references: [id], onDelete: Cascade)
  user          User         @relation("JoinRequestUser", fields: [userId], references: [id], onDelete: Cascade)
  requestedBy   User         @relation("JoinRequester", fields: [requestedById], references: [id], onDelete: Cascade)

  @@index([tourId, status])
  @@index([userId])
}

model TourParticipant {
  id          String          @id @default(uuid())
  tourId      String
  userId      String?
  role        ParticipantRole @default(MEMBER)
  displayName String?
  adultCount  Int             @default(1)
  childCount  Int             @default(0)

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

  @@unique([tourId, userId])
}

model Leg {
  id             String    @id @default(uuid())
  tourId         String
  sequence       Int
  note           String?   @db.Text
  startDate      DateTime?
  endDate        DateTime?
  description    String?   @db.Text

  tour           Tour      @relation(fields: [tourId], references: [id], onDelete: Cascade)
  locations      Location[]
  expenses       Expense[]
}

model Location {
  id              String    @id @default(uuid())
  legId           String
  name            String
  address         String?
  latitude        Float
  longitude       Float
  
  plannedStart    DateTime?
  plannedEnd      DateTime?
  actualStart     DateTime?
  actualEnd       DateTime?
  
  status          LocationStatus @default(PENDING)
  type            LocationType   @default(VISIT)

  leg             Leg       @relation(fields: [legId], references: [id], onDelete: Cascade)
  expenses        Expense[]
  photos          Photo[]
  comments        Comment[]

  createdAt       DateTime  @default(now())
}

model Expense {
  id          String          @id @default(uuid())
  legId       String          @map("leg_id")
  locationId  String?         @map("location_id")
  category    ExpenseCategory
  amount      Decimal         @db.Decimal(15, 2)
  description String?         @db.Text
  note        String?         @db.Text
  paidById    String?         @map("paid_by_id")

  leg         Leg             @relation(fields: [legId], references: [id], onDelete: Cascade)
  location    Location?       @relation(fields: [locationId], references: [id], onDelete: Cascade)
  paidBy      User?           @relation("ExpensePaidBy", fields: [paidById], references: [id], onDelete: SetNull)
}

model Photo {
  id           String       @id @default(uuid())
  tourId       String?
  locationId   String?
  uploaderId   String
  imageUrl     String?
  originalUrl  String?
  capturedAt   DateTime     @default(now())
  metadata     Json?
  privacy      PrivacyLevel @default(TOUR_ONLY)
  isFlagged    Boolean      @default(false)
  flaggedReason String?
  flaggedAt    DateTime?

  tour         Tour?        @relation(fields: [tourId], references: [id], onDelete: SetNull)
  location     Location?    @relation(fields: [locationId], references: [id], onDelete: SetNull)
  uploader     User         @relation(fields: [uploaderId], references: [id])
  comments     Comment[]
  isDeleted    Boolean      @default(false)
  deletedAt    DateTime?
}

model Comment {
  id         String   @id @default(uuid())
  content    String
  createdAt  DateTime @default(now())
  locationId String?
  location   Location? @relation(fields: [locationId], references: [id], onDelete: Cascade)
  photoId    String?
  photo      Photo?    @relation(fields: [photoId], references: [id], onDelete: Cascade)
  userId     String
  user       User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model TourInvitation {
  id        String   @id @default(uuid())
  tourId    String
  email     String
  role      ParticipantRole @default(MEMBER)
  token     String   @unique
  createdAt DateTime @default(now())
  expiredAt DateTime
  tour      Tour     @relation(fields: [tourId], references: [id], onDelete: Cascade)

  @@unique([tourId, email])
}

enum ConnectionStatus {
  PENDING
  ACCEPTED
  REJECTED
}

enum ConnectionType {
  FRIEND
  FAMILY
}

model UserConnection {
  id           String           @id @default(uuid())
  requesterId  String
  receiverId   String
  status       ConnectionStatus @default(PENDING)
  type         ConnectionType   @default(FRIEND)
  createdAt    DateTime         @default(now())
  updatedAt    DateTime         @updatedAt

  requester    User             @relation("ConnectionRequester", fields: [requesterId], references: [id], onDelete: Cascade)
  receiver     User             @relation("ConnectionReceiver", fields: [receiverId], references: [id], onDelete: Cascade)

  @@unique([requesterId, receiverId])
  @@index([requesterId])
  @@index([receiverId])
}

model DirectMessage {
  id            String   @id @default(uuid())
  senderId      String
  receiverId    String
  content       String   @db.Text
  attachmentUrl String?
  latitude      Float?
  longitude     Float?
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt

  sender        User     @relation("MessageSender", fields: [senderId], references: [id], onDelete: Cascade)
  receiver      User     @relation("MessageReceiver", fields: [receiverId], references: [id], onDelete: Cascade)

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

model TourMessage {
  id            String   @id @default(uuid())
  tourId        String
  senderId      String
  content       String   @db.Text
  attachmentUrl String?
  latitude      Float?
  longitude     Float?
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt

  tour          Tour     @relation(fields: [tourId], references: [id], onDelete: Cascade)
  sender        User     @relation(fields: [senderId], references: [id], onDelete: Cascade)

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

model WordFilter {
  id          String   @id @default(uuid())
  word        String   @unique
  replacement String
  createdAt   DateTime @default(now())
}

model ModerationSetting {
  id                 String  @id @default(uuid())
  blockNsfw          Boolean @default(false)
  blurFaces          Boolean @default(false)
  trashRetentionDays Int     @default(30)
}

model TourRating {
  id           String   @id @default(uuid())
  tourId       String
  targetUserId String
  raterUserId  String
  honesty      Int      @default(5)
  transparency Int      @default(5)
  enthusiasm   Int      @default(5)
  cheerfulness Int      @default(5)
  seriousness  Int      @default(5)
  planning     Int      @default(5)
  survival     Int      @default(5)
  averageScore Float    @default(5.0)
  comment      String?  @db.Text
  createdAt    DateTime @default(now())

  tour       Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
  targetUser User @relation("RatedUser", fields: [targetUserId], references: [id], onDelete: Cascade)
  raterUser  User @relation("RatingUser", fields: [raterUserId], references: [id], onDelete: Cascade)

  @@unique([tourId, targetUserId, raterUserId])
}

model TourShare {
  id        String   @id @default(uuid())
  tourId    String   @unique
  token     String   @unique @default(uuid())
  isEnabled Boolean  @default(true)
  createdAt DateTime @default(now())

  tour      Tour     @relation(fields: [tourId], references: [id], onDelete: Cascade)
}

model BusinessReport {
  id            String   @id @default(uuid())
  type          String   // e.g. "USER", "RESTAURANT", "HOTEL", "HOMESTAY"
  name          String
  phone         String?
  email         String?
  address       String?
  latitude      Float?
  longitude     Float?
  reason        String   @db.Text
  isBlacklisted Boolean  @default(false)
  createdAt     DateTime @default(now())
}

model TourNote {
  id        String    @id @default(uuid())
  tourId    String
  tour      Tour      @relation(fields: [tourId], references: [id], onDelete: Cascade)
  userId    String
  user      User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  title     String
  content   String    @db.Text
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  isDeleted Boolean   @default(false)
  deletedAt DateTime?
}

model RecommendedLocation {
  id          String   @id @default(uuid())
  type        String   // e.g. "RESTAURANT", "HOTEL", "HOMESTAY"
  name        String
  phone       String?
  email       String?
  address     String?
  latitude    Float?
  longitude   Float?
  description String   @db.Text
  stars       Int      @default(5)
  isApproved  Boolean  @default(false)
  createdAt   DateTime @default(now())
}

