// 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"
    previewFeatures = ["relationJoins"]
}

datasource db {
    provider = "postgresql"
    // NOTE: When using mysql or sqlserver, uncomment the @db.Text annotations in model Account below
    // Further reading:
    // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema
    // https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string
    url      = env("DATABASE_URL")
}

// Necessary for Next auth
model Account {
    id                String  @id @default(cuid())
    userId            Int
    type              String
    provider          String
    providerAccountId String
    refresh_token     String? // @db.Text
    access_token      String? // @db.Text
    expires_at        Int?
    token_type        String?
    scope             String?
    id_token          String? // @db.Text
    session_state     String?
    user              User    @relation(fields: [userId], references: [id], onDelete: Cascade)

    @@unique([provider, providerAccountId])
}

model Session {
    id           String   @id @default(cuid())
    sessionToken String   @unique
    userId       Int
    expires      DateTime
    user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
    id                  Int                  @id @default(autoincrement())
    name                String?
    email               String?              @unique
    emailVerified       DateTime?
    image               String?
    currency            String               @default("USD")
    accounts            Account[]
    sessions            Session[]
    groups              Group[]
    associatedGroups    GroupUser[]
    expenseParticipants ExpenseParticipant[]
    expenseNotes        ExpenseNote[]
    userBalances        Balance[]            @relation("UserBalance")
    friendBalances      Balance[]            @relation("FriendBalance")
    groupUserBalances   GroupBalance[]       @relation("GroupUserBalance")
    groupFriendBalances GroupBalance[]       @relation("GroupFriendBalance")
    paidExpenses        Expense[]            @relation("PaidByUser")
    addedExpenses       Expense[]            @relation("AddedByUser")
    deletedExpenses     Expense[]            @relation("DeletedByUser")
    updatedExpenses     Expense[]            @relation("UpdatedByUser")
}

model VerificationToken {
    identifier String
    token      String   @unique
    expires    DateTime

    @@unique([identifier, token])
}

model Balance {
    userId                Int
    currency              String
    friendId              Int
    amount                Int
    createdAt             DateTime @default(now())
    updatedAt             DateTime @updatedAt
    importedFromSplitwise Boolean  @default(false)
    user                  User     @relation(name: "UserBalance", fields: [userId], references: [id], onDelete: Cascade)
    friend                User     @relation(name: "FriendBalance", fields: [friendId], references: [id], onDelete: Cascade)

    @@id([userId, currency, friendId])
}

model Group {
    id               Int            @id @default(autoincrement())
    publicId         String         @unique
    name             String
    userId           Int
    defaultCurrency  String         @default("USD")
    createdAt        DateTime       @default(now())
    updatedAt        DateTime       @updatedAt
    splitwiseGroupId String?        @unique
    createdBy        User           @relation(fields: [userId], references: [id], onDelete: Cascade)
    groupUsers       GroupUser[]
    expenses         Expense[]
    groupBalances    GroupBalance[]
}

model GroupUser {
    groupId Int
    userId  Int
    user    User  @relation(fields: [userId], references: [id], onDelete: Cascade)
    group   Group @relation(fields: [groupId], references: [id], onDelete: Cascade)

    @@id([groupId, userId])
}

model GroupBalance {
    groupId   Int
    currency  String
    userId    Int
    firendId  Int
    amount    Int
    updatedAt DateTime @updatedAt
    group     Group    @relation(fields: [groupId], references: [id], onDelete: Cascade)
    user      User     @relation(name: "GroupUserBalance", fields: [userId], references: [id], onDelete: Cascade)
    friend    User     @relation(name: "GroupFriendBalance", fields: [firendId], references: [id], onDelete: Cascade)

    @@id([groupId, currency, firendId, userId])
}

enum SplitType {
    EQUAL
    PERCENTAGE
    EXACT
    SHARE
    ADJUSTMENT
    SETTLEMENT
}

model Expense {
    id                  String               @id @default(cuid())
    paidBy              Int
    addedBy             Int
    name                String
    category            String
    amount              Int
    splitType           SplitType            @default(EQUAL)
    expenseDate         DateTime             @default(now())
    createdAt           DateTime             @default(now())
    updatedAt           DateTime             @updatedAt
    currency            String
    fileKey             String?
    groupId             Int?
    deletedAt           DateTime?
    deletedBy           Int?
    updatedBy           Int?
    group               Group?               @relation(fields: [groupId], references: [id], onDelete: Cascade)
    paidByUser          User                 @relation(name: "PaidByUser", fields: [paidBy], references: [id], onDelete: Cascade)
    addedByUser         User                 @relation(name: "AddedByUser", fields: [addedBy], references: [id], onDelete: Cascade)
    deletedByUser       User?                @relation(name: "DeletedByUser", fields: [deletedBy], references: [id], onDelete: Cascade)
    updatedByUser       User?                @relation(name: "UpdatedByUser", fields: [updatedBy], references: [id], onDelete: SetNull)
    expenseParticipants ExpenseParticipant[]
    expenseNotes        ExpenseNote[]

    @@index([groupId])
    @@index([paidBy])
}

model ExpenseParticipant {
    expenseId String
    userId    Int
    amount    Int
    user      User    @relation(fields: [userId], references: [id], onDelete: Cascade)
    expense   Expense @relation(fields: [expenseId], references: [id], onDelete: Cascade)

    @@id([expenseId, userId])
}

model ExpenseNote {
    id          String   @id @default(cuid())
    expenseId   String
    note        String
    createdById Int
    createdAt   DateTime @default(now())
    createdBy   User     @relation(fields: [createdById], references: [id], onDelete: Cascade)
    expense     Expense  @relation(fields: [expenseId], references: [id], onDelete: Cascade)
}

model PushNotification {
    userId       Int    @id
    subscription String
}
