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

// Конфигурация для автоматического seeding
generator seed {
  provider = "prisma-client-js"
  output   = "./generated/client"
}

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

model User {
  id             String        @id @default(cuid())
  phone          String        @unique
  avatar         String?
  managerName    String?
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt
  organizationId String?
  sentMessages   Message[]     @relation("SentMessages")
  smsCodes       SmsCode[]
  organization   Organization? @relation(fields: [organizationId], references: [id])

  @@map("users")
}

model Admin {
  id        String    @id @default(cuid())
  username  String    @unique
  password  String // Хеш пароля
  email     String?   @unique
  isActive  Boolean   @default(true)
  lastLogin DateTime?
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt

  @@map("admins")
}

model SmsCode {
  id          String   @id @default(cuid())
  code        String
  phone       String
  expiresAt   DateTime
  isUsed      Boolean  @default(false)
  attempts    Int      @default(0)
  maxAttempts Int      @default(3)
  createdAt   DateTime @default(now())
  userId      String?
  user        User?    @relation(fields: [userId], references: [id])

  @@map("sms_codes")
}

model Organization {
  id                         String                @id @default(cuid())
  inn                        String                @unique
  kpp                        String?
  name                       String?
  fullName                   String?
  ogrn                       String?
  ogrnDate                   DateTime?
  type                       OrganizationType
  market                     String?
  createdAt                  DateTime              @default(now())
  updatedAt                  DateTime              @updatedAt
  address                    String?
  addressFull                String?
  status                     String?
  actualityDate              DateTime?
  registrationDate           DateTime?
  liquidationDate            DateTime?
  managementName             String?
  managementPost             String?
  opfCode                    String?
  opfFull                    String?
  opfShort                   String?
  okato                      String?
  oktmo                      String?
  okpo                       String?
  okved                      String?
  phones                     Json?
  emails                     Json?
  employeeCount              Int?
  revenue                    BigInt?
  taxSystem                  String?
  dadataData                 Json?
  apiKeys                    ApiKey[]
  carts                      Cart?
  counterpartyOf             Counterparty[]        @relation("CounterpartyOf")
  organizationCounterparties Counterparty[]        @relation("OrganizationCounterparties")
  receivedRequests           CounterpartyRequest[] @relation("ReceivedRequests")
  sentRequests               CounterpartyRequest[] @relation("SentRequests")
  employees                  Employee[]
  favorites                  Favorites[]
  receivedMessages           Message[]             @relation("ReceivedMessages")
  sentMessages               Message[]             @relation("SentMessages")
  products                   Product[]
  services                   Service[]
  supplies                   Supply[]
  users                      User[]
  logistics                  Logistics[]
  supplyOrders               SupplyOrder[]
  partnerSupplyOrders        SupplyOrder[]         @relation("SupplyOrderPartner")
  fulfillmentSupplyOrders    SupplyOrder[]         @relation("SupplyOrderFulfillmentCenter")
  logisticsSupplyOrders      SupplyOrder[]         @relation("SupplyOrderLogistics")
  wildberriesSupplies        WildberriesSupply[]
  supplySuppliers            SupplySupplier[]      @relation("SupplySuppliers")
  externalAds                ExternalAd[]          @relation("ExternalAds")
  wbWarehouseCaches          WBWarehouseCache[]    @relation("WBWarehouseCaches")
  sellerStatsCaches          SellerStatsCache[]    @relation("SellerStatsCaches")
  sellerSupplies             Supply[]              @relation("SellerSupplies")

  @@map("organizations")
}

model ApiKey {
  id             String          @id @default(cuid())
  marketplace    MarketplaceType
  apiKey         String
  isActive       Boolean         @default(true)
  createdAt      DateTime        @default(now())
  updatedAt      DateTime        @updatedAt
  validationData Json?
  organizationId String
  organization   Organization    @relation(fields: [organizationId], references: [id])

  @@unique([organizationId, marketplace])
  @@map("api_keys")
}

model CounterpartyRequest {
  id         String                    @id @default(cuid())
  status     CounterpartyRequestStatus @default(PENDING)
  createdAt  DateTime                  @default(now())
  updatedAt  DateTime                  @updatedAt
  senderId   String
  receiverId String
  message    String?
  receiver   Organization              @relation("ReceivedRequests", fields: [receiverId], references: [id])
  sender     Organization              @relation("SentRequests", fields: [senderId], references: [id])

  @@unique([senderId, receiverId])
  @@map("counterparty_requests")
}

