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

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

model User {
  id              String            @id @default(cuid())
  email           String?           @unique
  phone           String?           @unique
  passwordHash    String
  role            UserRole
  status          AccountStatus     @default(PENDING)
  emailVerifiedAt DateTime?
  phoneVerifiedAt DateTime?
  createdAt       DateTime          @default(now())
  updatedAt       DateTime          @updatedAt
  addresses       Address[]
  auditLogs       AuditLog[]
  customer        Customer?
  driver          Driver?
  financialLedger FinancialLedger[]
  notifications   Notification[]
  restaurant      Restaurant?
  supportTickets  SupportTicket[]
  wallet          Wallet?
}

model Customer {
  id               String                @id @default(cuid())
  userId           String                @unique
  fullName         String
  avatarUrl        String?
  defaultAddressId String?
  createdAt        DateTime              @default(now())
  updatedAt        DateTime              @updatedAt
  user             User                  @relation(fields: [userId], references: [id])
  orders           Order[]
  subscriptions    PremiumSubscription[]
  reviews          Review[]
  wallet           Wallet?
}

model Driver {
  id                 String           @id @default(cuid())
  userId             String           @unique
  fullName           String
  avatarUrl          String?
  rating             Decimal          @default(5)
  documentNumber     String           @unique
  cnhUrl             String?
  vehicleDocumentUrl String?
  vehiclePlate       String?
  vehicleModel       String?
  pixKey             String?
  status             AccountStatus    @default(PENDING)
  isOnline           Boolean          @default(false)
  createdAt          DateTime         @default(now())
  updatedAt          DateTime         @updatedAt
  deliveries         Delivery[]
  routes             DeliveryRoute[]
  user               User             @relation(fields: [userId], references: [id])
  locations          DriverLocation[]
  reviews            Review[]
  wallet             Wallet?
}

model Restaurant {
  id                   String                       @id @default(cuid())
  userId               String                       @unique
  name                 String
  slug                 String                       @unique
  description          String?
  documentNumber       String                       @unique
  pixKey               String?
  street               String?
  number               String?
  complement           String?
  state                String?
  zipCode              String?
  commissionPercentage Decimal                      @default(12.5)
  serviceFeePercentage Decimal                      @default(0)
  baseDeliveryFee      Decimal                      @default(5)
  pricePerKm           Decimal                      @default(1.5)
  latitude             Decimal?
  longitude            Decimal?
  city                 String?
  neighborhood         String?
  acceptsCashOnDelivery Boolean                     @default(false)
  isOpen               Boolean                      @default(true)
  isPaused             Boolean                      @default(false)
  status               AccountStatus                @default(PENDING)
  companyContractUrl   String?
  businessLicenseUrl   String?
  ownerDocumentUrl     String?
  bankProofUrl         String?
  documentReviewNotes  String?
  documentsSubmittedAt DateTime?
  approvedAt           DateTime?
  rejectedAt           DateTime?
  coverImageUrl        String?
  logoUrl              String?
  createdAt            DateTime                     @default(now())
  updatedAt            DateTime                     @updatedAt
  orders               Order[]
  products             Product[]
  productCategories    ProductCategory[]
  coupons              Coupon[]
  promotions           Promotion[]
  user                 User                         @relation(fields: [userId], references: [id])
  categories           RestaurantCategory[]
  openingHours         RestaurantOpeningHour[]
  planSubscriptions    RestaurantPlanSubscription[]
  reviews              Review[]
  sponsoredProfiles    SponsoredRestaurant[]
  wallet               Wallet?
}

model RestaurantCategory {
  id           String     @id @default(cuid())
  restaurantId String
  name         String
  description  String?
  createdAt    DateTime   @default(now())
  updatedAt    DateTime   @updatedAt
  restaurant   Restaurant @relation(fields: [restaurantId], references: [id])
}

model ProductCategory {
  id           String     @id @default(cuid())
  restaurantId String
  name         String
  sortOrder    Int        @default(0)
  createdAt    DateTime   @default(now())
  updatedAt    DateTime   @updatedAt
  products     Product[]
  restaurant   Restaurant @relation(fields: [restaurantId], references: [id])
}

model Product {
  id           String              @id @default(cuid())
  restaurantId String
  categoryId   String?
  name         String
  description  String?
  imageUrl     String?
  price        Decimal
  isActive     Boolean             @default(true)
  createdAt    DateTime            @default(now())
  updatedAt    DateTime            @updatedAt
  orderItems   OrderItem[]
  category     ProductCategory?    @relation(fields: [categoryId], references: [id])
  restaurant   Restaurant          @relation(fields: [restaurantId], references: [id])
  additionals  ProductAdditional[]
  variations   ProductVariation[]
}

