// 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"
}

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

// =============================================================================
// ENUMS
// =============================================================================

enum UserRole {
  SUPER_ADMIN
  ORG_ADMIN
  SITE_ADMIN
  RECEPTIONIST
  TRAINER
}

enum CourtType {
  INDOOR
  OUTDOOR
  COVERED
}

enum CourtStatus {
  AVAILABLE
  MAINTENANCE
  CLOSED
}

enum BookingStatus {
  PENDING
  CONFIRMED
  CANCELLED
  COMPLETED
  NO_SHOW
}

enum PaymentType {
  CASH
  CARD
  TRANSFER
  MEMBERSHIP
  FREE
}

enum MembershipStatus {
  ACTIVE
  EXPIRED
  CANCELLED
  SUSPENDED
}

enum TournamentType {
  AMERICANO
  MEXICANO
  BRACKET
  ROUND_ROBIN
  LEAGUE
}

enum TournamentStatus {
  DRAFT
  REGISTRATION_OPEN
  REGISTRATION_CLOSED
  IN_PROGRESS
  COMPLETED
  CANCELLED
}

enum MatchStatus {
  SCHEDULED
  IN_PROGRESS
  COMPLETED
  CANCELLED
  WALKOVER
}

// =============================================================================
// ORGANIZATION & SITES
// =============================================================================

model Organization {
  id        String   @id @default(cuid())
  name      String
  slug      String   @unique
  logo      String?
  settings  Json     @default("{}")
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  sites       Site[]
  users       User[]
  clients     Client[]
  memberships MembershipPlan[]
  products    Product[]
  categories  ProductCategory[]
  tournaments Tournament[]

  @@index([slug])
}

model Site {
  id             String   @id @default(cuid())
  organizationId String
  name           String
  slug           String
  address        String?
  phone          String?
  email          String?
  timezone       String   @default("Europe/Madrid")
  openTime       String   @default("08:00")
  closeTime      String   @default("22:00")
  settings       Json     @default("{}")
  isActive       Boolean  @default(true)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt

  organization  Organization   @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  courts        Court[]
  users         User[]
  bookings      Booking[]
  cashRegisters CashRegister[]
  tournaments   Tournament[]

  @@unique([organizationId, slug])
  @@index([organizationId])
  @@index([slug])
}

model Court {
  id          String      @id @default(cuid())
  siteId      String
  name        String
  type        CourtType   @default(INDOOR)
  status      CourtStatus @default(AVAILABLE)
  pricePerHour Decimal    @db.Decimal(10, 2)
  description String?
  features    String[]    @default([])
  displayOrder Int        @default(0)
  isActive    Boolean     @default(true)
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt

  site     Site      @relation(fields: [siteId], references: [id], onDelete: Cascade)
  bookings Booking[]
  matches  Match[]

  @@index([siteId])
  @@index([status])
}

// =============================================================================
// USERS & CLIENTS
// =============================================================================

model User {
  id             String    @id @default(cuid())
  organizationId String
  email          String
  password       String
  firstName      String
  lastName       String
  role           UserRole  @default(RECEPTIONIST)
  phone          String?
  avatar         String?
  siteIds        String[]  @default([])
  isActive       Boolean   @default(true)
  lastLogin      DateTime?
  createdAt      DateTime  @default(now())
  updatedAt      DateTime  @updatedAt

  organization   Organization    @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  sites          Site[]
  bookingsCreated Booking[]      @relation("BookingCreatedBy")
  salesCreated   Sale[]          @relation("SaleCreatedBy")
  cashRegisters  CashRegister[]

  @@unique([organizationId, email])
  @@index([organizationId])
  @@index([email])
  @@index([role])
}

model Client {
  id             String   @id @default(cuid())
  organizationId String
  email          String?
  phone          String?
  firstName      String
  lastName       String
  dni            String?
  dateOfBirth    DateTime?
  address        String?
  notes          String?
  avatar         String?
  level          String?
  preferredHand  String?
  emergencyContact String?
  emergencyPhone String?
  tags           String[] @default([])
  isActive       Boolean  @default(true)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt

  organization  Organization              @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  memberships   Membership[]
  bookings      Booking[]
  payments      Payment[]
  sales         Sale[]
  inscriptions  TournamentInscription[]

  @@unique([organizationId, email])
  @@unique([organizationId, dni])
  @@index([organizationId])
  @@index([email])
  @@index([phone])
  @@index([lastName, firstName])
}

// =============================================================================
// BOOKINGS & PAYMENTS
// =============================================================================