model Counterparty {
  id             String       @id @default(cuid())
  createdAt      DateTime     @default(now())
  organizationId String
  counterpartyId String
  counterparty   Organization @relation("CounterpartyOf", fields: [counterpartyId], references: [id])
  organization   Organization @relation("OrganizationCounterparties", fields: [organizationId], references: [id])

  @@unique([organizationId, counterpartyId])
  @@map("counterparties")
}

model Message {
  id                     String       @id @default(cuid())
  content                String?
  type                   MessageType  @default(TEXT)
  voiceUrl               String?
  voiceDuration          Int?
  fileUrl                String?
  fileName               String?
  fileSize               Int?
  fileType               String?
  isRead                 Boolean      @default(false)
  createdAt              DateTime     @default(now())
  updatedAt              DateTime     @updatedAt
  senderId               String
  senderOrganizationId   String
  receiverOrganizationId String
  receiverOrganization   Organization @relation("ReceivedMessages", fields: [receiverOrganizationId], references: [id])
  sender                 User         @relation("SentMessages", fields: [senderId], references: [id])
  senderOrganization     Organization @relation("SentMessages", fields: [senderOrganizationId], references: [id])

  @@index([senderOrganizationId, receiverOrganizationId, createdAt])
  @@index([receiverOrganizationId, isRead])
  @@map("messages")
}

model Service {
  id             String       @id @default(cuid())
  name           String
  description    String?
  price          Decimal      @db.Decimal(10, 2)
  imageUrl       String?
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organizationId String
  organization   Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("services")
}

model Supply {
  id             String        @id @default(cuid())
  name           String
  description    String?
  price          Decimal       @db.Decimal(10, 2) // Цена закупки у поставщика (не меняется)
  pricePerUnit   Decimal?      @db.Decimal(10, 2) // Цена продажи селлерам (устанавливается фулфилментом)
  quantity       Int           @default(0)
  unit           String        @default("шт")
  category       String        @default("Расходники")
  status         String        @default("planned") // planned, in-transit, delivered, in-stock
  date           DateTime      @default(now())
  supplier       String        @default("Не указан")
  minStock       Int           @default(0)
  currentStock   Int           @default(0)
  usedStock      Int           @default(0) // Количество использованных расходников
  imageUrl       String?
  type           SupplyType    @default(FULFILLMENT_CONSUMABLES) // Тип расходников
  sellerOwnerId  String? // ID селлера-владельца (для расходников селлеров)
  sellerOwner    Organization? @relation("SellerSupplies", fields: [sellerOwnerId], references: [id], onDelete: SetNull)
  shopLocation   String? // Местоположение в магазине фулфилмента
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt
  organizationId String
  organization   Organization  @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("supplies")
}

model Category {
  id        String    @id @default(cuid())
  name      String    @unique
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  products  Product[]

  @@map("categories")
}

model Product {
  id               String            @id @default(cuid())
  name             String
  article          String
  description      String?
  price            Decimal           @db.Decimal(12, 2)
  pricePerSet      Decimal?          @db.Decimal(12, 2)
  quantity         Int               @default(0)
  setQuantity      Int?
  ordered          Int?
  inTransit        Int?
  stock            Int?
  sold             Int?
  type             ProductType       @default(PRODUCT)
  categoryId       String?
  brand            String?
  color            String?
  size             String?
  weight           Decimal?          @db.Decimal(8, 3)
  dimensions       String?
  material         String?
  images           Json              @default("[]")
  mainImage        String?
  isActive         Boolean           @default(true)
  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
  organizationId   String
  cartItems        CartItem[]
  favorites        Favorites[]
  supplyOrderItems SupplyOrderItem[]
  category         Category?         @relation(fields: [categoryId], references: [id])
  organization     Organization      @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@unique([organizationId, article])
  @@map("products")
}

model Cart {
  id             String       @id @default(cuid())
  organizationId String       @unique
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  items          CartItem[]
  organization   Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("carts")
}

model CartItem {
  id        String   @id @default(cuid())
  cartId    String
  productId String
  quantity  Int      @default(1)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  cart      Cart     @relation(fields: [cartId], references: [id], onDelete: Cascade)
  product   Product  @relation(fields: [productId], references: [id], onDelete: Cascade)

  @@unique([cartId, productId])
  @@map("cart_items")
}

model Favorites {
  id             String       @id @default(cuid())
  organizationId String
  productId      String
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  product        Product      @relation(fields: [productId], references: [id], onDelete: Cascade)

  @@unique([organizationId, productId])
  @@map("favorites")
}