model ProductAdditional {
  id        String  @id @default(cuid())
  productId String
  name      String
  price     Decimal
  isActive  Boolean @default(true)
  product   Product @relation(fields: [productId], references: [id])
}

model ProductVariation {
  id        String  @id @default(cuid())
  productId String
  name      String
  price     Decimal
  product   Product @relation(fields: [productId], references: [id])
}

model Order {
  id              String            @id @default(cuid())
  customerId      String
  restaurantId    String
  addressId       String?
  couponId        String?
  status          OrderStatus       @default(CREATED)
  subtotal        Decimal
  deliveryFee     Decimal
  serviceFee      Decimal           @default(0)
  discountAmount  Decimal           @default(0)
  total           Decimal
  notes           String?
  createdAt       DateTime          @default(now())
  updatedAt       DateTime          @updatedAt
  delivery        Delivery?
  deliveryRoute   DeliveryRoute?
  driverLocations DriverLocation[]
  financialLedger FinancialLedger[]
  address         Address?          @relation(fields: [addressId], references: [id])
  coupon          Coupon?           @relation(fields: [couponId], references: [id])
  customer        Customer          @relation(fields: [customerId], references: [id])
  restaurant      Restaurant        @relation(fields: [restaurantId], references: [id])
  items           OrderItem[]
  payment         Payment?
  reviews         Review[]
}

model OrderItem {
  id         String  @id @default(cuid())
  orderId    String
  productId  String
  quantity   Int
  unitPrice  Decimal
  totalPrice Decimal
  notes      String?
  order      Order   @relation(fields: [orderId], references: [id])
  product    Product @relation(fields: [productId], references: [id])
}

model Payment {
  id                String        @id @default(cuid())
  orderId           String        @unique
  method            PaymentMethod
  status            PaymentStatus @default(PENDING)
  externalReference String?
  amount            Decimal
  createdAt         DateTime      @default(now())
  updatedAt         DateTime      @updatedAt
  order             Order         @relation(fields: [orderId], references: [id])
  transactions      Transaction[]
}

model Transaction {
  id        String   @id @default(cuid())
  paymentId String
  type      String
  amount    Decimal
  metadata  Json?
  createdAt DateTime @default(now())
  payment   Payment  @relation(fields: [paymentId], references: [id])
}

model Withdrawal {
  id          String           @id @default(cuid())
  walletId    String
  amount      Decimal
  feeAmount   Decimal          @default(0)
  status      WithdrawalStatus @default(PENDING)
  pixKey      String?
  createdAt   DateTime         @default(now())
  approvedAt  DateTime?
  completedAt DateTime?
  wallet      Wallet           @relation(fields: [walletId], references: [id])
}

model Delivery {
  id                     String         @id @default(cuid())
  orderId                String         @unique
  driverId               String?
  status                 DeliveryStatus @default(PENDING)
  distanceKm             Decimal?
  etaMinutes             Int?
  baseFee                Decimal        @default(0)
  pricePerKm             Decimal        @default(0)
  deliveryFeeCustomer    Decimal        @default(0)
  driverEarning          Decimal        @default(0)
  platformDeliveryProfit Decimal        @default(0)
  demandMultiplier       Decimal        @default(1)
  weatherMultiplier      Decimal        @default(1)
  surgeMultiplier        Decimal        @default(1)
  bonusAmount            Decimal        @default(0)
  rainBonus              Decimal        @default(0)
  peakBonus              Decimal        @default(0)
  tipsAmount             Decimal        @default(0)
  proofImageUrl          String?
  pickedUpAt             DateTime?
  deliveredAt            DateTime?
  createdAt              DateTime       @default(now())
  updatedAt              DateTime       @updatedAt
  driver                 Driver?        @relation(fields: [driverId], references: [id])
  order                  Order          @relation(fields: [orderId], references: [id])
}

model DeliveryRoute {
  id                          String              @id @default(cuid())
  orderId                     String              @unique
  driverId                    String?
  restaurantLatitude          Decimal?
  restaurantLongitude         Decimal?
  customerLatitude            Decimal?
  customerLongitude           Decimal?
  pickupDistanceKm            Decimal?
  deliveryDistanceKm          Decimal?
  estimatedPickupTime         Int?
  estimatedDeliveryTime       Int?
  encodedPolylineToRestaurant String?
  encodedPolylineToCustomer   String?
  status                      DeliveryRouteStatus @default(SEARCHING_DRIVER)
  createdAt                   DateTime            @default(now())
  updatedAt                   DateTime            @updatedAt
  driver                      Driver?             @relation(fields: [driverId], references: [id])
  order                       Order               @relation(fields: [orderId], references: [id])
}