model Booking {
  id            String        @id @default(cuid())
  siteId        String
  courtId       String
  clientId      String?
  createdById   String?
  startTime     DateTime
  endTime       DateTime
  status        BookingStatus @default(PENDING)
  paymentType   PaymentType   @default(CASH)
  totalPrice    Decimal       @db.Decimal(10, 2)
  paidAmount    Decimal       @default(0) @db.Decimal(10, 2)
  notes         String?
  playerNames   String[]      @default([])
  isRecurring   Boolean       @default(false)
  recurringId   String?
  cancelledAt   DateTime?
  cancelReason  String?
  createdAt     DateTime      @default(now())
  updatedAt     DateTime      @updatedAt

  site      Site      @relation(fields: [siteId], references: [id], onDelete: Cascade)
  court     Court     @relation(fields: [courtId], references: [id], onDelete: Cascade)
  client    Client?   @relation(fields: [clientId], references: [id], onDelete: SetNull)
  createdBy User?     @relation("BookingCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
  payments  Payment[]
  match     Match?

  @@index([siteId])
  @@index([courtId])
  @@index([clientId])
  @@index([startTime, endTime])
  @@index([status])
  @@index([recurringId])
}

model Payment {
  id            String      @id @default(cuid())
  bookingId     String?
  clientId      String?
  saleId        String?
  membershipId  String?
  amount        Decimal     @db.Decimal(10, 2)
  paymentType   PaymentType
  reference     String?
  notes         String?
  cashRegisterId String?
  createdAt     DateTime    @default(now())
  updatedAt     DateTime    @updatedAt

  booking      Booking?      @relation(fields: [bookingId], references: [id], onDelete: SetNull)
  client       Client?       @relation(fields: [clientId], references: [id], onDelete: SetNull)
  sale         Sale?         @relation(fields: [saleId], references: [id], onDelete: SetNull)
  membership   Membership?   @relation(fields: [membershipId], references: [id], onDelete: SetNull)
  cashRegister CashRegister? @relation(fields: [cashRegisterId], references: [id], onDelete: SetNull)

  @@index([bookingId])
  @@index([clientId])
  @@index([saleId])
  @@index([membershipId])
  @@index([cashRegisterId])
  @@index([createdAt])
}

// =============================================================================
// MEMBERSHIPS
// =============================================================================

model MembershipPlan {
  id             String   @id @default(cuid())
  organizationId String
  name           String
  description    String?
  price          Decimal  @db.Decimal(10, 2)
  durationMonths Int
  courtHours     Int?
  discountPercent Decimal? @db.Decimal(5, 2)
  benefits       String[] @default([])
  isActive       Boolean  @default(true)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt

  organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  memberships  Membership[]

  @@index([organizationId])
  @@index([isActive])
}

model Membership {
  id            String           @id @default(cuid())
  planId        String
  clientId      String
  startDate     DateTime
  endDate       DateTime
  status        MembershipStatus @default(ACTIVE)
  remainingHours Int?
  autoRenew     Boolean          @default(false)
  notes         String?
  createdAt     DateTime         @default(now())
  updatedAt     DateTime         @updatedAt

  plan     MembershipPlan @relation(fields: [planId], references: [id], onDelete: Cascade)
  client   Client         @relation(fields: [clientId], references: [id], onDelete: Cascade)
  payments Payment[]

  @@index([planId])
  @@index([clientId])
  @@index([status])
  @@index([endDate])
}

// =============================================================================
// PRODUCTS & SALES
// =============================================================================

model ProductCategory {
  id             String   @id @default(cuid())
  organizationId String
  name           String
  description    String?
  displayOrder   Int      @default(0)
  isActive       Boolean  @default(true)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt

  organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  products     Product[]

  @@unique([organizationId, name])
  @@index([organizationId])
}

model Product {
  id             String   @id @default(cuid())
  organizationId String
  categoryId     String?
  name           String
  description    String?
  sku            String?
  price          Decimal  @db.Decimal(10, 2)
  costPrice      Decimal? @db.Decimal(10, 2)
  stock          Int      @default(0)
  minStock       Int      @default(0)
  trackStock     Boolean  @default(true)
  image          String?
  isActive       Boolean  @default(true)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt

  organization Organization     @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  category     ProductCategory? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
  saleItems    SaleItem[]

  @@unique([organizationId, sku])
  @@index([organizationId])
  @@index([categoryId])
  @@index([name])
  @@index([isActive])
}

model Sale {
  id            String      @id @default(cuid())
  clientId      String?
  createdById   String?
  cashRegisterId String?
  subtotal      Decimal     @db.Decimal(10, 2)
  discount      Decimal     @default(0) @db.Decimal(10, 2)
  tax           Decimal     @default(0) @db.Decimal(10, 2)
  total         Decimal     @db.Decimal(10, 2)
  paymentType   PaymentType
  notes         String?
  createdAt     DateTime    @default(now())
  updatedAt     DateTime    @updatedAt

  client       Client?       @relation(fields: [clientId], references: [id], onDelete: SetNull)
  createdBy    User?         @relation("SaleCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
  cashRegister CashRegister? @relation(fields: [cashRegisterId], references: [id], onDelete: SetNull)
  items        SaleItem[]
  payments     Payment[]

  @@index([clientId])
  @@index([createdById])
  @@index([cashRegisterId])
  @@index([createdAt])
}

model SaleItem {
  id        String   @id @default(cuid())
  saleId    String
  productId String
  quantity  Int
  unitPrice Decimal  @db.Decimal(10, 2)
  subtotal  Decimal  @db.Decimal(10, 2)
  createdAt DateTime @default(now())

  sale    Sale    @relation(fields: [saleId], references: [id], onDelete: Cascade)
  product Product @relation(fields: [productId], references: [id], onDelete: Cascade)

  @@index([saleId])
  @@index([productId])
}

model CashRegister {
  id            String    @id @default(cuid())
  siteId        String
  userId        String
  openedAt      DateTime  @default(now())
  closedAt      DateTime?
  openingAmount Decimal   @db.Decimal(10, 2)
  closingAmount Decimal?  @db.Decimal(10, 2)
  expectedAmount Decimal? @db.Decimal(10, 2)
  difference    Decimal?  @db.Decimal(10, 2)
  notes         String?
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt

  site     Site      @relation(fields: [siteId], references: [id], onDelete: Cascade)
  user     User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  sales    Sale[]
  payments Payment[]

  @@index([siteId])
  @@index([userId])
  @@index([openedAt])
  @@index([closedAt])
}

// =============================================================================
// TOURNAMENTS
// =============================================================================

model Tournament {
  id             String           @id @default(cuid())
  organizationId String
  siteId         String?
  name           String
  description    String?
  type           TournamentType   @default(AMERICANO)
  status         TournamentStatus @default(DRAFT)
  startDate      DateTime
  endDate        DateTime?
  maxPlayers     Int?
  entryFee       Decimal?         @db.Decimal(10, 2)
  prizePool      Decimal?         @db.Decimal(10, 2)
  rules          String?
  settings       Json             @default("{}")
  image          String?
  isPublic       Boolean          @default(true)
  createdAt      DateTime         @default(now())
  updatedAt      DateTime         @updatedAt

  organization Organization            @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  site         Site?                   @relation(fields: [siteId], references: [id], onDelete: SetNull)
  inscriptions TournamentInscription[]
  matches      Match[]

  @@index([organizationId])
  @@index([siteId])
  @@index([status])
  @@index([startDate])
  @@index([type])
}

model TournamentInscription {
  id           String   @id @default(cuid())
  tournamentId String
  clientId     String
  partnerId    String?
  teamName     String?
  seedNumber   Int?
  paidAmount   Decimal  @default(0) @db.Decimal(10, 2)
  isPaid       Boolean  @default(false)
  notes        String?
  registeredAt DateTime @default(now())
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt

  tournament Tournament @relation(fields: [tournamentId], references: [id], onDelete: Cascade)
  client     Client     @relation(fields: [clientId], references: [id], onDelete: Cascade)

  @@unique([tournamentId, clientId])
  @@index([tournamentId])
  @@index([clientId])
}

model Match {
  id           String      @id @default(cuid())
  tournamentId String
  bookingId    String?     @unique
  courtId      String?
  round        Int
  position     Int
  scheduledAt  DateTime?
  startedAt    DateTime?
  completedAt  DateTime?
  status       MatchStatus @default(SCHEDULED)
  team1Players String[]    @default([])
  team2Players String[]    @default([])
  team1Score   Int[]       @default([])
  team2Score   Int[]       @default([])
  winnerId     String?
  notes        String?
  createdAt    DateTime    @default(now())
  updatedAt    DateTime    @updatedAt

  tournament Tournament @relation(fields: [tournamentId], references: [id], onDelete: Cascade)
  booking    Booking?   @relation(fields: [bookingId], references: [id], onDelete: SetNull)
  court      Court?     @relation(fields: [courtId], references: [id], onDelete: SetNull)

  @@index([tournamentId])
  @@index([courtId])
  @@index([status])
  @@index([round, position])
  @@index([scheduledAt])
}