model Employee {
  id               String             @id @default(cuid())
  firstName        String
  lastName         String
  middleName       String?
  birthDate        DateTime?
  avatar           String?
  passportPhoto    String?
  passportSeries   String?
  passportNumber   String?
  passportIssued   String?
  passportDate     DateTime?
  address          String?
  position         String
  department       String?
  hireDate         DateTime
  salary           Float?
  status           EmployeeStatus     @default(ACTIVE)
  phone            String
  email            String?
  telegram         String?
  whatsapp         String?
  emergencyContact String?
  emergencyPhone   String?
  organizationId   String
  createdAt        DateTime           @default(now())
  updatedAt        DateTime           @updatedAt
  scheduleRecords  EmployeeSchedule[]
  organization     Organization       @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("employees")
}

model EmployeeSchedule {
  id            String         @id @default(cuid())
  date          DateTime
  status        ScheduleStatus
  hoursWorked   Float?
  overtimeHours Float?
  notes         String?
  employeeId    String
  createdAt     DateTime       @default(now())
  updatedAt     DateTime       @updatedAt
  employee      Employee       @relation(fields: [employeeId], references: [id], onDelete: Cascade)

  @@unique([employeeId, date])
  @@map("employee_schedules")
}

model WildberriesSupply {
  id             String                  @id @default(cuid())
  organizationId String
  deliveryDate   DateTime?
  status         WildberriesSupplyStatus @default(DRAFT)
  totalAmount    Decimal                 @db.Decimal(12, 2)
  totalItems     Int
  createdAt      DateTime                @default(now())
  updatedAt      DateTime                @updatedAt
  organization   Organization            @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  cards          WildberriesSupplyCard[]

  @@map("wildberries_supplies")
}

model WildberriesSupplyCard {
  id               String            @id @default(cuid())
  supplyId         String
  nmId             String
  vendorCode       String
  title            String
  brand            String?
  price            Decimal           @db.Decimal(12, 2)
  discountedPrice  Decimal?          @db.Decimal(12, 2)
  quantity         Int
  selectedQuantity Int
  selectedMarket   String?
  selectedPlace    String?
  sellerName       String?
  sellerPhone      String?
  deliveryDate     DateTime?
  mediaFiles       Json              @default("[]")
  selectedServices Json              @default("[]")
  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
  supply           WildberriesSupply @relation(fields: [supplyId], references: [id], onDelete: Cascade)

  @@map("wildberries_supply_cards")
}

enum OrganizationType {
  FULFILLMENT
  SELLER
  LOGIST
  WHOLESALE
}

enum MarketplaceType {
  WILDBERRIES
  OZON
}

enum CounterpartyRequestStatus {
  PENDING
  ACCEPTED
  REJECTED
  CANCELLED
}

enum MessageType {
  TEXT
  VOICE
  IMAGE
  FILE
}

enum EmployeeStatus {
  ACTIVE
  VACATION
  SICK
  FIRED
}

enum ScheduleStatus {
  WORK
  WEEKEND
  VACATION
  SICK
  ABSENT
}

enum SupplyOrderStatus {
  PENDING
  CONFIRMED
  IN_TRANSIT
  SUPPLIER_APPROVED
  LOGISTICS_CONFIRMED
  SHIPPED
  DELIVERED
  CANCELLED
}

enum WildberriesSupplyStatus {
  DRAFT
  CREATED
  IN_PROGRESS
  DELIVERED
  CANCELLED
}

enum ProductType {
  PRODUCT
  CONSUMABLE
}

enum SupplyType {
  FULFILLMENT_CONSUMABLES // Расходники фулфилмента (купленные фулфилментом для себя)
  SELLER_CONSUMABLES // Расходники селлеров (принятые от селлеров для хранения)
}

model Logistics {
  id             String       @id @default(cuid())
  fromLocation   String
  toLocation     String
  priceUnder1m3  Float
  priceOver1m3   Float
  description    String?
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organizationId String
  organization   Organization @relation(fields: [organizationId], references: [id])

  @@map("logistics")
}

