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

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

enum UserRole {
  ADMIN
  DRIVER
}

enum BookingStatus {
  RESERVED              // Initial (nach E-Mail-Eingang)
  CONFIRMED             // Admin hat bestätigt & gesendet
  READY_FOR_ASSIGNMENT  // Vertrag unterschrieben → Admin-Freigabe
  OPEN_FOR_DRIVERS      // Admin hat freigegeben → Fahrer können sich melden
  ASSIGNED              // Admin hat Fahrer zugewiesen & Tour erstellt
  COMPLETED             // Event abgeschlossen
  CANCELLED             // Storniert
}

enum PhotoboxStatus {
  AVAILABLE
  IN_USE
  MAINTENANCE
  DAMAGED
}

enum PhotoboxModel {
  VINTAGE_SMILE
  VINTAGE_PHOTOS
  NOSTALGIE
  MAGIC_MIRROR
}

enum InvoiceType {
  PRIVATE
  BUSINESS
}

enum EquipmentType {
  PRINTER
  CARPET
  VIP_BARRIER
  ACCESSORIES_KIT
  PRINTER_PAPER
  TRIPOD
  OTHER
}

enum EquipmentStatus {
  AVAILABLE
  IN_USE
  MAINTENANCE
  DAMAGED
  RESERVED
}

model User {
  id            String    @id @default(cuid())
  email         String    @unique
  name          String
  password      String
  role          UserRole  @default(DRIVER)
  phoneNumber   String?
  vehiclePlate  String?
  vehicleModel  String?
  active        Boolean   @default(true)
  available     Boolean   @default(true)
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  
  driverTours          Tour[]
  notifications        Notification[]
  driverAvailability   DriverAvailability[]
}

model Location {
  id              String    @id @default(cuid())
  name            String
  city            String
  slug            String    @unique
  websiteUrl      String
  contactEmail    String
  active          Boolean   @default(true)
  
  imapHost        String?
  imapPort        Int?
  imapUser        String?
  imapPassword    String?
  imapSecure      Boolean   @default(true)
  
  smtpHost        String?
  smtpPort        Int?
  smtpUser        String?
  smtpPassword    String?
  smtpSecure      Boolean   @default(true)
  
  emailSyncEnabled Boolean  @default(false)
  lastEmailSync   DateTime?
  
  priceConfig     PriceConfig[]
  photoboxes      Photobox[]
  bookings        Booking[]
  equipment       Equipment[]
  
  createdAt       DateTime  @default(now())
  updatedAt       DateTime  @updatedAt
  
  @@index([slug])
}

model PriceConfig {
  id              String          @id @default(cuid())
  locationId      String
  location        Location        @relation(fields: [locationId], references: [id], onDelete: Cascade)
  
  model           PhotoboxModel
  basePrice       Float
  pricePerKm      Float
  includedKm      Int             @default(0)
  
  createdAt       DateTime        @default(now())
  updatedAt       DateTime        @updatedAt
  
  @@unique([locationId, model])
}

model Photobox {
  id              String          @id @default(cuid())
  locationId      String
  location        Location        @relation(fields: [locationId], references: [id], onDelete: Cascade)
  
  model           PhotoboxModel
  serialNumber    String          @unique
  status          PhotoboxStatus  @default(AVAILABLE)
  active          Boolean         @default(true)
  
  description     String?
  purchaseDate    DateTime?
  lastMaintenance DateTime?
  
  bookings        Booking[]
  
  createdAt       DateTime        @default(now())
  updatedAt       DateTime        @updatedAt
  
  @@index([locationId, model])
  @@index([status])
}

model Booking {
  id                    String          @id @default(cuid())
  bookingNumber         String          @unique
  
  locationId            String
  location              Location        @relation(fields: [locationId], references: [id])
  
  photoboxId            String?
  photobox              Photobox?       @relation(fields: [photoboxId], references: [id])
  
  status                BookingStatus   @default(RESERVED)
  
  customerName          String
  customerEmail         String
  customerPhone         String
  customerAddress       String?
  customerCity          String?
  customerZip           String?
  
  invoiceType           InvoiceType     @default(PRIVATE)
  companyName           String?
  
  eventDate             DateTime
  eventAddress          String
  eventCity             String
  eventZip              String
  eventLocation         String?
  
  setupTimeStart        DateTime
  setupTimeLatest       DateTime
  dismantleTimeEarliest DateTime?
  dismantleTimeLatest   DateTime?
  
  distance              Float?
  calculatedPrice       Float?
  
  // Contract Management
  contractSigned        Boolean         @default(false)
  contractSignedAt      DateTime?
  contractGenerated     Boolean         @default(false)
  contractGeneratedAt   DateTime?
  contractSentAt        DateTime?
  contractSignedOnline  Boolean         @default(false)
  contractPdfUrl        String?
  contractSignatureData String?         @db.Text
  contractSignedBy      String?
  contractSignedIp      String?
  contractUploadedBy    String?
  
  lexofficeOfferId      String?
  lexofficeInvoiceId    String?
  lexofficeContactId    String?
  lexofficeConfirmationId String?
  confirmationSentAt    DateTime?
  
  // KI-Analyse
  aiParsed              Boolean         @default(false)
  aiResponseDraft       String?         @db.Text
  aiProcessedAt         DateTime?
  
  // Freigabe-Status
  readyForAssignment    Boolean         @default(false)
  openForDrivers        Boolean         @default(false)
  
  // Kalender-Sync (Nextcloud)
  calendarEventId       String?
  calendarSynced        Boolean         @default(false)
  calendarSyncedAt      DateTime?
  
  tourId                String?
  tour                  Tour?           @relation(fields: [tourId], references: [id])
  
  notes                 String?
  internalNotes         String?
  
  emails                Email[]
  bookingEquipment      BookingEquipment[]
  driverAvailability    DriverAvailability[]
  setupWindows          SetupWindow[]
  
  createdAt             DateTime        @default(now())
  updatedAt             DateTime        @updatedAt
  
  @@index([eventDate])
  @@index([status])
  @@index([locationId])
}

