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

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

/// Категория изделий (игрушки, сувениры и т.д.)
model Category {
  id       String    @id @default(cuid())
  name     String
  slug     String    @unique
  sort     Int       @default(0)
  products Product[]
}

model Product {
  id          String   @id @default(cuid())
  title       String
  slug        String   @unique
  shortDescription String?
  description String?
  /// Количество на складе
  quantity    Int      @default(0)
  /// Материалы (список, например: ["хлопок","дерево"])
  materials   String   @default("[]")
  /// Цена в копейках (целое число, без дробной части)
  priceCents  Int
  imageUrl    String?
  published   Boolean  @default(false)
  category    Category @relation(fields: [categoryId], references: [id], onDelete: Restrict)
  categoryId  String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  images ProductImage[]
  reviews Review[]
  orderItems OrderItem[]
  cartItems CartItem[]
}

model ProductImage {
  id        String   @id @default(cuid())
  url       String
  sort      Int      @default(0)
  createdAt DateTime @default(now())

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

  @@index([productId, sort])
}

/// Медиатека админки: зарегистрированные файлы /uploads/... (без обязательной привязки к товару).
model GalleryImage {
  id        String   @id @default(cuid())
  url       String   @unique
  isResized Boolean  @default(false)
  createdAt DateTime @default(now())

  catalogSliderSlides CatalogSliderSlide[]
}

/// Слайды главной витрины (каталог): картинка из галереи + подпись.
model CatalogSliderSlide {
  id             String       @id @default(cuid())
  sortOrder      Int
  caption        String       @default("")
  textColor      String       @default("#ffffff")
  galleryImageId String
  galleryImage   GalleryImage @relation(fields: [galleryImageId], references: [id], onDelete: Cascade)

  @@index([sortOrder])
}

model User {
  id           String   @id @default(cuid())
  email        String   @unique
  displayName  String?
  avatar       String?
  avatarStyle  String?
  passwordHash String?
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt

  codes AuthCode[]
  addresses ShippingAddress[]
  cartItems CartItem[]
  orders Order[]
  reviews Review[]
  orderMessageReadStates UserOrderMessageReadState[]
  oauthAccounts OAuthAccount[]
  pendingEmails PendingEmail[]
  notificationPreference NotificationPreference?
  notificationLogs NotificationLog[]
}

/// Прочитанность чата по заказу (для сообщений от админа после lastReadAt)
model UserOrderMessageReadState {
  id         String   @id @default(cuid())
  lastReadAt DateTime @default("1970-01-01T00:00:00.000Z")
  updatedAt  DateTime @updatedAt

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

  @@unique([userId, orderId])
  @@index([userId])
}

model CartItem {
  id        String   @id @default(cuid())
  qty       Int
  createdAt DateTime @default(now())

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

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

  @@unique([userId, productId])
  @@index([userId])
}

model Order {
  id                  String      @id @default(cuid())
  /// Статус заказа (валидация переходов на уровне API)
  status              String      @default("DRAFT")
  deliveryFeeLocked   Boolean     @default(false)
  /// 'delivery' | 'pickup'
  deliveryType        String      @default("delivery")
  /// RUSSIAN_POST | OZON_PVZ | YANDEX_PVZ | FIVE_POST при deliveryType=delivery
  deliveryCarrier     String?
  /// 'online' | 'on_pickup' — способ расчёта для заказа
  paymentMethod       String      @default("online")
  itemsSubtotalCents  Int         @default(0)
  deliveryFeeCents    Int         @default(0)
  totalCents          Int         @default(0)
  currency            String      @default("RUB")
  addressSnapshotJson String?
  comment             String?
  createdAt           DateTime    @default(now())
  updatedAt           DateTime    @updatedAt

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

  items    OrderItem[]
  messages OrderMessage[]
  payments Payment[]
  messageReadStates UserOrderMessageReadState[]

  @@index([userId, createdAt])
  @@index([status, updatedAt])
}