model Coupon {
  id            String     @id @default(cuid())
  restaurantId  String?
  code          String     @unique
  type          CouponType
  value         Decimal
  minOrderValue Decimal?
  usageLimit    Int?
  perUserLimit  Int?
  validFrom     DateTime
  validUntil    DateTime
  isActive      Boolean    @default(true)
  orders        Order[]
  restaurant    Restaurant? @relation(fields: [restaurantId], references: [id])
}

model Review {
  id           String      @id @default(cuid())
  customerId   String
  restaurantId String?
  driverId     String?
  orderId      String
  rating       Int
  comment      String?
  createdAt    DateTime    @default(now())
  customer     Customer    @relation(fields: [customerId], references: [id])
  driver       Driver?     @relation(fields: [driverId], references: [id])
  order        Order       @relation(fields: [orderId], references: [id])
  restaurant   Restaurant? @relation(fields: [restaurantId], references: [id])
}

model Notification {
  id        String              @id @default(cuid())
  userId    String
  title     String
  body      String
  channel   NotificationChannel
  readAt    DateTime?
  payload   Json?
  createdAt DateTime            @default(now())
  user      User                @relation(fields: [userId], references: [id])
}

model SupportTicket {
  id          String       @id @default(cuid())
  userId      String
  subject     String
  description String
  status      TicketStatus @default(OPEN)
  attachments Json?
  createdAt   DateTime     @default(now())
  updatedAt   DateTime     @updatedAt
  user        User         @relation(fields: [userId], references: [id])
}

model Address {
  id           String   @id @default(cuid())
  userId       String
  label        String
  street       String
  number       String
  complement   String?
  neighborhood String
  city         String
  state        String
  zipCode      String
  latitude     Decimal?
  longitude    Decimal?
  isDefault    Boolean  @default(false)
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
  user         User     @relation(fields: [userId], references: [id])
  orders       Order[]
}

model Wallet {
  id             String              @id @default(cuid())
  userId         String?             @unique
  customerId     String?             @unique
  driverId       String?             @unique
  restaurantId   String?             @unique
  type           WalletType
  balance        Decimal             @default(0)
  blockedBalance Decimal             @default(0)
  currency       String              @default("BRL")
  createdAt      DateTime            @default(now())
  updatedAt      DateTime            @updatedAt
  customer       Customer?           @relation(fields: [customerId], references: [id])
  driver         Driver?             @relation(fields: [driverId], references: [id])
  restaurant     Restaurant?         @relation(fields: [restaurantId], references: [id])
  user           User?               @relation(fields: [userId], references: [id])
  transactions   WalletTransaction[]
  withdrawals    Withdrawal[]
}

model WalletTransaction {
  id            String                @id @default(cuid())
  walletId      String
  type          WalletTransactionType
  amount        Decimal
  description   String
  referenceType String?
  referenceId   String?
  status        String                @default("POSTED")
  metadata      Json?
  createdAt     DateTime              @default(now())
  wallet        Wallet                @relation(fields: [walletId], references: [id])
}

model DriverLocation {
  id        String   @id @default(cuid())
  driverId  String
  orderId   String?
  latitude  Decimal
  longitude Decimal
  heading   Decimal?
  speed     Decimal?
  accuracy  Decimal?
  createdAt DateTime @default(now())
  driver    Driver   @relation(fields: [driverId], references: [id])
  order     Order?   @relation(fields: [orderId], references: [id])

  @@index([driverId, createdAt])
  @@index([orderId, createdAt])
}