model SupplyOrder {
  id                  String            @id @default(cuid())
  partnerId           String
  deliveryDate        DateTime
  status              SupplyOrderStatus @default(PENDING)
  totalAmount         Decimal           @db.Decimal(12, 2)
  totalItems          Int
  fulfillmentCenterId String?
  logisticsPartnerId  String? // Опциональная логистика - может назначить фулфилмент
  consumableType      String? // Классификация расходников: FULFILLMENT_CONSUMABLES, SELLER_CONSUMABLES
  createdAt           DateTime          @default(now())
  updatedAt           DateTime          @updatedAt
  organizationId      String
  items               SupplyOrderItem[]
  organization        Organization      @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  partner             Organization      @relation("SupplyOrderPartner", fields: [partnerId], references: [id])
  fulfillmentCenter   Organization?     @relation("SupplyOrderFulfillmentCenter", fields: [fulfillmentCenterId], references: [id])
  logisticsPartner    Organization?     @relation("SupplyOrderLogistics", fields: [logisticsPartnerId], references: [id])

  @@map("supply_orders")
}

model SupplyOrderItem {
  id            String      @id @default(cuid())
  supplyOrderId String
  productId     String
  quantity      Int
  price         Decimal     @db.Decimal(12, 2)
  totalPrice    Decimal     @db.Decimal(12, 2)
  // Поля для рецептуры продукта
  services              String[]  @default([]) // ID услуг
  fulfillmentConsumables String[] @default([]) // ID расходников фулфилмента
  sellerConsumables     String[]  @default([]) // ID расходников селлера
  marketplaceCardId     String?   // ID карточки маркетплейса
  createdAt     DateTime    @default(now())
  updatedAt     DateTime    @updatedAt
  supplyOrder   SupplyOrder @relation(fields: [supplyOrderId], references: [id], onDelete: Cascade)
  product       Product     @relation(fields: [productId], references: [id])

  @@unique([supplyOrderId, productId])
  @@map("supply_order_items")
}

model SupplySupplier {
  id             String       @id @default(cuid())
  name           String
  contactName    String
  phone          String
  market         String?
  address        String?
  place          String?
  telegram       String?
  organizationId String
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation("SupplySuppliers", fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("supply_suppliers")
}

model ExternalAd {
  id             String       @id @default(cuid())
  name           String // Название рекламы
  url            String // URL рекламы
  cost           Decimal      @db.Decimal(12, 2) // Стоимость
  date           DateTime // Дата рекламы
  nmId           String // ID товара Wildberries
  clicks         Int          @default(0) // Количество кликов
  organizationId String // ID организации
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation("ExternalAds", fields: [organizationId], references: [id], onDelete: Cascade)

  @@index([organizationId, date])
  @@map("external_ads")
}

model WBWarehouseCache {
  id             String       @id @default(cuid())
  organizationId String // ID организации
  cacheDate      DateTime // Дата кеширования (только дата, без времени)
  data           Json // Кешированные данные склада WB
  totalProducts  Int          @default(0) // Общее количество товаров
  totalStocks    Int          @default(0) // Общее количество остатков
  totalReserved  Int          @default(0) // Общее количество в резерве
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation("WBWarehouseCaches", fields: [organizationId], references: [id], onDelete: Cascade)

  @@unique([organizationId, cacheDate])
  @@index([organizationId, cacheDate])
  @@map("wb_warehouse_caches")
}

model SellerStatsCache {
  id             String    @id @default(cuid())
  organizationId String // ID организации
  cacheDate      DateTime // Дата кеширования (только дата, без времени)
  period         String // Период статистики (week, month, quarter, custom)
  dateFrom       DateTime? // Дата начала периода (для custom)
  dateTo         DateTime? // Дата окончания периода (для custom)

  // Данные товаров
  productsData        Json? // Кешированные данные товаров
  productsTotalSales  Decimal? @db.Decimal(15, 2) // Общая сумма продаж товаров
  productsTotalOrders Int? // Общее количество заказов товаров
  productsCount       Int? // Количество товаров

  // Данные рекламы
  advertisingData        Json? // Кешированные данные рекламы
  advertisingTotalCost   Decimal? @db.Decimal(15, 2) // Общие расходы на рекламу
  advertisingTotalViews  Int? // Общие показы рекламы
  advertisingTotalClicks Int? // Общие клики рекламы

  // Метаданные
  expiresAt    DateTime // Время истечения кеша (24 часа)
  createdAt    DateTime     @default(now())
  updatedAt    DateTime     @updatedAt
  organization Organization @relation("SellerStatsCaches", fields: [organizationId], references: [id], onDelete: Cascade)

  @@unique([organizationId, cacheDate, period, dateFrom, dateTo])
  @@index([organizationId, cacheDate])
  @@index([expiresAt])
  @@map("seller_stats_caches")
}
