// Esquema de la app de Agencia de Viajes
// Documentación: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}

datasource db {
  provider = "mysql"
}

// MySQL: usamos String para roles/estados en lugar de enums nativos.
// Roles de User:       SUPERADMIN | AGENCY
// Estado de Agency:    ACTIVE | SUSPENDED
// Tipo de Document:    FLIGHT | TRAIN | ENTRY | INSURANCE | OTHER

model User {
  id           String   @id @default(cuid())
  email        String   @unique
  passwordHash String
  name         String
  role         String   @default("AGENCY")
  agencyId     String?
  agency       Agency?  @relation(fields: [agencyId], references: [id], onDelete: Cascade)
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
}

// Tipo de licencia: limitada por número de viajeros registrados.
model License {
  id           String    @id @default(cuid())
  name         String    @unique
  maxTravelers Int
  price        Float     @default(0)
  rank         Int       @default(0) // orden ascendente para auto-actualización
  active       Boolean   @default(true)
  agencies     Agency[]
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
}

model Agency {
  id          String   @id @default(cuid())
  name        String
  logoUrl     String?
  taxId       String? // RFC / identificación fiscal
  address     String?
  phone       String?
  email       String?
  whatsapp    String?
  // Datos del dueño / administrador
  ownerName   String
  ownerEmail  String?
  ownerPhone  String?
  // Licencia
  licenseId   String?
  license     License? @relation(fields: [licenseId], references: [id])
  status      String   @default("ACTIVE") // ACTIVE | SUSPENDED
  // Facturación: día del mes (1-31)
  billingCutoffDay   Int?
  invoiceCreationDay Int?
  // Credenciales de acceso (visible solo al superadmin)
  loginPassword      String?

  users     User[]
  travelers Traveler[]
  trips     Trip[]
  bracelets Bracelet[]
  invoices  Invoice[]

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

model Traveler {
  id        String  @id @default(cuid())
  agencyId  String
  agency    Agency  @relation(fields: [agencyId], references: [id], onDelete: Cascade)

  firstName String
  lastName  String
  photoUrl  String?
  birthDate DateTime?
  gender    String?
  email     String?
  phone     String?
  passportNumber String?

  // Localización / idioma para el panel público
  nationality      String?
  residenceCountry String? // código ISO, ej "MX"
  language         String  @default("es") // idioma del viajero, ej "es"

  // Datos clínicos
  bloodType   String?
  allergies   String?
  conditions  String?
  medications String?
  medicalNotes String?

  // Acceso al panel público (link + QR + NFC)
  publicToken String @unique @default(cuid())

  emergencyContacts EmergencyContact[]
  assignments       TripAssignment[]
  documents         Document[]
  bracelets         Bracelet[]

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

// Contactos de emergencia personales del viajero
model EmergencyContact {
  id           String   @id @default(cuid())
  travelerId   String
  traveler     Traveler @relation(fields: [travelerId], references: [id], onDelete: Cascade)
  name         String
  relationship String?
  country      String? // código ISO del país para la lada telefónica, ej "MX"
  phone        String
  email        String?
}

model Trip {
  id                 String   @id @default(cuid())
  agencyId           String
  agency             Agency   @relation(fields: [agencyId], references: [id], onDelete: Cascade)
  name               String
  destinationCountry String? // código ISO destino, ej "FR"
  originCountry      String? // código ISO origen/residencia, ej "MX"
  startDate          DateTime?
  endDate            DateTime?
  baseCost           Float    @default(0)
  // Tipo de cambio asignado por la agencia para este viaje
  currencyFrom       String?  // ej "MXN"
  currencyTo         String?  // ej "EUR"
  exchangeRate       Float?   // tasa manual opcional (si no, se usa la diaria)
  description        String?

  assignments      TripAssignment[]
  itineraryDays    ItineraryDay[]
  emergencyNumbers TripEmergencyNumber[]

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

model ItineraryDay {
  id     String   @id @default(cuid())
  tripId String
  trip   Trip     @relation(fields: [tripId], references: [id], onDelete: Cascade)
  date   DateTime?
  title  String
  order  Int      @default(0)
  items  ItineraryItem[]
}

model ItineraryItem {
  id          String       @id @default(cuid())
  dayId       String
  day         ItineraryDay @relation(fields: [dayId], references: [id], onDelete: Cascade)
  time        String?
  title       String
  description String?
  location    String?
  order       Int          @default(0)
}

// Asignación de un viajero a un viaje (un viajero puede tener varios viajes)
model TripAssignment {
  id         String   @id @default(cuid())
  tripId     String
  trip       Trip     @relation(fields: [tripId], references: [id], onDelete: Cascade)
  travelerId String
  traveler   Traveler @relation(fields: [travelerId], references: [id], onDelete: Cascade)
  cost       Float    @default(0) // costo para este viajero en este viaje

  payments  Payment[]
  documents Document[]

  createdAt DateTime @default(now())

  @@unique([tripId, travelerId])
}

// Pagos en abonos por asignación viajero-viaje
model Payment {
  id           String         @id @default(cuid())
  assignmentId String
  assignment   TripAssignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
  amount       Float
  date         DateTime       @default(now())
  method       String?
  note         String?
}

// Documentos: tickets de avión/tren/entradas, seguros (pdf/foto), otros
model Document {
  id           String          @id @default(cuid())
  travelerId   String
  traveler     Traveler        @relation(fields: [travelerId], references: [id], onDelete: Cascade)
  assignmentId String?
  assignment   TripAssignment? @relation(fields: [assignmentId], references: [id], onDelete: SetNull)
  type         String          @default("OTHER") // FLIGHT | TRAIN | ENTRY | INSURANCE | OTHER
  title        String
  fileUrl      String
  mimeType     String?
  createdAt    DateTime        @default(now())
}

// Teléfonos de emergencia por viaje según país (policía, ambulancia, etc.)
model TripEmergencyNumber {
  id      String @id @default(cuid())
  tripId  String
  trip    Trip   @relation(fields: [tripId], references: [id], onDelete: Cascade)
  label   String // ej "Policía", "Ambulancia", "Embajada"
  phone   String
  country String?
}

// Facturas mensuales de licencia para agencias
model Invoice {
  id            String    @id @default(cuid())
  number        Int       @unique
  cutoffDate    DateTime
  agencyId      String
  agency        Agency    @relation(fields: [agencyId], references: [id], onDelete: Cascade)
  licenseId     String?
  licenseName   String?
  priceUsd      Float     @default(0)
  exchangeRate  Float     @default(0)
  costMxn       Float     @default(0)
  status        String    @default("UNPAID") // UNPAID | PENDING | PAID
  receiptUrl    String?
  paymentMethod String?   // EFECTIVO | TRANSFERENCIA | TARJETA | REGALO
  submittedAt   DateTime?
  paidAt        DateTime?
  createdAt     DateTime  @default(now())
}

// Pulseras NFC asignadas a viajeros
model Bracelet {
  id         String   @id @default(cuid())
  agencyId   String
  agency     Agency   @relation(fields: [agencyId], references: [id], onDelete: Cascade)
  travelerId String?
  traveler   Traveler? @relation(fields: [travelerId], references: [id], onDelete: SetNull)
  number     String
  nfcWritten Boolean  @default(false)
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt
}
