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

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

model User {
  id String @id @default(uuid())

  // Credentials
  email    String  @unique
  password String?

  // Relations
  memberships ProjectMembership[]

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

  @@map("users")
}

model Project {
  id String @id @default(uuid())

  // Details
  name String
  url  String

  // Verified domain
  verified Boolean @default(false)
  email    String?
  from     String?

  // API access
  public String @unique
  secret String @unique

  // Relations
  memberships ProjectMembership[]
  contacts    Contact[]
  campaigns   Campaign[]
  actions     Action[]
  events      Event[]
  templates   Template[]
  emails      Email[]

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

  @@map("projects")
}

// Table to maintain many-to-many relationship between Account and Project
model ProjectMembership {
  role Role @default(MEMBER)

  // Relations
  user      User    @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId    String
  project   Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String

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

  @@id(fields: [userId, projectId])
  @@map("projectmemberhips")
}

model Event {
  id String @id @default(uuid())

  // Details
  name String

  // Relations
  project   Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String

  template   Template? @relation(fields: [templateId], references: [id], onDelete: Cascade)
  templateId String?

  campaign   Campaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
  campaignId String?

  actions    Action[]  @relation("ActionToEvent")
  notActions Action[]  @relation("ActionToNotEvent")
  triggers   Trigger[]

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

  @@index(fields: [projectId, templateId, campaignId])
  @@map("events")
}

model Template {
  id String @id @default(uuid())

  // Details
  subject String
  body    String
  email   String?
  from    String?

  type  TemplateType
  style TemplateStyle

  // Relations
  project   Project  @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String
  events    Event[]
  actions   Action[]

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

  @@index(fields: [projectId])
  @@map("templates")
}

model Action {
  id String @id @default(uuid())

  // Details
  name    String
  runOnce Boolean @default(false)
  delay   Int     @default(0)

  // Relations
  project   Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String

  template   Template @relation(fields: [templateId], references: [id])
  templateId String

  events    Event[] @relation("ActionToEvent")
  notevents Event[] @relation("ActionToNotEvent")

  triggers Trigger[]
  emails   Email[]
  tasks    Task[]

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

  @@index(fields: [projectId, templateId])
  @@map("actions")
}

model Campaign {
  id String @id @default(uuid())

  subject String
  body    String
  email   String?
  from    String?

  status    CampaignStatus @default(DRAFT)
  delivered DateTime?

  style      TemplateStyle
  // Relations
  project    Project       @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId  String
  emails     Email[]
  tasks      Task[]
  recipients Contact[]
  events     Event[]

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

  @@index(fields: [projectId])
  @@map("campaigns")
}

model Trigger {
  id String @id @default(uuid())

  // Relations
  contact   Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
  contactId String

  event    Event?  @relation(fields: [eventId], references: [id], onDelete: Cascade)
  eventId  String?
  action   Action? @relation(fields: [actionId], references: [id], onDelete: Cascade)
  actionId String?

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

  @@index(fields: [contactId, eventId, actionId, createdAt])
  @@map("triggers")
}

model Contact {
  id String @id @default(uuid())

  // Details
  email      String
  subscribed Boolean @default(true)
  data       String?

  // Relations
  project   Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String

  emails    Email[]
  triggers  Trigger[]
  tasks     Task[]
  campaigns Campaign[]

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

  @@index(fields: [projectId])
  @@map("contacts")
}

model Email {
  id String @id @default(uuid())

  messageId String      @unique
  subject   String?
  body      String?
  status    EmailStatus @default(SENT)

  // Relations
  project   Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
  projectId String?

  action   Action? @relation(fields: [actionId], references: [id], onDelete: Cascade)
  actionId String?

  campaign   Campaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
  campaignId String?

  contact   Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
  contactId String

  clicks Click[]

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

  @@index(fields: [projectId, actionId, campaignId, contactId, createdAt])
  @@map("emails")
}

model Click {
  id String @id @default(uuid())

  link String

  // Relations
  email   Email  @relation(fields: [emailId], references: [id], onDelete: Cascade)
  emailId String

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

  @@index([emailId, createdAt])
  @@map("clicks")
}

model Task {
  id String @id @default(uuid())

  // Details
  runBy DateTime @default(now())

  // Relations
  action   Action? @relation(fields: [actionId], references: [id], onDelete: Cascade)
  actionId String?

  campaign   Campaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
  campaignId String?

  contact   Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
  contactId String

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

  @@index([runBy, createdAt])
  @@map("tasks")
}

enum TemplateType {
  MARKETING
  TRANSACTIONAL
}

enum TemplateStyle {
  PLUNK
  HTML
}

enum EmailStatus {
  SENT
  DELIVERED
  BOUNCED
  OPENED
  COMPLAINT
}

enum CampaignStatus {
  DRAFT
  SCHEDULED
  DELIVERED
}

enum Role {
  OWNER
  ADMIN
  MEMBER
}