model FinancialLedger {
  id          String          @id @default(cuid())
  orderId     String?
  userId      String?
  type        String
  amount      Decimal
  direction   LedgerDirection
  description String
  status      LedgerStatus    @default(POSTED)
  createdAt   DateTime        @default(now())
  order       Order?          @relation(fields: [orderId], references: [id])
  user        User?           @relation(fields: [userId], references: [id])

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

model AdsCampaign {
  id           String           @id @default(cuid())
  restaurantId String
  title        String
  budget       Decimal
  status       AdCampaignStatus @default(DRAFT)
  startsAt     DateTime?
  endsAt       DateTime?
  createdAt    DateTime         @default(now())
  updatedAt    DateTime         @updatedAt
  clicks       AdsClick[]
  impressions  AdsImpression[]
}

model AdsImpression {
  id         String      @id @default(cuid())
  campaignId String
  createdAt  DateTime    @default(now())
  campaign   AdsCampaign @relation(fields: [campaignId], references: [id])
}

model AdsClick {
  id         String      @id @default(cuid())
  campaignId String
  createdAt  DateTime    @default(now())
  campaign   AdsCampaign @relation(fields: [campaignId], references: [id])
}

model SponsoredRestaurant {
  id           String     @id @default(cuid())
  restaurantId String
  priority     Int        @default(0)
  createdAt    DateTime   @default(now())
  updatedAt    DateTime   @updatedAt
  restaurant   Restaurant @relation(fields: [restaurantId], references: [id])
}

model PremiumSubscription {
  id           String             @id @default(cuid())
  customerId   String
  name         String
  monthlyFee   Decimal
  cashbackRate Decimal            @default(0)
  status       SubscriptionStatus @default(ACTIVE)
  startedAt    DateTime           @default(now())
  expiresAt    DateTime?
  customer     Customer           @relation(fields: [customerId], references: [id])
}

model RestaurantPlanSubscription {
  id           String             @id @default(cuid())
  restaurantId String
  planName     String
  monthlyFee   Decimal
  features     Json?
  status       SubscriptionStatus @default(ACTIVE)
  startedAt    DateTime           @default(now())
  expiresAt    DateTime?
  restaurant   Restaurant         @relation(fields: [restaurantId], references: [id])
}

model RestaurantOpeningHour {
  id           String     @id @default(cuid())
  restaurantId String
  weekDay      Int
  opensAt      String
  closesAt     String
  isClosed     Boolean    @default(false)
  restaurant   Restaurant @relation(fields: [restaurantId], references: [id])
}

model Banner {
  id        String    @id @default(cuid())
  title     String
  imageUrl  String
  isActive  Boolean   @default(true)
  startsAt  DateTime?
  endsAt    DateTime?
  createdAt DateTime  @default(now())
}

model Promotion {
  id            String     @id @default(cuid())
  restaurantId  String
  title         String
  description   String?
  discountType  CouponType
  discountValue Decimal
  startsAt      DateTime
  endsAt        DateTime
  isActive      Boolean    @default(true)
  restaurant    Restaurant @relation(fields: [restaurantId], references: [id])
}

model Setting {
  id        String   @id @default(cuid())
  key       String   @unique
  value     Json
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model AuditLog {
  id        String   @id @default(cuid())
  userId    String?
  action    String
  entity    String
  entityId  String?
  metadata  Json?
  ipAddress String?
  userAgent String?
  createdAt DateTime @default(now())
  user      User?    @relation(fields: [userId], references: [id])
}

enum UserRole {
  CUSTOMER
  DRIVER
  RESTAURANT
  ADMIN
  SUPER_ADMIN
}

enum AccountStatus {
  PENDING
  ACTIVE
  SUSPENDED
  REJECTED
}

enum OrderStatus {
  CREATED
  WAITING_PAYMENT
  PAYMENT_CONFIRMED
  SENT_TO_RESTAURANT
  RESTAURANT_ACCEPTED
  PREPARING
  READY_FOR_PICKUP
  SEARCHING_DRIVER
  DRIVER_ACCEPTED
  DRIVER_ARRIVED
  PICKED_UP
  ON_THE_WAY
  DELIVERED
  CANCELLED
  REFUNDED
}

enum PaymentMethod {
  PIX
  CREDIT_CARD
  DEBIT_CARD
  CASH
  WALLET
  MERCADO_PAGO
  STRIPE
}

enum PaymentStatus {
  PENDING
  PAID
  FAILED
  REFUNDED
  CHARGEBACK
}

enum DeliveryStatus {
  PENDING
  ASSIGNED
  ACCEPTED
  PICKED_UP
  ON_THE_WAY
  DELIVERED
  FAILED
  CANCELLED
}

enum DeliveryRouteStatus {
  SEARCHING_DRIVER
  TO_RESTAURANT
  AT_RESTAURANT
  TO_CUSTOMER
  DELIVERED
  CANCELLED
}

enum WalletType {
  CUSTOMER
  DRIVER
  RESTAURANT
  PLATFORM
}

enum WalletTransactionType {
  CREDIT
  DEBIT
  CASHBACK
  ORDER_PAYMENT
  RESTAURANT_REVENUE
  DRIVER_EARNING
  PLATFORM_COMMISSION
  WITHDRAWAL
  REFUND
  AD_PAYMENT
  SUBSCRIPTION_PAYMENT
  SERVICE_FEE
  DELIVERY_PROFIT
}

enum WithdrawalStatus {
  PENDING
  APPROVED
  REJECTED
  COMPLETED
}

enum LedgerDirection {
  IN
  OUT
}

enum LedgerStatus {
  PENDING
  POSTED
  CANCELLED
}

enum TicketStatus {
  OPEN
  IN_PROGRESS
  RESOLVED
  CLOSED
}

enum NotificationChannel {
  PUSH
  EMAIL
  SMS
  IN_APP
}

enum CouponType {
  PERCENTAGE
  FIXED
  FREE_DELIVERY
}

enum SubscriptionStatus {
  ACTIVE
  PAUSED
  CANCELLED
  EXPIRED
}

enum AdCampaignStatus {
  DRAFT
  ACTIVE
  PAUSED
  FINISHED
}
