generator client {
  provider     = "prisma-client"
  output       = "../src/generated/prisma"
  runtime      = "nodejs"
  moduleFormat = "esm"
}

datasource db {
  provider = "postgresql"
}

enum UserRole {
  ADMIN
  MANAGER
  AGENT
  COLLABORATOR
}

enum TicketStatus {
  PENDING
  AWAITING_ATTENDANCE
  PAUSED
  RESOLVED
}

enum TicketPriority {
  LOW
  MEDIUM
  HIGH
  URGENT
}

enum TicketChannel {
  EMAIL
  WHATSAPP
  CHAT
  PHONE
  API
  MANUAL
}

enum CommentVisibility {
  PUBLIC
  INTERNAL
}

enum CompanyStateRegistrationType {
  STANDARD
  EXEMPT
  SIMPLES
}

model Team {
  id          String       @id @default(cuid())
  tenantId    String
  name        String
  description String?
  members     TeamMember[]
  queues      Queue[]
  createdAt   DateTime     @default(now())
  updatedAt   DateTime     @updatedAt

  @@index([tenantId, name])
}

model TeamMember {
  teamId     String
  userId     String
  isLead     Boolean  @default(false)
  assignedAt DateTime @default(now())

  team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@id([teamId, userId])
}

model Company {
  id                      String                        @id @default(cuid())
  tenantId                String
  name                    String
  slug                    String
  provisioningCode        String                        @unique
  isAvulso                Boolean                       @default(false)
  contractedHoursPerMonth Float?
  cnpj                    String?
  domain                  String?
  phone                   String?
  description             String?
  address                 String?
  legalName               String?
  tradeName               String?
  stateRegistration       String?
  stateRegistrationType   CompanyStateRegistrationType?
  primaryCnae             String?
  timezone                String?
  businessHours           Json?
  supportEmail            String?
  billingEmail            String?
  contactPreferences      Json?
  clientDomains           Json?
  communicationChannels   Json?
  fiscalAddress           Json?
  hasBranches             Boolean                       @default(false)
  regulatedEnvironments   Json?
  privacyPolicyAccepted   Boolean                       @default(false)
  privacyPolicyReference  String?
  privacyPolicyMetadata   Json?
  contacts                Json?
  locations               Json?
  contracts               Json?
  sla                     Json?
  tags                    Json?
  customFields            Json?
  notes                   String?
  createdAt               DateTime                      @default(now())
  updatedAt               DateTime                      @updatedAt

  users   User[]
  tickets Ticket[]

  @@unique([tenantId, slug])
  @@index([tenantId, name])
}

model User {
  id               String          @id @default(cuid())
  tenantId         String
  name             String
  email            String          @unique
  role             UserRole
  jobTitle         String?
  managerId        String?
  timezone         String          @default("America/Sao_Paulo")
  avatarUrl        String?
  companyId        String?
  teams            TeamMember[]
  requestedTickets Ticket[]        @relation("TicketRequester")
  assignedTickets  Ticket[]        @relation("TicketAssignee")
  comments         TicketComment[]
  createdAt        DateTime        @default(now())
  updatedAt        DateTime        @updatedAt

  manager          User?           @relation("UserManager", fields: [managerId], references: [id])
  reports          User[]          @relation("UserManager")
  company Company? @relation(fields: [companyId], references: [id])

  // Relações do sistema de notificações
  ticketRatings           TicketRating[]
  ticketAccessTokens      TicketAccessToken[]
  notificationPreferences NotificationPreferences?

  @@index([tenantId, role])
  @@index([tenantId, companyId])
  @@index([tenantId, managerId])
}

model Queue {
  id        String   @id @default(cuid())
  tenantId  String
  name      String
  slug      String
  teamId    String?
  tickets   Ticket[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  team Team? @relation(fields: [teamId], references: [id])

  @@unique([tenantId, slug])
}

model Ticket {
  id              String         @id @default(cuid())
  tenantId        String
  reference       Int            @default(0)
  subject         String
  summary         String?
  status          TicketStatus   @default(PENDING)
  priority        TicketPriority @default(MEDIUM)
  channel         TicketChannel  @default(EMAIL)
  queueId         String?
  requesterId     String
  assigneeId      String?
  slaPolicyId     String?
  companyId       String?
  slaSnapshot     Json?
  slaResponseDueAt DateTime?
  slaSolutionDueAt DateTime?
  slaResponseStatus String?
  slaSolutionStatus String?
  slaPausedAt     DateTime?
  slaPausedBy     String?
  slaPausedMs     Int?
  dueAt           DateTime?
  firstResponseAt DateTime?
  resolvedAt      DateTime?
  closedAt        DateTime?
  createdAt       DateTime       @default(now())
  updatedAt       DateTime       @updatedAt

  requester User            @relation("TicketRequester", fields: [requesterId], references: [id])
  assignee  User?           @relation("TicketAssignee", fields: [assigneeId], references: [id])
  queue     Queue?          @relation(fields: [queueId], references: [id])
  slaPolicy SlaPolicy?      @relation(fields: [slaPolicyId], references: [id])
  company   Company?        @relation(fields: [companyId], references: [id])
  events    TicketEvent[]
  comments  TicketComment[]

  // Relações do sistema de notificações
  rating       TicketRating?
  accessTokens TicketAccessToken[]

  @@index([tenantId, status])
  @@index([tenantId, queueId])
  @@index([tenantId, assigneeId])
  @@index([tenantId, companyId])
}

model ReportExportSchedule {
  id          String   @id @default(cuid())
  tenantId    String
  name        String
  reportKeys  Json
  range       String   @default("30d")
  companyId   String?
  companyName String?
  format      String   @default("xlsx")
  frequency   String
  dayOfWeek   Int?
  dayOfMonth  Int?
  hour        Int      @default(8)
  minute      Int      @default(0)
  timezone    String   @default("America/Sao_Paulo")
  recipients  Json
  status      String   @default("ACTIVE")
  lastRunAt   DateTime?
  nextRunAt   DateTime?
  createdBy   String
  updatedBy   String?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  runs ReportExportRun[]

  @@index([tenantId, status])
  @@index([tenantId, nextRunAt])
}

model ReportExportRun {
  id          String   @id @default(cuid())
  tenantId    String
  scheduleId  String
  status      String   @default("PENDING")
  startedAt   DateTime @default(now())
  completedAt DateTime?
  error       String?
  artifacts   Json?

  schedule ReportExportSchedule @relation(fields: [scheduleId], references: [id], onDelete: Cascade)

  @@index([tenantId, status])
  @@index([tenantId, scheduleId])
}

model TicketEvent {
  id        String   @id @default(cuid())
  ticketId  String
  type      String
  payload   Json
  createdAt DateTime @default(now())

  ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)

  @@index([ticketId, createdAt])
}

