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

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

enum TenantStatus {
  ACTIVE
  SUSPENDED
  TRIAL
  INACTIVE
}

enum UserStatus {
  ACTIVE
  INVITED
  DISABLED
}

enum RoleCode {
  SUPER_ADMIN
  ADMIN_CLIENT
  AGENT
}

enum ChannelStatus {
  CONNECTED
  DISCONNECTED
  PENDING
  ERROR
}

enum ConversationStatus {
  OPEN
  PENDING
  RESOLVED
  ARCHIVED
  SPAM
}

enum ConversationPriority {
  LOW
  NORMAL
  HIGH
  URGENT
}

enum MessageDirection {
  INBOUND
  OUTBOUND
}

enum AuthTokenType {
  PASSWORD_RESET
  INVITE_ACCEPTANCE
}

enum MessageType {
  TEXT
  IMAGE
  VIDEO
  AUDIO
  DOCUMENT
  TEMPLATE
  INTERACTIVE
}

enum DeliveryStatus {
  QUEUED
  SENT
  DELIVERED
  READ
  FAILED
}

enum OptInStatus {
  UNKNOWN
  OPTED_IN
  OPTED_OUT
}

enum TemplateApprovalStatus {
  DRAFT
  PENDING
  APPROVED
  REJECTED
  DISABLED
}

enum CampaignStatus {
  DRAFT
  SCHEDULED
  PROCESSING
  COMPLETED
  PARTIAL_FAILED
  FAILED
  CANCELED
}

enum CampaignAudienceType {
  SEGMENT
  IMPORT
  MANUAL
}

enum CampaignType {
  BROADCAST
  BULK_FOLLOWUP
}

enum PaymentStatus {
  UNPAID
  PAID
  OVERDUE
  VOID
}

model SubscriptionPlan {
  id             String           @id @default(cuid())
  name           String
  code           String           @unique
  priceMonthly   Int
  messageQuota   Int
  seatQuota      Int
  broadcastQuota Int
  featuresJson   String?
  createdAt      DateTime         @default(now())
  updatedAt      DateTime         @updatedAt
  tenants        Tenant[]
  invoices       BillingInvoice[]
}

model Tenant {
  id              String                 @id @default(cuid())
  name            String
  slug            String                 @unique
  companyName     String
  timezone        String
  status          TenantStatus           @default(TRIAL)
  planId          String
  createdAt       DateTime               @default(now())
  updatedAt       DateTime               @updatedAt
  plan            SubscriptionPlan       @relation(fields: [planId], references: [id])
  users           User[]
  roles           Role[]
  channels        Channel[]
  contacts        Contact[]
  tags            Tag[]
  conversations   Conversation[]
  messages        Message[]
  notes           ConversationNote[]
  activities      ConversationActivity[]
  segments        ContactSegment[]
  templates       MessageTemplate[]
  campaigns       BroadcastCampaign[]
  auditLogs       AuditLog[]
  webhookEvents   WebhookEvent[]
  usageMetrics    UsageMetric[]
  billingInvoices BillingInvoice[]
}

model Role {
  id              String   @id @default(cuid())
  tenantId        String?
  name            String
  code            RoleCode
  permissionsJson String?
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
  tenant          Tenant?  @relation(fields: [tenantId], references: [id])
  users           User[]
}

model User {
  id                    String                 @id @default(cuid())
  tenantId              String
  fullName              String
  email                 String                 @unique
  passwordHash          String
  roleId                String
  status                UserStatus             @default(INVITED)
  avatarUrl             String?
  lastLoginAt           DateTime?
  createdAt             DateTime               @default(now())
  updatedAt             DateTime               @updatedAt
  tenant                Tenant                 @relation(fields: [tenantId], references: [id])
  role                  Role                   @relation(fields: [roleId], references: [id])
  assignedConversations Conversation[]
  notes                 ConversationNote[]
  sentMessages          Message[]
  activities            ConversationActivity[] @relation("ActorActivities")
  campaigns             BroadcastCampaign[]
  auditLogs             AuditLog[]
}