model SetupWindow {
  id                String    @id @default(cuid())
  bookingId         String
  booking           Booking   @relation(fields: [bookingId], references: [id], onDelete: Cascade)
  
  setupDate         DateTime
  setupTimeStart    DateTime
  setupTimeEnd      DateTime
  preferred         Boolean   @default(false)
  selected          Boolean   @default(false)
  
  notes             String?
  
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt
  
  @@index([bookingId])
  @@index([setupDate])
}

enum TourStatus {
  PLANNED
  IN_PROGRESS
  COMPLETED
  CANCELLED
}

model Tour {
  id              String      @id @default(cuid())
  tourDate        DateTime
  tourNumber      String      @unique
  
  driverId        String?
  driver          User?       @relation(fields: [driverId], references: [id])
  
  bookings        Booking[]
  
  routeOptimized  Json?
  totalDistance   Float?
  estimatedDuration Int?
  
  status          TourStatus  @default(PLANNED)
  startedAt       DateTime?
  completedAt     DateTime?
  
  notes           String?
  
  createdAt       DateTime    @default(now())
  updatedAt       DateTime    @updatedAt
  
  @@index([tourDate])
  @@index([driverId])
  @@index([status])
}

model Notification {
  id          String    @id @default(cuid())
  userId      String?
  user        User?     @relation(fields: [userId], references: [id])
  
  type        String
  title       String
  message     String
  read        Boolean   @default(false)
  
  metadata    Json?
  
  createdAt   DateTime  @default(now())
  
  @@index([userId, read])
}

model Email {
  id              String    @id @default(cuid())
  locationSlug    String?
  
  from            String
  to              String
  subject         String
  textBody        String?
  htmlBody        String?
  
  messageId       String?   @unique
  inReplyTo       String?
  
  bookingId       String?
  booking         Booking?  @relation(fields: [bookingId], references: [id])
  
  parsed          Boolean   @default(false)
  parsedData      Json?
  
  direction       String    @default("INBOUND")
  
  receivedAt      DateTime  @default(now())
  createdAt       DateTime  @default(now())
  
  @@index([locationSlug])
  @@index([bookingId])
  @@index([receivedAt])
}

model Project {
  id          String      @id @default(cuid())
  name        String
  description String?
  active      Boolean     @default(true)
  
  equipment   Equipment[]
  
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt
}

model Equipment {
  id              String          @id @default(cuid())
  name            String
  type            EquipmentType
  brand           String?
  model           String?
  serialNumber    String?         @unique
  quantity        Int             @default(1)
  status          EquipmentStatus @default(AVAILABLE)
  
  locationId      String?
  location        Location?       @relation(fields: [locationId], references: [id])
  
  projectId       String?
  project         Project?        @relation(fields: [projectId], references: [id])
  
  notes           String?
  purchaseDate    DateTime?
  purchasePrice   Decimal?
  
  minStockLevel   Int?
  currentStock    Int?
  
  createdAt       DateTime        @default(now())
  updatedAt       DateTime        @updatedAt
  
  bookingEquipment BookingEquipment[]
  
  @@index([type])
  @@index([status])
  @@index([locationId])
}

model BookingEquipment {
  id          String      @id @default(cuid())
  
  bookingId   String
  booking     Booking     @relation(fields: [bookingId], references: [id], onDelete: Cascade)
  
  equipmentId String
  equipment   Equipment   @relation(fields: [equipmentId], references: [id])
  
  quantity    Int         @default(1)
  
  createdAt   DateTime    @default(now())
  
  @@unique([bookingId, equipmentId])
  @@index([bookingId])
  @@index([equipmentId])
}

model DriverAvailability {
  id         String   @id @default(cuid())
  
  bookingId  String
  booking    Booking  @relation(fields: [bookingId], references: [id], onDelete: Cascade)
  
  driverId   String
  driver     User     @relation(fields: [driverId], references: [id], onDelete: Cascade)
  
  available  Boolean  @default(true)
  message    String?  @db.Text
  
  createdAt  DateTime @default(now())
  
  @@unique([bookingId, driverId])
  @@index([bookingId])
  @@index([driverId])
}