model TicketComment {
  id          String            @id @default(cuid())
  ticketId    String
  authorId    String
  visibility  CommentVisibility @default(INTERNAL)
  body        String
  attachments Json?
  createdAt   DateTime          @default(now())
  updatedAt   DateTime          @updatedAt

  ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
  author User   @relation(fields: [authorId], references: [id])

  @@index([ticketId, visibility])
}

model SlaPolicy {
  id                  String   @id @default(cuid())
  tenantId            String
  name                String
  description         String?
  timeToFirstResponse Int?
  timeToResolution    Int?
  calendar            Json?
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt

  tickets Ticket[]

  @@unique([tenantId, name])
}

model AuthUser {
  id             String        @id @default(cuid())
  name           String?
  email          String        @unique
  emailVerified  Boolean       @default(false)
  image          String?
  role           String        @default("agent")
  tenantId       String?
  avatarUrl      String?
  machinePersona String?
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt
  sessions       AuthSession[]
  accounts       AuthAccount[]
}

model AuthSession {
  id        String   @id @default(cuid())
  userId    String
  token     String   @unique
  expiresAt DateTime
  ipAddress String?
  userAgent String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@index([userId])
  @@index([token])
}

model AuthAccount {
  id                    String    @id @default(cuid())
  userId                String
  accountId             String
  providerId            String
  accessToken           String?
  refreshToken          String?
  accessTokenExpiresAt  DateTime?
  refreshTokenExpiresAt DateTime?
  scope                 String?
  idToken               String?
  password              String?
  createdAt             DateTime  @default(now())
  updatedAt             DateTime  @updatedAt

  user AuthUser @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([providerId, accountId])
  @@index([userId])
}

model AuthInvite {
  id            String    @id @default(cuid())
  email         String
  name          String?
  role          String    @default("agent")
  tenantId      String
  token         String    @unique
  status        String    @default("pending")
  expiresAt     DateTime
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  createdById   String?
  acceptedAt    DateTime?
  acceptedById  String?
  revokedAt     DateTime?
  revokedById   String?
  revokedReason String?

  events AuthInviteEvent[]

  @@index([tenantId, status])
  @@index([tenantId, email])
}

model AuthInviteEvent {
  id        String   @id @default(cuid())
  inviteId  String
  type      String
  payload   Json?
  actorId   String?
  createdAt DateTime @default(now())

  invite AuthInvite @relation(fields: [inviteId], references: [id], onDelete: Cascade)

  @@index([inviteId, createdAt])
}

model AuthVerification {
  id         String   @id @default(cuid())
  identifier String
  value      String
  expiresAt  DateTime
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  @@index([identifier])
}

// ============================================
// Sistema de Notificações por E-mail
// ============================================

model TicketRating {
  id        String   @id @default(cuid())
  tenantId  String
  ticketId  String   @unique
  userId    String
  rating    Int      // 1-5 estrelas
  comment   String?  // Feedback opcional do usuário
  createdAt DateTime @default(now())

  ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
  user   User   @relation(fields: [userId], references: [id])

  @@index([tenantId, rating])
  @@index([tenantId, createdAt])
}

model TicketAccessToken {
  id        String    @id @default(cuid())
  tenantId  String
  token     String    @unique
  ticketId  String
  userId    String
  machineId String?   // Máquina esperada (opcional)
  scope     String    @default("view") // view, interact, rate
  expiresAt DateTime
  usedAt    DateTime?
  createdAt DateTime  @default(now())

  ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
  user   User   @relation(fields: [userId], references: [id])

  @@index([tenantId, ticketId])
  @@index([tenantId, userId])
  @@index([expiresAt])
}

model NotificationPreferences {
  id        String @id @default(cuid())
  tenantId  String
  userId    String @unique

  // Preferências globais
  emailEnabled    Boolean @default(true)
  quietHoursStart String? // "22:00"
  quietHoursEnd   String? // "08:00"
  timezone        String  @default("America/Sao_Paulo")
  digestFrequency String  @default("immediate") // immediate, daily, weekly

  // Preferências por tipo de notificação (JSON)
  // Ex: { "ticket_created": true, "ticket_resolved": true, "comment_public": false }
  typePreferences String @default("{}")

  // Preferências por categoria de ticket (JSON)
  // Ex: { "category_id_1": true, "category_id_2": false }
  categoryPreferences String @default("{}")

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

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

  @@index([tenantId])
}