model AuthToken {
  id            String         @id @default(cuid())
  userId        String
  tenantId      String
  tokenType     AuthTokenType
  tokenHash     String         @unique
  expiresAt     DateTime
  consumedAt    DateTime?
  createdByUser String?
  createdAt     DateTime       @default(now())
  metadataJson  String?

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

model Channel {
  id                 String              @id @default(cuid())
  tenantId           String
  channelName        String
  provider           String
  wabaId             String?
  phoneNumberId      String?
  displayPhoneNumber String?
  status             ChannelStatus       @default(PENDING)
  webhookStatus      String?
  lastSyncAt         DateTime?
  createdAt          DateTime            @default(now())
  updatedAt          DateTime            @updatedAt
  tenant             Tenant              @relation(fields: [tenantId], references: [id])
  contacts           Contact[]
  conversations      Conversation[]
  messages           Message[]
  templates          MessageTemplate[]
  campaigns          BroadcastCampaign[]
  webhookEvents      WebhookEvent[]
}

model Contact {
  id                 String              @id @default(cuid())
  tenantId           String
  channelId          String?
  externalRef        String?
  fullName           String
  phoneNumber        String
  email              String?
  avatarUrl          String?
  countryCode        String?
  optInStatus        OptInStatus         @default(UNKNOWN)
  lastInteractionAt  DateTime?
  createdAt          DateTime            @default(now())
  updatedAt          DateTime            @updatedAt
  tenant             Tenant              @relation(fields: [tenantId], references: [id])
  channel            Channel?            @relation(fields: [channelId], references: [id])
  conversations      Conversation[]
  messages           Message[]
  contactTags        ContactTag[]
  segmentMembers     SegmentMember[]
  campaignRecipients CampaignRecipient[]

  @@unique([tenantId, phoneNumber])
}

model Tag {
  id               String            @id @default(cuid())
  tenantId         String
  name             String
  color            String?
  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
  tenant           Tenant            @relation(fields: [tenantId], references: [id])
  contactTags      ContactTag[]
  conversationTags ConversationTag[]

  @@unique([tenantId, name])
}

model ContactTag {
  id        String   @id @default(cuid())
  tenantId  String
  contactId String
  tagId     String
  createdAt DateTime @default(now())
  contact   Contact  @relation(fields: [contactId], references: [id])
  tag       Tag      @relation(fields: [tagId], references: [id])

  @@unique([contactId, tagId])
}

model Conversation {
  id               String                 @id @default(cuid())
  tenantId         String
  channelId        String
  contactId        String
  subject          String?
  status           ConversationStatus     @default(OPEN)
  priority         ConversationPriority   @default(NORMAL)
  assignedUserId   String?
  firstMessageAt   DateTime?
  lastMessageAt    DateTime?
  lastInboundAt    DateTime?
  lastOutboundAt   DateTime?
  resolvedAt       DateTime?
  createdAt        DateTime               @default(now())
  updatedAt        DateTime               @updatedAt
  tenant           Tenant                 @relation(fields: [tenantId], references: [id])
  channel          Channel                @relation(fields: [channelId], references: [id])
  contact          Contact                @relation(fields: [contactId], references: [id])
  assignedUser     User?                  @relation(fields: [assignedUserId], references: [id])
  messages         Message[]
  notes            ConversationNote[]
  activities       ConversationActivity[]
  conversationTags ConversationTag[]

  @@index([tenantId, status])
  @@index([tenantId, assignedUserId])
  @@index([tenantId, lastMessageAt])
}

model Message {
  id                String           @id @default(cuid())
  tenantId          String
  conversationId    String
  channelId         String
  contactId         String?
  direction         MessageDirection
  type              MessageType      @default(TEXT)
  providerMessageId String?          @unique
  replyToMessageId  String?
  contentText       String?
  mediaUrl          String?
  mimeType          String?
  deliveryStatus    DeliveryStatus   @default(QUEUED)
  failedReason      String?
  sentByUserId      String?
  sentAt            DateTime?
  deliveredAt       DateTime?
  readAt            DateTime?
  createdAt         DateTime         @default(now())
  tenant            Tenant           @relation(fields: [tenantId], references: [id])
  conversation      Conversation     @relation(fields: [conversationId], references: [id])
  channel           Channel          @relation(fields: [channelId], references: [id])
  contact           Contact?         @relation(fields: [contactId], references: [id])
  sentByUser        User?            @relation(fields: [sentByUserId], references: [id])
}

model ConversationNote {
  id             String       @id @default(cuid())
  tenantId       String
  conversationId String
  userId         String
  content        String
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  tenant         Tenant       @relation(fields: [tenantId], references: [id])
  conversation   Conversation @relation(fields: [conversationId], references: [id])
  user           User         @relation(fields: [userId], references: [id])
}

model ConversationTag {
  id             String       @id @default(cuid())
  tenantId       String
  conversationId String
  tagId          String
  createdAt      DateTime     @default(now())
  conversation   Conversation @relation(fields: [conversationId], references: [id])
  tag            Tag          @relation(fields: [tagId], references: [id])

  @@unique([conversationId, tagId])
}

model ConversationActivity {
  id             String       @id @default(cuid())
  tenantId       String
  conversationId String
  actorUserId    String?
  activityType   String
  metadataJson   String?
  createdAt      DateTime     @default(now())
  tenant         Tenant       @relation(fields: [tenantId], references: [id])
  conversation   Conversation @relation(fields: [conversationId], references: [id])
  actorUser      User?        @relation("ActorActivities", fields: [actorUserId], references: [id])
}

model ContactSegment {
  id          String              @id @default(cuid())
  tenantId    String
  name        String
  description String?
  rulesJson   String?
  createdAt   DateTime            @default(now())
  updatedAt   DateTime            @updatedAt
  tenant      Tenant              @relation(fields: [tenantId], references: [id])
  members     SegmentMember[]
  campaigns   BroadcastCampaign[]
}

model SegmentMember {
  id        String         @id @default(cuid())
  tenantId  String
  segmentId String
  contactId String
  createdAt DateTime       @default(now())
  segment   ContactSegment @relation(fields: [segmentId], references: [id])
  contact   Contact        @relation(fields: [contactId], references: [id])

  @@unique([segmentId, contactId])
}

model MessageTemplate {
  id                 String                 @id @default(cuid())
  tenantId           String
  channelId          String
  name               String
  category           String
  languageCode       String
  templateType       String?
  bodyText           String
  headerType         String?
  footerText         String?
  buttonsJson        String?
  providerTemplateId String?
  approvalStatus     TemplateApprovalStatus @default(DRAFT)
  rejectedReason     String?
  createdAt          DateTime               @default(now())
  updatedAt          DateTime               @updatedAt
  tenant             Tenant                 @relation(fields: [tenantId], references: [id])
  channel            Channel                @relation(fields: [channelId], references: [id])
  campaigns          BroadcastCampaign[]
}

model BroadcastCampaign {
  id              String               @id @default(cuid())
  tenantId        String
  channelId       String
  templateId      String
  createdByUserId String
  name            String
  campaignType    CampaignType         @default(BROADCAST)
  audienceType    CampaignAudienceType
  segmentId       String?
  scheduledAt     DateTime?
  startedAt       DateTime?
  finishedAt      DateTime?
  status          CampaignStatus       @default(DRAFT)
  totalRecipients Int                  @default(0)
  totalSent       Int                  @default(0)
  totalDelivered  Int                  @default(0)
  totalRead       Int                  @default(0)
  totalFailed     Int                  @default(0)
  createdAt       DateTime             @default(now())
  updatedAt       DateTime             @updatedAt
  tenant          Tenant               @relation(fields: [tenantId], references: [id])
  channel         Channel              @relation(fields: [channelId], references: [id])
  template        MessageTemplate      @relation(fields: [templateId], references: [id])
  createdByUser   User                 @relation(fields: [createdByUserId], references: [id])
  segment         ContactSegment?      @relation(fields: [segmentId], references: [id])
  recipients      CampaignRecipient[]

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

model CampaignRecipient {
  id                String            @id @default(cuid())
  tenantId          String
  campaignId        String
  contactId         String
  phoneNumber       String
  sendStatus        DeliveryStatus    @default(QUEUED)
  sendAttempts      Int               @default(0)
  maxSendAttempts   Int               @default(3)
  lastAttemptAt     DateTime?
  nextRetryAt       DateTime?
  failureReason     String?
  providerMessageId String?
  sentAt            DateTime?
  deliveredAt       DateTime?
  readAt            DateTime?
  createdAt         DateTime          @default(now())
  campaign          BroadcastCampaign @relation(fields: [campaignId], references: [id])
  contact           Contact           @relation(fields: [contactId], references: [id])

  @@index([campaignId, sendStatus, nextRetryAt])
  @@index([campaignId, sendStatus])
}

model BackgroundJobState {
  id                String   @id @default(cuid())
  jobName           String   @unique
  lockedBy          String
  lockedUntil       DateTime?
  runs              Int      @default(0)
  consecutiveFailures Int     @default(0)
  lastRunStartedAt  DateTime?
  lastRunCompletedAt DateTime?
  lastRunStatus     String?
  lastRunSummaryJson String?
  lastError         String?
  lastFailureAt     DateTime?
  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt
}

model AuditLog {
  id           String   @id @default(cuid())
  tenantId     String
  actorUserId  String?
  entityType   String
  entityId     String
  action       String
  metadataJson String?
  ipAddress    String?
  userAgent    String?
  createdAt    DateTime @default(now())
  tenant       Tenant   @relation(fields: [tenantId], references: [id])
  actorUser    User?    @relation(fields: [actorUserId], references: [id])
}

model WebhookEvent {
  id              String    @id @default(cuid())
  tenantId        String
  channelId       String?
  eventType       String
  providerEventId String?
  eventHash       String?
  payloadJson     String
  processStatus   String
  failedReason    String?
  createdAt       DateTime  @default(now())
  processedAt     DateTime?
  tenant          Tenant    @relation(fields: [tenantId], references: [id])
  channel         Channel?  @relation(fields: [channelId], references: [id])

  @@index([tenantId, channelId, eventHash])
}

model UsageMetric {
  id               String   @id @default(cuid())
  tenantId         String
  metricDate       DateTime
  inboundMessages  Int      @default(0)
  outboundMessages Int      @default(0)
  activeContacts   Int      @default(0)
  activeAgents     Int      @default(0)
  broadcastSent    Int      @default(0)
  storageUsedMb    Int      @default(0)
  createdAt        DateTime @default(now())
  updatedAt        DateTime @updatedAt
  tenant           Tenant   @relation(fields: [tenantId], references: [id])

  @@unique([tenantId, metricDate])
}

model BillingInvoice {
  id            String           @id @default(cuid())
  tenantId      String
  planId        String
  invoiceNumber String           @unique
  periodStart   DateTime
  periodEnd     DateTime
  subtotal      Int
  taxAmount     Int
  totalAmount   Int
  paymentStatus PaymentStatus    @default(UNPAID)
  dueDate       DateTime
  paidAt        DateTime?
  createdAt     DateTime         @default(now())
  updatedAt     DateTime         @updatedAt
  tenant        Tenant           @relation(fields: [tenantId], references: [id])
  plan          SubscriptionPlan @relation(fields: [planId], references: [id])
}