model Payment {
  id                String    @id @default(cuid())
  orderId           String
  order             Order     @relation(fields: [orderId], references: [id], onDelete: Cascade)
  yookassaPaymentId String    @unique
  status            String
  amountCents       Int
  currency          String    @default("RUB")
  confirmationUrl   String?
  expiresAt         DateTime?
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt

  @@index([orderId])
}

model OrderItem {
  id                 String @id @default(cuid())
  qty                Int
  titleSnapshot      String
  priceCentsSnapshot Int

  order   Order  @relation(fields: [orderId], references: [id], onDelete: Cascade)
  orderId String

  product   Product @relation(fields: [productId], references: [id], onDelete: Restrict)
  productId String

  @@index([orderId])
}

model OrderMessage {
  id             String            @id @default(cuid())
  /// 'user' | 'admin'
  authorType     String
  text           String
  /// URL вида /uploads/… (чек к оплате и т.п.)
  attachmentUrl  String?
  createdAt      DateTime          @default(now())

  order   Order  @relation(fields: [orderId], references: [id], onDelete: Cascade)
  orderId String

  @@index([orderId, createdAt])
}

model Review {
  id          String       @id @default(cuid())
  rating      Int
  text        String?
  imageUrl    String?
  /// 'pending' | 'approved' | 'rejected'
  status      String       @default("pending")
  createdAt   DateTime     @default(now())
  moderatedAt DateTime?

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

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

  @@index([productId, status, createdAt])
  @@index([status, createdAt])
  @@unique([productId, userId])
}

model ShippingAddress {
  id             String   @id @default(cuid())
  label          String?
  recipientName  String
  recipientPhone String
  addressLine    String
  comment        String?
  lat            Float
  lng            Float
  isDefault      Boolean  @default(false)
  createdAt      DateTime @default(now())
  updatedAt      DateTime @updatedAt

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

  @@index([userId, isDefault])
  @@index([userId, updatedAt])
}

model OAuthAccount {
  id               String   @id @default(cuid())
  /// 'vk' | 'yandex'
  provider         String
  providerUserId   String
  accessToken      String?
  refreshToken     String?
  createdAt        DateTime @default(now())
  updatedAt        DateTime @updatedAt

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

  @@unique([provider, providerUserId])
  @@index([userId])
}

model PendingEmail {
  id        String   @id @default(cuid())
  userId    String
  email     String
  token     String   @unique
  expiresAt DateTime
  createdAt DateTime @default(now())

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

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

model AuthCode {
  id        String   @id @default(cuid())
  email     String
  codeHash  String
  purpose   String
  expiresAt DateTime
  usedAt    DateTime?
  createdAt DateTime @default(now())

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

  @@index([email, purpose])
  @@index([expiresAt])
}

/// Настройки оповещений пользователя
model NotificationPreference {
  id                     String   @id @default(cuid())
  userId                 String   @unique
  globalEnabled          Boolean  @default(true)
  orderCreated           Boolean  @default(true)
  orderStatusChanged     Boolean  @default(true)
  orderMessageReceived   Boolean  @default(true)
  paymentStatusChanged   Boolean  @default(true)
  deliveryFeeAdjusted    Boolean  @default(true)
  createdAt              DateTime @default(now())
  updatedAt              DateTime @updatedAt

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

/// Настройки оповещений админа
model AdminNotificationSettings {
  id                  String   @id @default(cuid())
  emailEnabled        Boolean  @default(true)
  telegramEnabled     Boolean  @default(false)
  telegramChatId      String?
  newOrder            Boolean  @default(true)
  newOrderMessage     Boolean  @default(true)
  newReview           Boolean  @default(true)
  authCodeDuplicate   Boolean  @default(false)
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt
}

/// Лог отправки оповещений
model NotificationLog {
  id          String   @id @default(cuid())
  userId      String?
  eventType   String
  channel     String
  status      String
  error       String?
  payload     String
  attempts    Int      @default(0)
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

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

  @@index([status, createdAt])
  @@index([userId, createdAt])
}

/// Результат ручной проверки тест-чеклиста
model ChecklistResult {
  id        String   @id @default(cuid())
  itemKey   String   @unique
  passed    Boolean
  comment   String?
  checkedAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}
