import { Prisma } from '@prisma/client'
import bcrypt from 'bcryptjs'
import { GraphQLError, GraphQLScalarType, Kind } from 'graphql'
import jwt from 'jsonwebtoken'

import { prisma } from '@/lib/prisma'
import { notifyMany, notifyOrganization } from '@/lib/realtime'
import { DaDataService } from '@/services/dadata-service'
import { MarketplaceService } from '@/services/marketplace-service'
import { SmsService } from '@/services/sms-service'
import { WildberriesService } from '@/services/wildberries-service'

import '@/lib/seed-init' // Автоматическая инициализация БД

// Сервисы
const smsService = new SmsService()
const dadataService = new DaDataService()
const marketplaceService = new MarketplaceService()

// Функция генерации уникального реферального кода
const generateReferralCode = async (): Promise<string> => {
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
  let attempts = 0
  const maxAttempts = 10
  
  while (attempts < maxAttempts) {
    let code = ''
    for (let i = 0; i < 10; i++) {
      code += chars.charAt(Math.floor(Math.random() * chars.length))
    }
    
    // Проверяем уникальность
    const existing = await prisma.organization.findUnique({
      where: { referralCode: code },
    })
    
    if (!existing) {
      return code
    }
    
    attempts++
  }
  
  // Если не удалось сгенерировать уникальный код, используем cuid как fallback
  return `REF${Date.now()}${Math.random().toString(36).substr(2, 5).toUpperCase()}`
}

// Функция для автоматического создания записи склада при новом партнерстве
const autoCreateWarehouseEntry = async (sellerId: string, fulfillmentId: string) => {
  console.warn(`🏗️ AUTO WAREHOUSE ENTRY: Creating for seller ${sellerId} with fulfillment ${fulfillmentId}`)
  
  // Получаем данные селлера
  const sellerOrg = await prisma.organization.findUnique({
    where: { id: sellerId },
  })

  if (!sellerOrg) {
    throw new Error(`Селлер с ID ${sellerId} не найден`)
  }

  // Проверяем что не существует уже записи для этого селлера у этого фулфилмента  
  // В будущем здесь может быть проверка в отдельной таблице warehouse_entries
  // Пока используем логику проверки через контрагентов
  
  // ЛОГИКА ОПРЕДЕЛЕНИЯ НАЗВАНИЯ МАГАЗИНА (консистентно с warehouseData resolver)
  let storeName = sellerOrg.name
  
  if (sellerOrg.fullName && sellerOrg.name?.includes('ИП')) {
    // Извлекаем название из скобок, например: "ИП Антипова Д. В. (Renrel)" -> "Renrel"
    const match = sellerOrg.fullName.match(/\(([^)]+)\)/)
    if (match && match[1]) {
      storeName = match[1]
    }
  }

  // Создаем структуру данных для склада
  const warehouseEntry = {
    id: `warehouse_${sellerId}_${Date.now()}`, // Уникальный ID записи
    storeName: storeName || sellerOrg.fullName || sellerOrg.name,
    storeOwner: sellerOrg.inn || sellerOrg.fullName || sellerOrg.name,  
    storeImage: sellerOrg.logoUrl || null,
    storeQuantity: 0, // Пока нет поставок
    partnershipDate: new Date(),
    products: [], // Пустой массив продуктов
  }

  console.warn(`✅ AUTO WAREHOUSE ENTRY CREATED:`, {
    sellerId,
    storeName: warehouseEntry.storeName,
    storeOwner: warehouseEntry.storeOwner,
  })

  // В реальной системе здесь бы была запись в таблицу warehouse_entries
  // Пока возвращаем структуру данных
  return warehouseEntry
}

// Интерфейсы для типизации
interface Context {
  user?: {
    id: string
    phone: string
  }
  admin?: {
    id: string
    username: string
  }
}

interface CreateEmployeeInput {
  firstName: string
  lastName: string
  middleName?: string
  birthDate?: string
  avatar?: string
  passportPhoto?: string
  passportSeries?: string
  passportNumber?: string
  passportIssued?: string
  passportDate?: string
  address?: string
  position: string
  department?: string
  hireDate: string
  salary?: number
  phone: string
  email?: string
  telegram?: string
  whatsapp?: string
  emergencyContact?: string
  emergencyPhone?: string
}

interface UpdateEmployeeInput {
  firstName?: string
  lastName?: string
  middleName?: string
  birthDate?: string
  avatar?: string
  passportPhoto?: string
  passportSeries?: string
  passportNumber?: string
  passportIssued?: string
  passportDate?: string
  address?: string
  position?: string
  department?: string
  hireDate?: string
  salary?: number
  status?: 'ACTIVE' | 'VACATION' | 'SICK' | 'FIRED'
  phone?: string
  email?: string
  telegram?: string
  whatsapp?: string
  emergencyContact?: string
  emergencyPhone?: string
}

interface UpdateScheduleInput {
  employeeId: string
  date: string
  status: 'WORK' | 'WEEKEND' | 'VACATION' | 'SICK' | 'ABSENT'
  hoursWorked?: number
  overtimeHours?: number
  notes?: string
}

interface AuthTokenPayload {
  userId: string
  phone: string
}

// JWT утилиты
const generateToken = (payload: AuthTokenPayload): string => {
  return jwt.sign(payload, process.env.JWT_SECRET!, { expiresIn: '30d' })
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const verifyToken = (token: string): AuthTokenPayload => {
  try {
    return jwt.verify(token, process.env.JWT_SECRET!) as AuthTokenPayload
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
  } catch (error) {
    throw new GraphQLError('Недействительный токен', {
      extensions: { code: 'UNAUTHENTICATED' },
    })
  }
}

// Скалярный тип для JSON
const JSONScalar = new GraphQLScalarType({
  name: 'JSON',
  description: 'JSON custom scalar type',
  serialize(value: unknown) {
    return value // значение отправляется клиенту
  },
  parseValue(value: unknown) {
    return value // значение получено от клиента
  },
  parseLiteral(ast) {
    switch (ast.kind) {
      case Kind.STRING:
      case Kind.BOOLEAN:
        return ast.value
      case Kind.INT:
      case Kind.FLOAT:
        return parseFloat(ast.value)
      case Kind.OBJECT: {
        const value = Object.create(null)
        ast.fields.forEach((field) => {
          value[field.name.value] = parseLiteral(field.value)
        })
        return value
      }
      case Kind.LIST:
        return ast.values.map(parseLiteral)
      default:
        return null
    }
  },
})

// Скалярный тип для DateTime
const DateTimeScalar = new GraphQLScalarType({
  name: 'DateTime',
  description: 'DateTime custom scalar type',
  serialize(value: unknown) {
    if (value instanceof Date) {
      return value.toISOString() // значение отправляется клиенту как ISO строка
    }
    return value
  },
  parseValue(value: unknown) {
    if (typeof value === 'string') {
      return new Date(value) // значение получено от клиента, парсим как дату
    }
    return value
  },
  parseLiteral(ast) {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value) // AST значение как дата
    }
    return null
  },
})

function parseLiteral(ast: unknown): unknown {
  const astNode = ast as {
    kind: string
    value?: unknown
    fields?: unknown[]
    values?: unknown[]
  }

  switch (astNode.kind) {
    case Kind.STRING:
    case Kind.BOOLEAN:
      return astNode.value
    case Kind.INT:
    case Kind.FLOAT:
      return parseFloat(astNode.value as string)
    case Kind.OBJECT: {
      const value = Object.create(null)
      if (astNode.fields) {
        astNode.fields.forEach((field: unknown) => {
          const fieldNode = field as {
            name: { value: string }
            value: unknown
          }
          value[fieldNode.name.value] = parseLiteral(fieldNode.value)
        })
      }
      return value
    }
    case Kind.LIST:
      return (ast as { values: unknown[] }).values.map(parseLiteral)
    default:
      return null
  }
}

export const resolvers = {
  JSON: JSONScalar,
  DateTime: DateTimeScalar,

  Query: {
    me: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      return await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })
    },

    organization: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const organization = await prisma.organization.findUnique({
        where: { id: args.id },
        include: {
          apiKeys: true,
          users: true,
        },
      })

      if (!organization) {
        throw new GraphQLError('Организация не найдена')
      }

      // Проверяем, что пользователь имеет доступ к этой организации
      const hasAccess = organization.users.some((user) => user.id === context.user!.id)
      if (!hasAccess) {
        throw new GraphQLError('Нет доступа к этой организации', {
          extensions: { code: 'FORBIDDEN' },
        })
      }

      return organization
    },

    // Поиск организаций по типу для добавления в контрагенты
    searchOrganizations: async (_: unknown, args: { type?: string; search?: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // Получаем текущую организацию пользователя
      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Получаем уже существующих контрагентов для добавления флага
      const existingCounterparties = await prisma.counterparty.findMany({
        where: { organizationId: currentUser.organization.id },
        select: { counterpartyId: true },
      })

      const existingCounterpartyIds = existingCounterparties.map((c) => c.counterpartyId)

      // Получаем исходящие заявки для добавления флага hasOutgoingRequest
      const outgoingRequests = await prisma.counterpartyRequest.findMany({
        where: {
          senderId: currentUser.organization.id,
          status: 'PENDING',
        },
        select: { receiverId: true },
      })

      const outgoingRequestIds = outgoingRequests.map((r) => r.receiverId)

      // Получаем входящие заявки для добавления флага hasIncomingRequest
      const incomingRequests = await prisma.counterpartyRequest.findMany({
        where: {
          receiverId: currentUser.organization.id,
          status: 'PENDING',
        },
        select: { senderId: true },
      })

      const incomingRequestIds = incomingRequests.map((r) => r.senderId)

      const where: Record<string, unknown> = {
        // Больше не исключаем собственную организацию
      }

      if (args.type) {
        where.type = args.type
      }

      if (args.search) {
        where.OR = [
          { name: { contains: args.search, mode: 'insensitive' } },
          { fullName: { contains: args.search, mode: 'insensitive' } },
          { inn: { contains: args.search } },
        ]
      }

      const organizations = await prisma.organization.findMany({
        where,
        take: 50, // Ограничиваем количество результатов
        orderBy: { createdAt: 'desc' },
        include: {
          users: true,
          apiKeys: true,
        },
      })

      // Добавляем флаги isCounterparty, isCurrentUser, hasOutgoingRequest и hasIncomingRequest к каждой организации
      return organizations.map((org) => ({
        ...org,
        isCounterparty: existingCounterpartyIds.includes(org.id),
        isCurrentUser: org.id === currentUser.organization?.id,
        hasOutgoingRequest: outgoingRequestIds.includes(org.id),
        hasIncomingRequest: incomingRequestIds.includes(org.id),
      }))
    },

    // Мои контрагенты
    myCounterparties: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      const counterparties = await prisma.counterparty.findMany({
        where: { organizationId: currentUser.organization.id },
        include: {
          counterparty: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
        },
      })

      return counterparties.map((c) => c.counterparty)
    },

    // Поставщики поставок
    supplySuppliers: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      const suppliers = await prisma.supplySupplier.findMany({
        where: { organizationId: currentUser.organization.id },
        orderBy: { createdAt: 'desc' },
      })

      return suppliers
    },

    // Логистика конкретной организации
    organizationLogistics: async (_: unknown, args: { organizationId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      return await prisma.logistics.findMany({
        where: { organizationId: args.organizationId },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Входящие заявки
    incomingRequests: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      return await prisma.counterpartyRequest.findMany({
        where: {
          receiverId: currentUser.organization.id,
          status: 'PENDING',
        },
        include: {
          sender: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
          receiver: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Исходящие заявки
    outgoingRequests: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      return await prisma.counterpartyRequest.findMany({
        where: {
          senderId: currentUser.organization.id,
          status: { in: ['PENDING', 'REJECTED'] },
        },
        include: {
          sender: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
          receiver: {
            include: {
              users: true,
              apiKeys: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Сообщения с контрагентом
    messages: async (
      _: unknown,
      args: { counterpartyId: string; limit?: number; offset?: number },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      const limit = args.limit || 50
      const offset = args.offset || 0

      const messages = await prisma.message.findMany({
        where: {
          OR: [
            {
              senderOrganizationId: currentUser.organization.id,
              receiverOrganizationId: args.counterpartyId,
            },
            {
              senderOrganizationId: args.counterpartyId,
              receiverOrganizationId: currentUser.organization.id,
            },
          ],
        },
        include: {
          sender: true,
          senderOrganization: {
            include: {
              users: true,
            },
          },
          receiverOrganization: {
            include: {
              users: true,
            },
          },
        },
        orderBy: { createdAt: 'asc' },
        take: limit,
        skip: offset,
      })

      return messages
    },

    // Список чатов (последние сообщения с каждым контрагентом)
    conversations: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Получаем всех контрагентов
      const counterparties = await prisma.counterparty.findMany({
        where: { organizationId: currentUser.organization.id },
        include: {
          counterparty: {
            include: {
              users: true,
            },
          },
        },
      })

      // Для каждого контрагента получаем последнее сообщение и количество непрочитанных
      const conversations = await Promise.all(
        counterparties.map(async (cp) => {
          const counterpartyId = cp.counterparty.id

          // Последнее сообщение с этим контрагентом
          const lastMessage = await prisma.message.findFirst({
            where: {
              OR: [
                {
                  senderOrganizationId: currentUser.organization!.id,
                  receiverOrganizationId: counterpartyId,
                },
                {
                  senderOrganizationId: counterpartyId,
                  receiverOrganizationId: currentUser.organization!.id,
                },
              ],
            },
            include: {
              sender: true,
              senderOrganization: {
                include: {
                  users: true,
                },
              },
              receiverOrganization: {
                include: {
                  users: true,
                },
              },
            },
            orderBy: { createdAt: 'desc' },
          })

          // Количество непрочитанных сообщений от этого контрагента
          const unreadCount = await prisma.message.count({
            where: {
              senderOrganizationId: counterpartyId,
              receiverOrganizationId: currentUser.organization!.id,
              isRead: false,
            },
          })

          // Если есть сообщения с этим контрагентом, включаем его в список
          if (lastMessage) {
            return {
              id: `${currentUser.organization!.id}-${counterpartyId}`,
              counterparty: cp.counterparty,
              lastMessage,
              unreadCount,
              updatedAt: lastMessage.createdAt,
            }
          }

          return null
        }),
      )

      // Фильтруем null значения и сортируем по времени последнего сообщения
      return conversations
        .filter((conv) => conv !== null)
        .sort((a, b) => new Date(b!.updatedAt).getTime() - new Date(a!.updatedAt).getTime())
    },

    // Мои услуги
    myServices: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Услуги доступны только для фулфилмент центров')
      }

      return await prisma.service.findMany({
        where: { organizationId: currentUser.organization.id },
        include: { organization: true },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Расходники селлеров (материалы клиентов на складе фулфилмента)
    mySupplies: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        return [] // Только фулфилменты имеют расходники
      }

      // Получаем ВСЕ расходники из таблицы supply для фулфилмента
      const allSupplies = await prisma.supply.findMany({
        where: { organizationId: currentUser.organization.id },
        include: { organization: true },
        orderBy: { createdAt: 'desc' },
      })

      // Преобразуем старую структуру в новую согласно GraphQL схеме
      const transformedSupplies = allSupplies.map((supply) => ({
        id: supply.id,
        name: supply.name,
        description: supply.description,
        pricePerUnit: supply.price ? parseFloat(supply.price.toString()) : null, // Конвертируем Decimal в Number
        unit: supply.unit || 'шт', // Единица измерения
        imageUrl: supply.imageUrl,
        warehouseStock: supply.currentStock || 0, // Остаток на складе
        isAvailable: (supply.currentStock || 0) > 0, // Есть ли в наличии
        warehouseConsumableId: supply.id, // Связь со складом (пока используем тот же ID)
        createdAt: supply.createdAt,
        updatedAt: supply.updatedAt,
        organization: supply.organization,
      }))

      console.warn('🔥 SUPPLIES RESOLVER - NEW FORMAT:', {
        organizationId: currentUser.organization.id,
        suppliesCount: transformedSupplies.length,
        supplies: transformedSupplies.map((s) => ({
          id: s.id,
          name: s.name,
          pricePerUnit: s.pricePerUnit,
          warehouseStock: s.warehouseStock,
          isAvailable: s.isAvailable,
        })),
      })

      return transformedSupplies
    },

    // Доступные расходники для рецептур селлеров (только с ценой и в наличии)
    getAvailableSuppliesForRecipe: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Селлеры могут получать расходники от своих фулфилмент-партнеров
      if (currentUser.organization.type !== 'SELLER') {
        return [] // Только селлеры используют рецептуры
      }

      // TODO: В будущем здесь будет логика получения расходников от партнерских фулфилментов
      // Пока возвращаем пустой массив, так как эта функциональность еще разрабатывается
      console.warn('🔥 getAvailableSuppliesForRecipe called for seller:', {
        sellerId: currentUser.organization.id,
        sellerName: currentUser.organization.name,
      })

      return []
    },

    // Расходники фулфилмента из склада (новая архитектура - синхронизация со склада)
    myFulfillmentSupplies: async (_: unknown, __: unknown, context: Context) => {
      console.warn('🔥🔥🔥 FULFILLMENT SUPPLIES RESOLVER CALLED (NEW ARCHITECTURE) 🔥🔥🔥')

      if (!context.user) {
        console.warn('❌ No user in context')
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      console.warn('👤 Current user:', {
        id: currentUser?.id,
        phone: currentUser?.phone,
        organizationId: currentUser?.organizationId,
        organizationType: currentUser?.organization?.type,
        organizationName: currentUser?.organization?.name,
      })

      if (!currentUser?.organization) {
        console.warn('❌ No organization for user')
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        console.warn('❌ User organization is not FULFILLMENT:', currentUser.organization.type)
        throw new GraphQLError('Доступ только для фулфилмент центров')
      }

      // Получаем расходники фулфилмента из таблицы Supply
      const supplies = await prisma.supply.findMany({
        where: {
          organizationId: currentUser.organization.id,
          type: 'FULFILLMENT_CONSUMABLES', // Только расходники фулфилмента
        },
        include: {
          organization: true,
        },
        orderBy: { createdAt: 'desc' },
      })

      // Логирование для отладки
      console.warn('🔥🔥🔥 FULFILLMENT SUPPLIES RESOLVER CALLED (NEW ARCHITECTURE) 🔥🔥🔥')
      console.warn('📊 Расходники фулфилмента из склада:', {
        organizationId: currentUser.organization.id,
        organizationType: currentUser.organization.type,
        suppliesCount: supplies.length,
        supplies: supplies.map((s) => ({
          id: s.id,
          name: s.name,
          type: s.type,
          status: s.status,
          currentStock: s.currentStock,
          quantity: s.quantity,
        })),
      })

      // Преобразуем в формат для фронтенда
      return supplies.map((supply) => ({
        ...supply,
        price: supply.price ? parseFloat(supply.price.toString()) : 0,
        shippedQuantity: 0, // Добавляем для совместимости
      }))
    },

    // Заказы поставок расходников
    supplyOrders: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Возвращаем заказы где текущая организация является заказчиком, поставщиком, получателем или логистическим партнером
      const orders = await prisma.supplyOrder.findMany({
        where: {
          OR: [
            { organizationId: currentUser.organization.id }, // Заказы созданные организацией
            { partnerId: currentUser.organization.id }, // Заказы где организация - поставщик
            { fulfillmentCenterId: currentUser.organization.id }, // Заказы где организация - получатель (фулфилмент)
            { logisticsPartnerId: currentUser.organization.id }, // Заказы где организация - логистический партнер
          ],
        },
        include: {
          partner: {
            include: {
              users: true,
            },
          },
          organization: {
            include: {
              users: true,
            },
          },
          fulfillmentCenter: {
            include: {
              users: true,
            },
          },
          logisticsPartner: true,
          items: {
            include: {
              product: {
                include: {
                  category: true,
                  organization: true,
                },
              },
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      })

      return orders
    },

    // Счетчик поставок, требующих одобрения
    pendingSuppliesCount: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Считаем заказы поставок, требующие действий

      // Расходники фулфилмента (созданные нами для себя) - требуют действий по статусам
      const ourSupplyOrders = await prisma.supplyOrder.count({
        where: {
          organizationId: currentUser.organization.id, // Создали мы
          fulfillmentCenterId: currentUser.organization.id, // Получатель - мы
          status: { in: ['CONFIRMED', 'IN_TRANSIT'] }, // Подтверждено или в пути
        },
      })

      // Расходники селлеров (созданные другими для нас) - требуют действий фулфилмента
      const sellerSupplyOrders = await prisma.supplyOrder.count({
        where: {
          fulfillmentCenterId: currentUser.organization.id, // Получатель - мы
          organizationId: { not: currentUser.organization.id }, // Создали НЕ мы
          status: {
            in: [
              'SUPPLIER_APPROVED', // Поставщик подтвердил - нужно назначить логистику
              'IN_TRANSIT', // В пути - нужно подтвердить получение
            ],
          },
        },
      })

      // 🔔 ВХОДЯЩИЕ ЗАКАЗЫ ДЛЯ ПОСТАВЩИКОВ (WHOLESALE) - требуют подтверждения
      const incomingSupplierOrders = await prisma.supplyOrder.count({
        where: {
          partnerId: currentUser.organization.id, // Мы - поставщик
          status: 'PENDING', // Ожидает подтверждения от поставщика
        },
      })

      // 🚚 ЛОГИСТИЧЕСКИЕ ЗАЯВКИ ДЛЯ ЛОГИСТИКИ (LOGIST) - требуют действий логистики
      const logisticsOrders = await prisma.supplyOrder.count({
        where: {
          logisticsPartnerId: currentUser.organization.id, // Мы - назначенная логистика
          status: {
            in: [
              'CONFIRMED', // Подтверждено фулфилментом - нужно подтвердить логистикой
              'LOGISTICS_CONFIRMED', // Подтверждено логистикой - нужно забрать товар у поставщика
            ],
          },
        },
      })

      // Общий счетчик поставок в зависимости от типа организации
      let pendingSupplyOrders = 0
      if (currentUser.organization.type === 'FULFILLMENT') {
        pendingSupplyOrders = ourSupplyOrders + sellerSupplyOrders
      } else if (currentUser.organization.type === 'WHOLESALE') {
        pendingSupplyOrders = incomingSupplierOrders
      } else if (currentUser.organization.type === 'LOGIST') {
        pendingSupplyOrders = logisticsOrders
      } else if (currentUser.organization.type === 'SELLER') {
        pendingSupplyOrders = 0 // Селлеры не подтверждают поставки, только отслеживают
      }

      // Считаем входящие заявки на партнерство со статусом PENDING
      const pendingIncomingRequests = await prisma.counterpartyRequest.count({
        where: {
          receiverId: currentUser.organization.id,
          status: 'PENDING',
        },
      })

      return {
        supplyOrders: pendingSupplyOrders,
        ourSupplyOrders: ourSupplyOrders, // Расходники фулфилмента
        sellerSupplyOrders: sellerSupplyOrders, // Расходники селлеров
        incomingSupplierOrders: incomingSupplierOrders, // 🔔 Входящие заказы для поставщиков
        logisticsOrders: logisticsOrders, // 🚚 Логистические заявки для логистики
        incomingRequests: pendingIncomingRequests,
        total: pendingSupplyOrders + pendingIncomingRequests,
      }
    },

    // Статистика склада фулфилмента с изменениями за сутки
    fulfillmentWarehouseStats: async (_: unknown, __: unknown, context: Context) => {
      console.warn('🔥 FULFILLMENT WAREHOUSE STATS RESOLVER CALLED')
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступ разрешен только для фулфилмент-центров')
      }

      const organizationId = currentUser.organization.id

      // Получаем дату начала суток (24 часа назад)
      const oneDayAgo = new Date()
      oneDayAgo.setDate(oneDayAgo.getDate() - 1)

      console.warn(`🏢 Organization ID: ${organizationId}, Date 24h ago: ${oneDayAgo.toISOString()}`)

      // Сначала проверим ВСЕ заказы поставок
      const allSupplyOrders = await prisma.supplyOrder.findMany({
        where: { status: 'DELIVERED' },
        include: {
          items: {
            include: { product: true },
          },
          organization: { select: { id: true, name: true, type: true } },
        },
      })
      console.warn(`📦 ALL DELIVERED ORDERS: ${allSupplyOrders.length}`)
      allSupplyOrders.forEach((order) => {
        console.warn(
          `  Order ${order.id}: org=${order.organizationId} (${order.organization?.name}), fulfillment=${order.fulfillmentCenterId}, items=${order.items.length}`,
        )
      })

      // Продукты (товары от селлеров) - заказы К нам, но исключаем расходники фулфилмента
      const sellerDeliveredOrders = await prisma.supplyOrder.findMany({
        where: {
          fulfillmentCenterId: organizationId, // Доставлено к нам (фулфилменту)
          organizationId: { not: organizationId }, // ИСПРАВЛЕНО: исключаем заказы самого фулфилмента
          status: 'DELIVERED',
        },
        include: {
          items: {
            include: { product: true },
          },
        },
      })
      console.warn(`🛒 SELLER ORDERS TO FULFILLMENT: ${sellerDeliveredOrders.length}`)

      const productsCount = sellerDeliveredOrders.reduce(
        (sum, order) =>
          sum +
          order.items.reduce((itemSum, item) => itemSum + (item.product.type === 'PRODUCT' ? item.quantity : 0), 0),
        0,
      )
      // Изменения товаров за сутки (от селлеров)
      const recentSellerDeliveredOrders = await prisma.supplyOrder.findMany({
        where: {
          fulfillmentCenterId: organizationId, // К нам
          organizationId: { not: organizationId }, // От селлеров
          status: 'DELIVERED',
          updatedAt: { gte: oneDayAgo },
        },
        include: {
          items: {
            include: { product: true },
          },
        },
      })

      const productsChangeToday = recentSellerDeliveredOrders.reduce(
        (sum, order) =>
          sum +
          order.items.reduce((itemSum, item) => itemSum + (item.product.type === 'PRODUCT' ? item.quantity : 0), 0),
        0,
      )

      // Товары (готовые товары = все продукты, не расходники)
      const goodsCount = productsCount // Готовые товары = все продукты
      const goodsChangeToday = productsChangeToday // Изменения товаров = изменения продуктов

      // Брак
      const defectsCount = 0 // TODO: реальные данные о браке
      const defectsChangeToday = 0

      // Возвраты с ПВЗ
      const pvzReturnsCount = 0 // TODO: реальные данные о возвратах
      const pvzReturnsChangeToday = 0

      // Расходники фулфилмента - заказы ОТ фулфилмента К поставщикам, НО доставленные на склад фулфилмента
      // Согласно правилам: фулфилмент заказывает расходники у поставщиков для своих операционных нужд
      const fulfillmentSupplyOrders = await prisma.supplyOrder.findMany({
        where: {
          organizationId: organizationId, // Заказчик = фулфилмент
          fulfillmentCenterId: organizationId, // ИСПРАВЛЕНО: доставлено НА склад фулфилмента
          status: 'DELIVERED',
        },
        include: {
          items: {
            include: { product: true },
          },
        },
      })

      console.warn(`🏭 FULFILLMENT SUPPLY ORDERS: ${fulfillmentSupplyOrders.length}`)

      // Подсчитываем количество из таблицы Supply (актуальные остатки на складе фулфилмента)
      // ИСПРАВЛЕНО: считаем только расходники фулфилмента, исключаем расходники селлеров
      const fulfillmentSuppliesFromWarehouse = await prisma.supply.findMany({
        where: {
          organizationId: organizationId, // Склад фулфилмента
          type: 'FULFILLMENT_CONSUMABLES', // ТОЛЬКО расходники фулфилмента
        },
      })

      const fulfillmentSuppliesCount = fulfillmentSuppliesFromWarehouse.reduce(
        (sum, supply) => sum + (supply.currentStock || 0),
        0,
      )

      console.warn(
        `🔥 FULFILLMENT SUPPLIES DEBUG: organizationId=${organizationId}, ordersCount=${fulfillmentSupplyOrders.length}, warehouseCount=${fulfillmentSuppliesFromWarehouse.length}, totalStock=${fulfillmentSuppliesCount}`,
      )
      console.warn(
        '📦 FULFILLMENT SUPPLIES BREAKDOWN:',
        fulfillmentSuppliesFromWarehouse.map((supply) => ({
          name: supply.name,
          currentStock: supply.currentStock,
          supplier: supply.supplier,
        })),
      )

      // Изменения расходников фулфилмента за сутки (ПРИБЫЛО)
      // Ищем заказы фулфилмента, доставленные на его склад за последние сутки
      const fulfillmentSuppliesReceivedToday = await prisma.supplyOrder.findMany({
        where: {
          organizationId: organizationId, // Заказчик = фулфилмент
          fulfillmentCenterId: organizationId, // ИСПРАВЛЕНО: доставлено НА склад фулфилмента
          status: 'DELIVERED',
          updatedAt: { gte: oneDayAgo },
        },
        include: {
          items: {
            include: { product: true },
          },
        },
      })

      const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedToday.reduce(
        (sum, order) =>
          sum +
          order.items.reduce((itemSum, item) => itemSum + (item.product.type === 'CONSUMABLE' ? item.quantity : 0), 0),
        0,
      )

      console.warn(
        `📊 FULFILLMENT SUPPLIES RECEIVED TODAY (ПРИБЫЛО): ${fulfillmentSuppliesReceivedToday.length} orders, ${fulfillmentSuppliesChangeToday} items`,
      )

      // Расходники селлеров - получаем из таблицы Supply (актуальные остатки на складе фулфилмента)
      // ИСПРАВЛЕНО: считаем из Supply с типом SELLER_CONSUMABLES
      const sellerSuppliesFromWarehouse = await prisma.supply.findMany({
        where: {
          organizationId: organizationId, // Склад фулфилмента
          type: 'SELLER_CONSUMABLES', // ТОЛЬКО расходники селлеров
        },
      })

      const sellerSuppliesCount = sellerSuppliesFromWarehouse.reduce(
        (sum, supply) => sum + (supply.currentStock || 0),
        0,
      )

      console.warn(`💼 SELLER SUPPLIES DEBUG: totalCount=${sellerSuppliesCount} (from Supply warehouse)`)

      // Изменения расходников селлеров за сутки - считаем из Supply записей, созданных за сутки
      const sellerSuppliesReceivedToday = await prisma.supply.findMany({
        where: {
          organizationId: organizationId, // Склад фулфилмента
          type: 'SELLER_CONSUMABLES', // ТОЛЬКО расходники селлеров
          createdAt: { gte: oneDayAgo }, // Созданы за последние сутки
        },
      })

      const sellerSuppliesChangeToday = sellerSuppliesReceivedToday.reduce(
        (sum, supply) => sum + (supply.currentStock || 0),
        0,
      )

      console.warn(
        `📊 SELLER SUPPLIES RECEIVED TODAY: ${sellerSuppliesReceivedToday.length} supplies, ${sellerSuppliesChangeToday} items`,
      )

      // Вычисляем процентные изменения
      const calculatePercentChange = (current: number, change: number): number => {
        if (current === 0) return change > 0 ? 100 : 0
        return (change / current) * 100
      }

      const result = {
        products: {
          current: productsCount,
          change: productsChangeToday,
          percentChange: calculatePercentChange(productsCount, productsChangeToday),
        },
        goods: {
          current: goodsCount,
          change: goodsChangeToday,
          percentChange: calculatePercentChange(goodsCount, goodsChangeToday),
        },
        defects: {
          current: defectsCount,
          change: defectsChangeToday,
          percentChange: calculatePercentChange(defectsCount, defectsChangeToday),
        },
        pvzReturns: {
          current: pvzReturnsCount,
          change: pvzReturnsChangeToday,
          percentChange: calculatePercentChange(pvzReturnsCount, pvzReturnsChangeToday),
        },
        fulfillmentSupplies: {
          current: fulfillmentSuppliesCount,
          change: fulfillmentSuppliesChangeToday,
          percentChange: calculatePercentChange(fulfillmentSuppliesCount, fulfillmentSuppliesChangeToday),
        },
        sellerSupplies: {
          current: sellerSuppliesCount,
          change: sellerSuppliesChangeToday,
          percentChange: calculatePercentChange(sellerSuppliesCount, sellerSuppliesChangeToday),
        },
      }

      console.warn('🏁 FINAL WAREHOUSE STATS RESULT:', JSON.stringify(result, null, 2))

      return result
    },

    // Движения товаров (прибыло/убыло) за период
    supplyMovements: async (_: unknown, args: { period?: string }, context: Context) => {
      console.warn('🔄 SUPPLY MOVEMENTS RESOLVER CALLED with period:', args.period)
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступ разрешен только фулфилмент центрам')
      }

      const organizationId = currentUser.organization.id
      console.warn(`🏢 SUPPLY MOVEMENTS for organization: ${organizationId}`)

      // Определяем период (по умолчанию 24 часа)
      const periodHours = args.period === '7d' ? 168 : args.period === '30d' ? 720 : 24
      const periodAgo = new Date(Date.now() - periodHours * 60 * 60 * 1000)

      // ПРИБЫЛО: Поставки НА фулфилмент (статус DELIVERED за период)
      const arrivedOrders = await prisma.supplyOrder.findMany({
        where: {
          fulfillmentCenterId: organizationId,
          status: 'DELIVERED',
          updatedAt: { gte: periodAgo },
        },
        include: {
          items: {
            include: { product: true },
          },
        },
      })

      console.warn(`📦 ARRIVED ORDERS: ${arrivedOrders.length}`)

      // Подсчитываем прибыло по типам
      const arrived = {
        products: 0,
        goods: 0, 
        defects: 0,
        pvzReturns: 0,
        fulfillmentSupplies: 0,
        sellerSupplies: 0,
      }

      arrivedOrders.forEach((order) => {
        order.items.forEach((item) => {
          const quantity = item.quantity
          const productType = item.product?.type

          if (productType === 'PRODUCT') arrived.products += quantity
          else if (productType === 'GOODS') arrived.goods += quantity
          else if (productType === 'DEFECT') arrived.defects += quantity
          else if (productType === 'PVZ_RETURN') arrived.pvzReturns += quantity
          else if (productType === 'CONSUMABLE') {
            // Определяем тип расходника по заказчику
            if (order.organizationId === organizationId) {
              arrived.fulfillmentSupplies += quantity
            } else {
              arrived.sellerSupplies += quantity
            }
          }
        })
      })

      // УБЫЛО: Поставки НА маркетплейсы (по статусам отгрузки)
      // TODO: Пока возвращаем заглушки, нужно реализовать логику отгрузок
      const departed = {
        products: 0, // TODO: считать из отгрузок на WB/Ozon
        goods: 0,
        defects: 0,
        pvzReturns: 0,
        fulfillmentSupplies: 0,
        sellerSupplies: 0,
      }

      console.warn('📊 SUPPLY MOVEMENTS RESULT:', { arrived, departed })

      return {
        arrived,
        departed,
      }
    },

    // Логистика организации
    myLogistics: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      return await prisma.logistics.findMany({
        where: { organizationId: currentUser.organization.id },
        include: { organization: true },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Логистические партнеры (организации-логисты)
    logisticsPartners: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // Получаем все организации типа LOGIST
      return await prisma.organization.findMany({
        where: {
          type: 'LOGIST',
          // Убираем фильтр по статусу пока не определим правильные значения
        },
        orderBy: { createdAt: 'desc' }, // Сортируем по дате создания вместо name
      })
    },

    // Мои поставки Wildberries
    myWildberriesSupplies: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      return await prisma.wildberriesSupply.findMany({
        where: { organizationId: currentUser.organization.id },
        include: {
          organization: true,
          cards: true,
        },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Расходники селлеров на складе фулфилмента (новый resolver)
    sellerSuppliesOnWarehouse: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Только фулфилмент может получать расходники селлеров на своем складе
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступ разрешен только для фулфилмент-центров')
      }

      // ИСПРАВЛЕНО: Усиленная фильтрация расходников селлеров
      const sellerSupplies = await prisma.supply.findMany({
        where: {
          organizationId: currentUser.organization.id, // На складе этого фулфилмента
          type: 'SELLER_CONSUMABLES' as const, // Только расходники селлеров
          sellerOwnerId: { not: null }, // ОБЯЗАТЕЛЬНО должен быть владелец-селлер
        },
        include: {
          organization: true, // Фулфилмент-центр (хранитель)
          sellerOwner: true, // Селлер-владелец расходников
        },
        orderBy: { createdAt: 'desc' },
      })

      // Логирование для отладки
      console.warn('🔍 ИСПРАВЛЕНО: Запрос расходников селлеров на складе фулфилмента:', {
        fulfillmentId: currentUser.organization.id,
        fulfillmentName: currentUser.organization.name,
        totalSupplies: sellerSupplies.length,
        sellerSupplies: sellerSupplies.map((supply) => ({
          id: supply.id,
          name: supply.name,
          type: supply.type,
          sellerOwnerId: supply.sellerOwnerId,
          sellerOwnerName: supply.sellerOwner?.name || supply.sellerOwner?.fullName,
          currentStock: supply.currentStock,
        })),
      })

      // ДВОЙНАЯ ПРОВЕРКА: Фильтруем на уровне кода для гарантии
      const filteredSupplies = sellerSupplies.filter((supply) => {
        const isValid =
          supply.type === 'SELLER_CONSUMABLES' && supply.sellerOwnerId != null && supply.sellerOwner != null

        if (!isValid) {
          console.warn('⚠️ ОТФИЛЬТРОВАН некорректный расходник:', {
            id: supply.id,
            name: supply.name,
            type: supply.type,
            sellerOwnerId: supply.sellerOwnerId,
            hasSellerOwner: !!supply.sellerOwner,
          })
        }

        return isValid
      })

      console.warn('✅ ФИНАЛЬНЫЙ РЕЗУЛЬТАТ после фильтрации:', {
        originalCount: sellerSupplies.length,
        filteredCount: filteredSupplies.length,
        removedCount: sellerSupplies.length - filteredSupplies.length,
      })

      return filteredSupplies
    },

    // Мои товары и расходники (для поставщиков)
    myProducts: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это поставщик
      if (currentUser.organization.type !== 'WHOLESALE') {
        throw new GraphQLError('Товары доступны только для поставщиков')
      }

      const products = await prisma.product.findMany({
        where: {
          organizationId: currentUser.organization.id,
          // Показываем и товары, и расходники поставщика
        },
        include: {
          category: true,
          organization: true,
        },
        orderBy: { createdAt: 'desc' },
      })

      console.warn('🔥 MY_PRODUCTS RESOLVER DEBUG:', {
        userId: currentUser.id,
        organizationId: currentUser.organization.id,
        organizationType: currentUser.organization.type,
        organizationName: currentUser.organization.name,
        totalProducts: products.length,
        productTypes: products.map((p) => ({
          id: p.id,
          name: p.name,
          article: p.article,
          type: p.type,
          isActive: p.isActive,
          createdAt: p.createdAt,
        })),
      })

      return products
    },

    // Товары на складе фулфилмента (из доставленных заказов поставок)
    warehouseProducts: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: true,
        },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Товары склада доступны только для фулфилмент центров')
      }

      // Получаем все доставленные заказы поставок, где этот фулфилмент центр является получателем
      const deliveredSupplyOrders = await prisma.supplyOrder.findMany({
        where: {
          fulfillmentCenterId: currentUser.organization.id,
          status: 'DELIVERED', // Только доставленные заказы
        },
        include: {
          items: {
            include: {
              product: {
                include: {
                  category: true,
                  organization: true, // Включаем информацию о поставщике
                },
              },
            },
          },
          organization: true, // Селлер, который сделал заказ
          partner: true, // Поставщик товаров
        },
      })

      // Собираем все товары из доставленных заказов
      const allProducts: unknown[] = []

      console.warn('🔍 Резолвер warehouseProducts (доставленные заказы):', {
        currentUserId: currentUser.id,
        organizationId: currentUser.organization.id,
        organizationType: currentUser.organization.type,
        deliveredOrdersCount: deliveredSupplyOrders.length,
        orders: deliveredSupplyOrders.map((order) => ({
          id: order.id,
          sellerName: order.organization.name || order.organization.fullName,
          supplierName: order.partner.name || order.partner.fullName,
          status: order.status,
          itemsCount: order.items.length,
          deliveryDate: order.deliveryDate,
        })),
      })

      for (const order of deliveredSupplyOrders) {
        console.warn(
          `📦 Заказ от селлера ${order.organization.name} у поставщика ${order.partner.name}:`,
          order.items.map((item) => ({
            productId: item.product.id,
            productName: item.product.name,
            article: item.product.article,
            orderedQuantity: item.quantity,
            price: item.price,
          })),
        )

        for (const item of order.items) {
          // Добавляем только товары типа PRODUCT, исключаем расходники
          if (item.product.type === 'PRODUCT') {
            allProducts.push({
              ...item.product,
              // Дополнительная информация о заказе
              orderedQuantity: item.quantity,
              orderedPrice: item.price,
              orderId: order.id,
              orderDate: order.deliveryDate,
              seller: order.organization, // Селлер, который заказал
              supplier: order.partner, // Поставщик товара
              // Для совместимости с существующим интерфейсом
              organization: order.organization, // Указываем селлера как владельца
            })
          } else {
            console.warn('🚫 Исключен расходник из основного склада фулфилмента:', {
              name: item.product.name,
              type: item.product.type,
              orderId: order.id,
            })
          }
        }
      }

      console.warn('✅ Итого товаров на складе фулфилмента (из доставленных заказов):', allProducts.length)
      return allProducts
    },

    // Данные склада с партнерами (3-уровневая иерархия)
    warehouseData: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Данные склада доступны только для фулфилмент центров')
      }

      console.warn('🏪 WAREHOUSE DATA: Получение данных склада для фулфилмента', currentUser.organization.id)

      // Получаем всех партнеров-селлеров
      const counterparties = await prisma.counterparty.findMany({
        where: { 
          organizationId: currentUser.organization.id 
        },
        include: {
          counterparty: true,
        },
      })

      const sellerPartners = counterparties.filter(c => c.counterparty.type === 'SELLER')

      console.warn('🤝 PARTNERS FOUND:', {
        totalCounterparties: counterparties.length,
        sellerPartners: sellerPartners.length,
        sellers: sellerPartners.map(p => ({
          id: p.counterparty.id,
          name: p.counterparty.name,
          fullName: p.counterparty.fullName,
          inn: p.counterparty.inn,
        })),
      })

      // Создаем данные склада для каждого партнера-селлера
      const stores = sellerPartners.map(partner => {
        const org = partner.counterparty
        
        // ЛОГИКА ОПРЕДЕЛЕНИЯ НАЗВАНИЯ МАГАЗИНА:
        // 1. Если есть name и оно не содержит "ИП" - используем name
        // 2. Если есть fullName и name содержит "ИП" - извлекаем из fullName название в скобках
        // 3. Fallback к name или fullName
        let storeName = org.name
        
        if (org.fullName && org.name?.includes('ИП')) {
          // Извлекаем название из скобок, например: "ИП Антипова Д. В. (Renrel)" -> "Renrel"
          const match = org.fullName.match(/\(([^)]+)\)/)
          if (match && match[1]) {
            storeName = match[1]
          }
        }
        
        return {
          id: `store_${org.id}`,
          storeName: storeName || org.fullName || org.name,
          storeOwner: org.inn || org.fullName || org.name,
          storeImage: org.logoUrl || null,
          storeQuantity: 0, // Пока без поставок
          partnershipDate: partner.createdAt || new Date(),
          products: [], // Пустой массив продуктов
        }
      })

      // Сортировка: новые партнеры (quantity = 0) в самом верху
      stores.sort((a, b) => {
        if (a.storeQuantity === 0 && b.storeQuantity > 0) return -1
        if (a.storeQuantity > 0 && b.storeQuantity === 0) return 1
        return b.storeQuantity - a.storeQuantity
      })

      console.warn('📦 WAREHOUSE STORES CREATED:', {
        storesCount: stores.length,
        storesPreview: stores.slice(0, 3).map(s => ({
          storeName: s.storeName,
          storeOwner: s.storeOwner,
          storeQuantity: s.storeQuantity,
        })),
      })

      return {
        stores,
      }
    },

    // Все товары и расходники поставщиков для маркета
    allProducts: async (_: unknown, args: { search?: string; category?: string }, context: Context) => {
      console.warn('🛍️ ALL_PRODUCTS RESOLVER - ВЫЗВАН:', {
        userId: context.user?.id,
        search: args.search,
        category: args.category,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const where: Record<string, unknown> = {
        isActive: true, // Показываем только активные товары
        // Показываем и товары, и расходники поставщиков
        organization: {
          type: 'WHOLESALE', // Только товары поставщиков
        },
      }

      if (args.search) {
        where.OR = [
          { name: { contains: args.search, mode: 'insensitive' } },
          { article: { contains: args.search, mode: 'insensitive' } },
          { description: { contains: args.search, mode: 'insensitive' } },
          { brand: { contains: args.search, mode: 'insensitive' } },
        ]
      }

      if (args.category) {
        where.categoryId = args.category
      }

      const products = await prisma.product.findMany({
        where,
        include: {
          category: true,
          organization: {
            include: {
              users: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
        take: 100, // Ограничиваем количество результатов
      })

      console.warn('🔥 ALL_PRODUCTS RESOLVER DEBUG:', {
        searchArgs: args,
        whereCondition: where,
        totalProducts: products.length,
        productTypes: products.map((p) => ({
          id: p.id,
          name: p.name,
          type: p.type,
          org: p.organization.name,
        })),
      })

      return products
    },

    // Товары конкретной организации (для формы создания поставки)
    organizationProducts: async (
      _: unknown,
      args: { organizationId: string; search?: string; category?: string; type?: string },
      context: Context,
    ) => {
      console.warn('🏢 ORGANIZATION_PRODUCTS RESOLVER - ВЫЗВАН:', {
        userId: context.user?.id,
        organizationId: args.organizationId,
        search: args.search,
        category: args.category,
        type: args.type,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const where: Record<string, unknown> = {
        isActive: true, // Показываем только активные товары
        organizationId: args.organizationId, // Фильтруем по конкретной организации
        type: args.type || 'ТОВАР', // Показываем только товары по умолчанию, НЕ расходники согласно development-checklist.md
      }

      if (args.search) {
        where.OR = [
          { name: { contains: args.search, mode: 'insensitive' } },
          { article: { contains: args.search, mode: 'insensitive' } },
          { description: { contains: args.search, mode: 'insensitive' } },
          { brand: { contains: args.search, mode: 'insensitive' } },
        ]
      }

      if (args.category) {
        where.categoryId = args.category
      }

      const products = await prisma.product.findMany({
        where,
        include: {
          category: true,
          organization: {
            include: {
              users: true,
            },
          },
        },
        orderBy: { createdAt: 'desc' },
        take: 100, // Ограничиваем количество результатов
      })

      console.warn('🔥 ORGANIZATION_PRODUCTS RESOLVER DEBUG:', {
        organizationId: args.organizationId,
        searchArgs: args,
        whereCondition: where,
        totalProducts: products.length,
        productTypes: products.map((p) => ({
          id: p.id,
          name: p.name,
          type: p.type,
          isActive: p.isActive,
        })),
      })

      return products
    },

    // Все категории
    categories: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user && !context.admin) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      return await prisma.category.findMany({
        orderBy: { name: 'asc' },
      })
    },

    // Публичные услуги контрагента (для фулфилмента)
    counterpartyServices: async (_: unknown, args: { organizationId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что запрашиваемая организация является контрагентом
      const counterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.organizationId,
        },
      })

      if (!counterparty) {
        throw new GraphQLError('Организация не является вашим контрагентом')
      }

      // Проверяем, что это фулфилмент центр
      const targetOrganization = await prisma.organization.findUnique({
        where: { id: args.organizationId },
      })

      if (!targetOrganization || targetOrganization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Услуги доступны только у фулфилмент центров')
      }

      return await prisma.service.findMany({
        where: { organizationId: args.organizationId },
        include: { organization: true },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Публичные расходники контрагента (для поставщиков)
    counterpartySupplies: async (_: unknown, args: { organizationId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что запрашиваемая организация является контрагентом
      const counterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.organizationId,
        },
      })

      if (!counterparty) {
        throw new GraphQLError('Организация не является вашим контрагентом')
      }

      // Проверяем, что это фулфилмент центр (у них есть расходники)
      const targetOrganization = await prisma.organization.findUnique({
        where: { id: args.organizationId },
      })

      if (!targetOrganization || targetOrganization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Расходники доступны только у фулфилмент центров')
      }

      return await prisma.supply.findMany({
        where: { organizationId: args.organizationId },
        include: { organization: true },
        orderBy: { createdAt: 'desc' },
      })
    },

    // Корзина пользователя
    myCart: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Найти или создать корзину для организации
      let cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
        include: {
          items: {
            include: {
              product: {
                include: {
                  category: true,
                  organization: {
                    include: {
                      users: true,
                    },
                  },
                },
              },
            },
          },
          organization: true,
        },
      })

      if (!cart) {
        cart = await prisma.cart.create({
          data: {
            organizationId: currentUser.organization.id,
          },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
            },
            organization: true,
          },
        })
      }

      return cart
    },

    // Избранные товары пользователя
    myFavorites: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Получаем избранные товары
      const favorites = await prisma.favorites.findMany({
        where: { organizationId: currentUser.organization.id },
        include: {
          product: {
            include: {
              category: true,
              organization: {
                include: {
                  users: true,
                },
              },
            },
          },
        },
        orderBy: { createdAt: 'desc' },
      })

      return favorites.map((favorite) => favorite.product)
    },

    // Сотрудники организации
    myEmployees: async (_: unknown, __: unknown, context: Context) => {
      console.warn('🔍 myEmployees resolver called')

      if (!context.user) {
        console.warn('❌ No user in context for myEmployees')
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      console.warn('✅ User authenticated for myEmployees:', context.user.id)

      try {
        const currentUser = await prisma.user.findUnique({
          where: { id: context.user.id },
          include: { organization: true },
        })

        if (!currentUser?.organization) {
          console.warn('❌ User has no organization')
          throw new GraphQLError('У пользователя нет организации')
        }

        console.warn('📊 User organization type:', currentUser.organization.type)

        if (currentUser.organization.type !== 'FULFILLMENT') {
          console.warn('❌ Not a fulfillment center')
          throw new GraphQLError('Доступно только для фулфилмент центров')
        }

        const employees = await prisma.employee.findMany({
          where: { organizationId: currentUser.organization.id },
          include: {
            organization: true,
          },
          orderBy: { createdAt: 'desc' },
        })

        console.warn('👥 Found employees:', employees.length)
        return employees
      } catch (error) {
        console.error('❌ Error in myEmployees resolver:', error)
        throw error
      }
    },

    // Получение сотрудника по ID
    employee: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступно только для фулфилмент центров')
      }

      const employee = await prisma.employee.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
        include: {
          organization: true,
        },
      })

      return employee
    },

    // Получить табель сотрудника за месяц
    employeeSchedule: async (
      _: unknown,
      args: { employeeId: string; year: number; month: number },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступно только для фулфилмент центров')
      }

      // Проверяем что сотрудник принадлежит организации
      const employee = await prisma.employee.findFirst({
        where: {
          id: args.employeeId,
          organizationId: currentUser.organization.id,
        },
      })

      if (!employee) {
        throw new GraphQLError('Сотрудник не найден')
      }

      // Получаем записи табеля за указанный месяц
      const startDate = new Date(args.year, args.month, 1)
      const endDate = new Date(args.year, args.month + 1, 0)

      const scheduleRecords = await prisma.employeeSchedule.findMany({
        where: {
          employeeId: args.employeeId,
          date: {
            gte: startDate,
            lte: endDate,
          },
        },
        orderBy: {
          date: 'asc',
        },
      })

      return scheduleRecords
    },

    // Получить партнерскую ссылку текущего пользователя
    myPartnerLink: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user?.organizationId) {
        throw new GraphQLError('Требуется авторизация и организация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const organization = await prisma.organization.findUnique({
        where: { id: context.user.organizationId },
        select: { referralCode: true },
      })

      if (!organization?.referralCode) {
        throw new GraphQLError('Реферальный код не найден')
      }

      return `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/register?partner=${organization.referralCode}`
    },

    // Получить реферальную ссылку
    myReferralLink: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user?.organizationId) {
        return 'http://localhost:3000/register?ref=PLEASE_LOGIN'
      }

      const organization = await prisma.organization.findUnique({
        where: { id: context.user.organizationId },
        select: { referralCode: true },
      })

      if (!organization?.referralCode) {
        throw new GraphQLError('Реферальный код не найден')
      }

      return `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/register?ref=${organization.referralCode}`
    },

    // Статистика по рефералам
    myReferralStats: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user?.organizationId) {
        throw new GraphQLError('Требуется авторизация и организация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      try {
        // Получаем текущие реферальные очки организации
        const organization = await prisma.organization.findUnique({
          where: { id: context.user.organizationId },
          select: { referralPoints: true },
        })

        // Получаем все транзакции где эта организация - реферер
        const transactions = await prisma.referralTransaction.findMany({
          where: { referrerId: context.user.organizationId },
          include: {
            referral: {
              select: { 
                type: true,
                createdAt: true,
              },
            },
          },
        })

        // Подсчитываем статистику
        const totalSpheres = organization?.referralPoints || 0
        const totalPartners = transactions.length

        // Партнеры за последний месяц
        const lastMonth = new Date()
        lastMonth.setMonth(lastMonth.getMonth() - 1)
        const monthlyPartners = transactions.filter(tx => tx.createdAt > lastMonth).length
        const monthlySpheres = transactions
          .filter(tx => tx.createdAt > lastMonth)
          .reduce((sum, tx) => sum + tx.points, 0)

        // Группировка по типам организаций
        const typeStats: Record<string, { count: number; spheres: number }> = {}
        transactions.forEach(tx => {
          const type = tx.referral.type
          if (!typeStats[type]) {
            typeStats[type] = { count: 0, spheres: 0 }
          }
          typeStats[type].count++
          typeStats[type].spheres += tx.points
        })

        // Группировка по источникам
        const sourceStats: Record<string, { count: number; spheres: number }> = {}
        transactions.forEach(tx => {
          const source = tx.type === 'REGISTRATION' ? 'REFERRAL_LINK' : 'AUTO_BUSINESS'
          if (!sourceStats[source]) {
            sourceStats[source] = { count: 0, spheres: 0 }
          }
          sourceStats[source].count++
          sourceStats[source].spheres += tx.points
        })

        return {
          totalPartners,
          totalSpheres,
          monthlyPartners,
          monthlySpheres,
          referralsByType: [
            { type: 'SELLER', count: typeStats['SELLER']?.count || 0, spheres: typeStats['SELLER']?.spheres || 0 },
            { type: 'WHOLESALE', count: typeStats['WHOLESALE']?.count || 0, spheres: typeStats['WHOLESALE']?.spheres || 0 },
            { type: 'FULFILLMENT', count: typeStats['FULFILLMENT']?.count || 0, spheres: typeStats['FULFILLMENT']?.spheres || 0 },
            { type: 'LOGIST', count: typeStats['LOGIST']?.count || 0, spheres: typeStats['LOGIST']?.spheres || 0 },
          ],
          referralsBySource: [
            { source: 'REFERRAL_LINK', count: sourceStats['REFERRAL_LINK']?.count || 0, spheres: sourceStats['REFERRAL_LINK']?.spheres || 0 },
            { source: 'AUTO_BUSINESS', count: sourceStats['AUTO_BUSINESS']?.count || 0, spheres: sourceStats['AUTO_BUSINESS']?.spheres || 0 },
          ],
        }
      } catch (error) {
        console.error('Ошибка получения статистики рефералов:', error)
        // Возвращаем заглушку в случае ошибки
        return {
          totalPartners: 0,
          totalSpheres: 0,
          monthlyPartners: 0,
          monthlySpheres: 0,
          referralsByType: [
            { type: 'SELLER', count: 0, spheres: 0 },
            { type: 'WHOLESALE', count: 0, spheres: 0 },
            { type: 'FULFILLMENT', count: 0, spheres: 0 },
            { type: 'LOGIST', count: 0, spheres: 0 },
          ],
          referralsBySource: [
            { source: 'REFERRAL_LINK', count: 0, spheres: 0 },
            { source: 'AUTO_BUSINESS', count: 0, spheres: 0 },
          ],
        }
      }
    },

    // Получить список рефералов
    myReferrals: async (_: unknown, args: any, context: Context) => {
      if (!context.user?.organizationId) {
        throw new GraphQLError('Требуется авторизация и организация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      try {
        const { limit = 50, offset = 0 } = args || {}

        // Получаем рефералов (организации, которых пригласил текущий пользователь)
        const referralTransactions = await prisma.referralTransaction.findMany({
          where: { referrerId: context.user.organizationId },
          include: {
            referral: {
              select: {
                id: true,
                name: true,
                fullName: true,
                inn: true,
                type: true,
                createdAt: true,
              },
            },
          },
          orderBy: { createdAt: 'desc' },
          skip: offset,
          take: limit,
        })

        // Преобразуем в формат для UI
        const referrals = referralTransactions.map(tx => ({
          id: tx.id,
          organization: tx.referral,
          source: tx.type === 'REGISTRATION' ? 'REFERRAL_LINK' : 'AUTO_BUSINESS',
          spheresEarned: tx.points,
          registeredAt: tx.createdAt.toISOString(),
          status: 'ACTIVE',
        }))

        // Получаем общее количество для пагинации
        const totalCount = await prisma.referralTransaction.count({
          where: { referrerId: context.user.organizationId },
        })

        const totalPages = Math.ceil(totalCount / limit)

        return {
          referrals,
          totalCount,
          totalPages,
        }
      } catch (error) {
        console.error('Ошибка получения рефералов:', error)
        return {
          referrals: [],
          totalCount: 0,
          totalPages: 0,
        }
      }
    },

    // Получить историю транзакций рефералов
    myReferralTransactions: async (_: unknown, args: { limit?: number; offset?: number }, context: Context) => {
      if (!context.user?.organizationId) {
        throw new GraphQLError('Требуется авторизация и организация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      try {
        // Временная заглушка для отладки
        const result = {
          transactions: [],
          totalCount: 0,
        }
        return result
      } catch (error) {
        console.error('Ошибка получения транзакций рефералов:', error)
        return {
          transactions: [],
          totalCount: 0,
        }
      }
    },
  },

  Mutation: {
    sendSmsCode: async (_: unknown, args: { phone: string }) => {
      const result = await smsService.sendSmsCode(args.phone)
      return {
        success: result.success,
        message: result.message || 'SMS код отправлен',
      }
    },

    verifySmsCode: async (_: unknown, args: { phone: string; code: string }) => {
      const verificationResult = await smsService.verifySmsCode(args.phone, args.code)

      if (!verificationResult.success) {
        return {
          success: false,
          message: verificationResult.message || 'Неверный код',
        }
      }

      // Найти или создать пользователя
      const formattedPhone = args.phone.replace(/\D/g, '')
      let user = await prisma.user.findUnique({
        where: { phone: formattedPhone },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user) {
        user = await prisma.user.create({
          data: {
            phone: formattedPhone,
          },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })
      }

      const token = generateToken({
        userId: user.id,
        phone: user.phone,
      })

      console.warn('verifySmsCode - Generated token:', token ? `${token.substring(0, 20)}...` : 'No token')
      console.warn('verifySmsCode - Full token:', token)
      console.warn('verifySmsCode - User object:', {
        id: user.id,
        phone: user.phone,
      })

      const result = {
        success: true,
        message: 'Авторизация успешна',
        token,
        user,
      }

      console.warn('verifySmsCode - Returning result:', {
        success: result.success,
        hasToken: !!result.token,
        hasUser: !!result.user,
        message: result.message,
        tokenPreview: result.token ? `${result.token.substring(0, 20)}...` : 'No token in result',
      })

      return result
    },

    verifyInn: async (_: unknown, args: { inn: string }) => {
      // Валидируем ИНН
      if (!dadataService.validateInn(args.inn)) {
        return {
          success: false,
          message: 'Неверный формат ИНН',
        }
      }

      // Получаем данные организации из DaData
      const organizationData = await dadataService.getOrganizationByInn(args.inn)
      if (!organizationData) {
        return {
          success: false,
          message: 'Организация с указанным ИНН не найдена',
        }
      }

      return {
        success: true,
        message: 'ИНН найден',
        organization: {
          name: organizationData.name,
          fullName: organizationData.fullName,
          address: organizationData.address,
          isActive: organizationData.isActive,
        },
      }
    },

    registerFulfillmentOrganization: async (
      _: unknown,
      args: {
        input: {
          phone: string
          inn: string
          type: 'FULFILLMENT' | 'LOGIST' | 'WHOLESALE'
          referralCode?: string
          partnerCode?: string
        }
      },
      context: Context,
    ) => {
      
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const { inn, type, referralCode, partnerCode } = args.input

      // Валидируем ИНН
      if (!dadataService.validateInn(inn)) {
        return {
          success: false,
          message: 'Неверный формат ИНН',
        }
      }

      // Получаем данные организации из DaData
      const organizationData = await dadataService.getOrganizationByInn(inn)
      if (!organizationData) {
        return {
          success: false,
          message: 'Организация с указанным ИНН не найдена',
        }
      }

      try {
        // Проверяем, что организация еще не зарегистрирована
        const existingOrg = await prisma.organization.findUnique({
          where: { inn: organizationData.inn },
        })

        if (existingOrg) {
          return {
            success: false,
            message: 'Организация с таким ИНН уже зарегистрирована',
          }
        }

        // Генерируем уникальный реферальный код
        const generatedReferralCode = await generateReferralCode()

        // Создаем организацию со всеми данными из DaData
        const organization = await prisma.organization.create({
          data: {
            inn: organizationData.inn,
            kpp: organizationData.kpp,
            name: organizationData.name,
            fullName: organizationData.fullName,
            address: organizationData.address,
            addressFull: organizationData.addressFull,
            ogrn: organizationData.ogrn,
            ogrnDate: organizationData.ogrnDate,

            // Статус организации
            status: organizationData.status,
            actualityDate: organizationData.actualityDate,
            registrationDate: organizationData.registrationDate,
            liquidationDate: organizationData.liquidationDate,

            // Руководитель
            managementName: organizationData.managementName,
            managementPost: organizationData.managementPost,

            // ОПФ
            opfCode: organizationData.opfCode,
            opfFull: organizationData.opfFull,
            opfShort: organizationData.opfShort,

            // Коды статистики
            okato: organizationData.okato,
            oktmo: organizationData.oktmo,
            okpo: organizationData.okpo,
            okved: organizationData.okved,

            // Контакты
            phones: organizationData.phones ? JSON.parse(JSON.stringify(organizationData.phones)) : null,
            emails: organizationData.emails ? JSON.parse(JSON.stringify(organizationData.emails)) : null,

            // Финансовые данные
            employeeCount: organizationData.employeeCount,
            revenue: organizationData.revenue,
            taxSystem: organizationData.taxSystem,

            type: type,
            dadataData: JSON.parse(JSON.stringify(organizationData.rawData)),
            
            // Реферальная система - генерируем код автоматически
            referralCode: generatedReferralCode,
          },
        })

        // Привязываем пользователя к организации
        const updatedUser = await prisma.user.update({
          where: { id: context.user.id },
          data: { organizationId: organization.id },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })

        // Обрабатываем реферальные коды
        if (referralCode) {
          try {
            // Находим реферера по реферальному коду
            const referrer = await prisma.organization.findUnique({
              where: { referralCode: referralCode },
            })
            
            if (referrer) {
              // Создаем реферальную транзакцию (100 сфер)
              await prisma.referralTransaction.create({
                data: {
                  referrerId: referrer.id,
                  referralId: organization.id,
                  points: 100,
                  type: 'REGISTRATION',
                  description: `Регистрация ${type.toLowerCase()} организации по реферальной ссылке`,
                },
              })

              // Увеличиваем счетчик сфер у реферера
              await prisma.organization.update({
                where: { id: referrer.id },
                data: { referralPoints: { increment: 100 } },
              })

              // Устанавливаем связь реферала и источник регистрации
              await prisma.organization.update({
                where: { id: organization.id },
                data: { referredById: referrer.id },
              })
            }
          } catch {
            // Error processing referral code, but continue registration
          }
        }

        if (partnerCode) {
          try {
                        
            // Находим партнера по партнерскому коду
            const partner = await prisma.organization.findUnique({
              where: { referralCode: partnerCode },
            })
            
                        
            if (partner) {
              // Создаем реферальную транзакцию (100 сфер)
              await prisma.referralTransaction.create({
                data: {
                  referrerId: partner.id,
                  referralId: organization.id,
                  points: 100,
                  type: 'AUTO_PARTNERSHIP',
                  description: `Регистрация ${type.toLowerCase()} организации по партнерской ссылке`,
                },
              })

              // Увеличиваем счетчик сфер у партнера
              await prisma.organization.update({
                where: { id: partner.id },
                data: { referralPoints: { increment: 100 } },
              })

              // Устанавливаем связь реферала и источник регистрации
              await prisma.organization.update({
                where: { id: organization.id },
                data: { referredById: partner.id },
              })

              // Создаем партнерскую связь (автоматическое добавление в контрагенты)
              await prisma.counterparty.create({
                data: {
                  organizationId: partner.id,
                  counterpartyId: organization.id,
                  type: 'AUTO',
                  triggeredBy: 'PARTNER_LINK',
                },
              })

              await prisma.counterparty.create({
                data: {
                  organizationId: organization.id,
                  counterpartyId: partner.id,
                  type: 'AUTO',
                  triggeredBy: 'PARTNER_LINK',
                },
              })
              
                          }
          } catch {
            // Error processing partner code, but continue registration
          }
        }

        return {
          success: true,
          message: 'Организация успешно зарегистрирована',
          user: updatedUser,
        }
      } catch {
        // Error registering fulfillment organization
        return {
          success: false,
          message: 'Ошибка при регистрации организации',
        }
      }
    },

    registerSellerOrganization: async (
      _: unknown,
      args: {
        input: {
          phone: string
          wbApiKey?: string
          ozonApiKey?: string
          ozonClientId?: string
          referralCode?: string
          partnerCode?: string
        }
      },
      context: Context,
    ) => {
      
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const { wbApiKey, ozonApiKey, ozonClientId, referralCode, partnerCode } = args.input

      if (!wbApiKey && !ozonApiKey) {
        return {
          success: false,
          message: 'Необходимо указать хотя бы один API ключ маркетплейса',
        }
      }

      try {
        // Валидируем API ключи
        const validationResults = []

        if (wbApiKey) {
          const wbResult = await marketplaceService.validateWildberriesApiKey(wbApiKey)
          if (!wbResult.isValid) {
            return {
              success: false,
              message: `Wildberries: ${wbResult.message}`,
            }
          }
          validationResults.push({
            marketplace: 'WILDBERRIES',
            apiKey: wbApiKey,
            data: wbResult.data,
          })
        }

        if (ozonApiKey && ozonClientId) {
          const ozonResult = await marketplaceService.validateOzonApiKey(ozonApiKey, ozonClientId)
          if (!ozonResult.isValid) {
            return {
              success: false,
              message: `Ozon: ${ozonResult.message}`,
            }
          }
          validationResults.push({
            marketplace: 'OZON',
            apiKey: ozonApiKey,
            data: ozonResult.data,
          })
        }

        // Создаем организацию селлера - используем tradeMark как основное имя
        const tradeMark = validationResults[0]?.data?.tradeMark
        const sellerName = validationResults[0]?.data?.sellerName
        const shopName = tradeMark || sellerName || 'Магазин'
        
        // Генерируем уникальный реферальный код
        const generatedReferralCode = await generateReferralCode()

        const organization = await prisma.organization.create({
          data: {
            inn: (validationResults[0]?.data?.inn as string) || `SELLER_${Date.now()}`,
            name: shopName, // Используем tradeMark как основное название
            fullName: sellerName ? `${sellerName} (${shopName})` : `Интернет-магазин "${shopName}"`,
            type: 'SELLER',
            
            // Реферальная система - генерируем код автоматически
            referralCode: generatedReferralCode,
          },
        })

        // Добавляем API ключи
        for (const validation of validationResults) {
          await prisma.apiKey.create({
            data: {
              marketplace: validation.marketplace as 'WILDBERRIES' | 'OZON',
              apiKey: validation.apiKey,
              organizationId: organization.id,
              validationData: JSON.parse(JSON.stringify(validation.data)),
            },
          })
        }

        // Привязываем пользователя к организации
        const updatedUser = await prisma.user.update({
          where: { id: context.user.id },
          data: { organizationId: organization.id },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })

        // Обрабатываем реферальные коды
        if (referralCode) {
          try {
            // Находим реферера по реферальному коду
            const referrer = await prisma.organization.findUnique({
              where: { referralCode: referralCode },
            })
            
            if (referrer) {
              // Создаем реферальную транзакцию (100 сфер)
              await prisma.referralTransaction.create({
                data: {
                  referrerId: referrer.id,
                  referralId: organization.id,
                  points: 100,
                  type: 'REGISTRATION',
                  description: 'Регистрация селлер организации по реферальной ссылке',
                },
              })

              // Увеличиваем счетчик сфер у реферера
              await prisma.organization.update({
                where: { id: referrer.id },
                data: { referralPoints: { increment: 100 } },
              })

              // Устанавливаем связь реферала и источник регистрации
              await prisma.organization.update({
                where: { id: organization.id },
                data: { referredById: referrer.id },
              })
            }
          } catch {
            // Error processing referral code, but continue registration
          }
        }

        if (partnerCode) {
          try {
                        
            // Находим партнера по партнерскому коду
            const partner = await prisma.organization.findUnique({
              where: { referralCode: partnerCode },
            })
            
                        
            if (partner) {
              // Создаем реферальную транзакцию (100 сфер)
              await prisma.referralTransaction.create({
                data: {
                  referrerId: partner.id,
                  referralId: organization.id,
                  points: 100,
                  type: 'AUTO_PARTNERSHIP',
                  description: 'Регистрация селлер организации по партнерской ссылке',
                },
              })

              // Увеличиваем счетчик сфер у партнера
              await prisma.organization.update({
                where: { id: partner.id },
                data: { referralPoints: { increment: 100 } },
              })

              // Устанавливаем связь реферала и источник регистрации
              await prisma.organization.update({
                where: { id: organization.id },
                data: { referredById: partner.id },
              })

              // Создаем партнерскую связь (автоматическое добавление в контрагенты)
              await prisma.counterparty.create({
                data: {
                  organizationId: partner.id,
                  counterpartyId: organization.id,
                  type: 'AUTO',
                  triggeredBy: 'PARTNER_LINK',
                },
              })

              await prisma.counterparty.create({
                data: {
                  organizationId: organization.id,
                  counterpartyId: partner.id,
                  type: 'AUTO',
                  triggeredBy: 'PARTNER_LINK',
                },
              })
              
                          }
          } catch {
            // Error processing partner code, but continue registration
          }
        }

        return {
          success: true,
          message: 'Селлер организация успешно зарегистрирована',
          user: updatedUser,
        }
      } catch {
        // Error registering seller organization
        return {
          success: false,
          message: 'Ошибка при регистрации организации',
        }
      }
    },

    addMarketplaceApiKey: async (
      _: unknown,
      args: {
        input: {
          marketplace: 'WILDBERRIES' | 'OZON'
          apiKey: string
          clientId?: string
          validateOnly?: boolean
        }
      },
      context: Context,
    ) => {
      // Разрешаем валидацию без авторизации
      if (!args.input.validateOnly && !context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const { marketplace, apiKey, clientId, validateOnly } = args.input

      console.warn(`🔍 Validating ${marketplace} API key:`, {
        keyLength: apiKey.length,
        keyPreview: apiKey.substring(0, 20) + '...',
        validateOnly,
      })

      // Валидируем API ключ
      const validationResult = await marketplaceService.validateApiKey(marketplace, apiKey, clientId)

      console.warn(`✅ Validation result for ${marketplace}:`, validationResult)

      if (!validationResult.isValid) {
        console.warn(`❌ Validation failed for ${marketplace}:`, validationResult.message)
        return {
          success: false,
          message: validationResult.message,
        }
      }

      // Если это только валидация, возвращаем результат без сохранения
      if (validateOnly) {
        return {
          success: true,
          message: 'API ключ действителен',
          apiKey: {
            id: 'validate-only',
            marketplace,
            apiKey: '***', // Скрываем реальный ключ при валидации
            isActive: true,
            validationData: validationResult,
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          },
        }
      }

      // Для сохранения API ключа нужна авторизация
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация для сохранения API ключа', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        return {
          success: false,
          message: 'Пользователь не привязан к организации',
        }
      }

      try {
        // Проверяем, что такого ключа еще нет
        const existingKey = await prisma.apiKey.findUnique({
          where: {
            organizationId_marketplace: {
              organizationId: user.organization.id,
              marketplace,
            },
          },
        })

        if (existingKey) {
          // Обновляем существующий ключ
          const updatedKey = await prisma.apiKey.update({
            where: { id: existingKey.id },
            data: {
              apiKey,
              validationData: JSON.parse(JSON.stringify(validationResult.data)),
              isActive: true,
            },
          })

          return {
            success: true,
            message: 'API ключ успешно обновлен',
            apiKey: updatedKey,
          }
        } else {
          // Создаем новый ключ
          const newKey = await prisma.apiKey.create({
            data: {
              marketplace,
              apiKey,
              organizationId: user.organization.id,
              validationData: JSON.parse(JSON.stringify(validationResult.data)),
            },
          })

          return {
            success: true,
            message: 'API ключ успешно добавлен',
            apiKey: newKey,
          }
        }
      } catch (error) {
        console.error('Error adding marketplace API key:', error)
        return {
          success: false,
          message: 'Ошибка при добавлении API ключа',
        }
      }
    },

    removeMarketplaceApiKey: async (_: unknown, args: { marketplace: 'WILDBERRIES' | 'OZON' }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Пользователь не привязан к организации')
      }

      try {
        await prisma.apiKey.delete({
          where: {
            organizationId_marketplace: {
              organizationId: user.organization.id,
              marketplace: args.marketplace,
            },
          },
        })

        return true
      } catch (error) {
        console.error('Error removing marketplace API key:', error)
        return false
      }
    },

    updateUserProfile: async (
      _: unknown,
      args: {
        input: {
          avatar?: string
          orgPhone?: string
          managerName?: string
          telegram?: string
          whatsapp?: string
          email?: string
          bankName?: string
          bik?: string
          accountNumber?: string
          corrAccount?: string
          market?: string
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user?.organization) {
        throw new GraphQLError('Пользователь не привязан к организации')
      }

      try {
        const { input } = args

        // Обновляем данные пользователя (аватар, имя управляющего)
        const userUpdateData: { avatar?: string; managerName?: string } = {}
        if (input.avatar) {
          userUpdateData.avatar = input.avatar
        }
        if (input.managerName) {
          userUpdateData.managerName = input.managerName
        }

        if (Object.keys(userUpdateData).length > 0) {
          await prisma.user.update({
            where: { id: context.user.id },
            data: userUpdateData,
          })
        }

        // Подготавливаем данные для обновления организации
        const updateData: {
          phones?: object
          emails?: object
          managementName?: string
          managementPost?: string
          market?: string
        } = {}

        // Название организации больше не обновляется через профиль
        // Для селлеров устанавливается при регистрации, для остальных - при смене ИНН

        // Обновляем контактные данные в JSON поле phones
        if (input.orgPhone) {
          updateData.phones = [{ value: input.orgPhone, type: 'main' }]
        }

        // Обновляем email в JSON поле emails
        if (input.email) {
          updateData.emails = [{ value: input.email, type: 'main' }]
        }

        // Обновляем рынок для поставщиков
        if (input.market !== undefined) {
          updateData.market = input.market === 'none' ? null : input.market
        }

        // Сохраняем дополнительные контакты в custom полях
        // Пока добавим их как дополнительные JSON поля
        const customContacts: {
          managerName?: string
          telegram?: string
          whatsapp?: string
          bankDetails?: {
            bankName?: string
            bik?: string
            accountNumber?: string
            corrAccount?: string
          }
        } = {}

        // managerName теперь сохраняется в поле пользователя, а не в JSON

        if (input.telegram) {
          customContacts.telegram = input.telegram
        }

        if (input.whatsapp) {
          customContacts.whatsapp = input.whatsapp
        }

        if (input.bankName || input.bik || input.accountNumber || input.corrAccount) {
          customContacts.bankDetails = {
            bankName: input.bankName,
            bik: input.bik,
            accountNumber: input.accountNumber,
            corrAccount: input.corrAccount,
          }
        }

        // Если есть дополнительные контакты, сохраним их в поле managementPost временно
        // В идеале нужно добавить отдельную таблицу для контактов
        if (Object.keys(customContacts).length > 0) {
          updateData.managementPost = JSON.stringify(customContacts)
        }

        // Обновляем организацию
        await prisma.organization.update({
          where: { id: user.organization.id },
          data: updateData,
          include: {
            apiKeys: true,
          },
        })

        // Получаем обновленного пользователя
        const updatedUser = await prisma.user.findUnique({
          where: { id: context.user.id },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })

        return {
          success: true,
          message: 'Профиль успешно обновлен',
          user: updatedUser,
        }
      } catch (error) {
        console.error('Error updating user profile:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении профиля',
        }
      }
    },

    updateOrganizationByInn: async (_: unknown, args: { inn: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user?.organization) {
        throw new GraphQLError('Пользователь не привязан к организации')
      }

      try {
        // Валидируем ИНН
        if (!dadataService.validateInn(args.inn)) {
          return {
            success: false,
            message: 'Неверный формат ИНН',
          }
        }

        // Получаем данные организации из DaData
        const organizationData = await dadataService.getOrganizationByInn(args.inn)
        if (!organizationData) {
          return {
            success: false,
            message: 'Организация с указанным ИНН не найдена в федеральном реестре',
          }
        }

        // Проверяем, есть ли уже организация с таким ИНН в базе (кроме текущей)
        const existingOrganization = await prisma.organization.findUnique({
          where: { inn: organizationData.inn },
        })

        if (existingOrganization && existingOrganization.id !== user.organization.id) {
          return {
            success: false,
            message: `Организация с ИНН ${organizationData.inn} уже существует в системе`,
          }
        }

        // Подготавливаем данные для обновления
        const updateData: Prisma.OrganizationUpdateInput = {
          kpp: organizationData.kpp,
          // Для селлеров не обновляем название организации (это название магазина)
          ...(user.organization.type !== 'SELLER' && {
            name: organizationData.name,
          }),
          fullName: organizationData.fullName,
          address: organizationData.address,
          addressFull: organizationData.addressFull,
          ogrn: organizationData.ogrn,
          ogrnDate: organizationData.ogrnDate ? organizationData.ogrnDate.toISOString() : null,
          registrationDate: organizationData.registrationDate ? organizationData.registrationDate.toISOString() : null,
          liquidationDate: organizationData.liquidationDate ? organizationData.liquidationDate.toISOString() : null,
          managementName: organizationData.managementName, // Всегда перезаписываем данными из DaData (может быть null)
          managementPost: user.organization.managementPost, // Сохраняем кастомные данные пользователя
          opfCode: organizationData.opfCode,
          opfFull: organizationData.opfFull,
          opfShort: organizationData.opfShort,
          okato: organizationData.okato,
          oktmo: organizationData.oktmo,
          okpo: organizationData.okpo,
          okved: organizationData.okved,
          status: organizationData.status,
        }

        // Добавляем ИНН только если он отличается от текущего
        if (user.organization.inn !== organizationData.inn) {
          updateData.inn = organizationData.inn
        }

        // Обновляем организацию
        await prisma.organization.update({
          where: { id: user.organization.id },
          data: updateData,
          include: {
            apiKeys: true,
          },
        })

        // Получаем обновленного пользователя
        const updatedUser = await prisma.user.findUnique({
          where: { id: context.user.id },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })

        return {
          success: true,
          message: 'Данные организации успешно обновлены',
          user: updatedUser,
        }
      } catch (error) {
        console.error('Error updating organization by INN:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении данных организации',
        }
      }
    },

    logout: () => {
      // В stateless JWT системе logout происходит на клиенте
      // Можно добавить blacklist токенов, если нужно
      return true
    },

    // Отправить заявку на добавление в контрагенты
    sendCounterpartyRequest: async (
      _: unknown,
      args: { organizationId: string; message?: string },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.id === args.organizationId) {
        throw new GraphQLError('Нельзя отправить заявку самому себе')
      }

      // Проверяем, что организация-получатель существует
      const receiverOrganization = await prisma.organization.findUnique({
        where: { id: args.organizationId },
      })

      if (!receiverOrganization) {
        throw new GraphQLError('Организация не найдена')
      }

      try {
        // Создаем или обновляем заявку
        const request = await prisma.counterpartyRequest.upsert({
          where: {
            senderId_receiverId: {
              senderId: currentUser.organization.id,
              receiverId: args.organizationId,
            },
          },
          update: {
            status: 'PENDING',
            message: args.message,
            updatedAt: new Date(),
          },
          create: {
            senderId: currentUser.organization.id,
            receiverId: args.organizationId,
            message: args.message,
            status: 'PENDING',
          },
          include: {
            sender: true,
            receiver: true,
          },
        })

        // Уведомляем получателя о новой заявке
        try {
          notifyOrganization(args.organizationId, {
            type: 'counterparty:request:new',
            payload: {
              requestId: request.id,
              senderId: request.senderId,
              receiverId: request.receiverId,
            },
          })
        } catch {}

        return {
          success: true,
          message: 'Заявка отправлена',
          request,
        }
      } catch (error) {
        console.error('Error sending counterparty request:', error)
        return {
          success: false,
          message: 'Ошибка при отправке заявки',
        }
      }
    },

    // Ответить на заявку контрагента
    respondToCounterpartyRequest: async (
      _: unknown,
      args: { requestId: string; accept: boolean },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Найти заявку и проверить права
        const request = await prisma.counterpartyRequest.findUnique({
          where: { id: args.requestId },
          include: {
            sender: true,
            receiver: true,
          },
        })

        if (!request) {
          throw new GraphQLError('Заявка не найдена')
        }

        if (request.receiverId !== currentUser.organization.id) {
          throw new GraphQLError('Нет прав на обработку этой заявки')
        }

        if (request.status !== 'PENDING') {
          throw new GraphQLError('Заявка уже обработана')
        }

        const newStatus = args.accept ? 'ACCEPTED' : 'REJECTED'

        // Обновляем статус заявки
        const updatedRequest = await prisma.counterpartyRequest.update({
          where: { id: args.requestId },
          data: { status: newStatus },
          include: {
            sender: true,
            receiver: true,
          },
        })

        // Если заявка принята, создаем связи контрагентов в обе стороны
        if (args.accept) {
          await prisma.$transaction([
            // Добавляем отправителя в контрагенты получателя
            prisma.counterparty.create({
              data: {
                organizationId: request.receiverId,
                counterpartyId: request.senderId,
              },
            }),
            // Добавляем получателя в контрагенты отправителя
            prisma.counterparty.create({
              data: {
                organizationId: request.senderId,
                counterpartyId: request.receiverId,
              },
            }),
          ])
          
          // АВТОМАТИЧЕСКОЕ СОЗДАНИЕ ЗАПИСЕЙ В ТАБЛИЦЕ СКЛАДА ФУЛФИЛМЕНТА
          // Проверяем, есть ли фулфилмент среди партнеров
          if (request.receiver.type === 'FULFILLMENT' && request.sender.type === 'SELLER') {
            // Селлер становится партнером фулфилмента - создаем запись склада
            try {
              await autoCreateWarehouseEntry(request.senderId, request.receiverId)
              console.warn(`✅ AUTO WAREHOUSE ENTRY: Created for seller ${request.senderId} with fulfillment ${request.receiverId}`)
            } catch (error) {
              console.error(`❌ AUTO WAREHOUSE ENTRY ERROR:`, error)
              // Не прерываем основной процесс, если не удалось создать запись склада
            }
          } else if (request.sender.type === 'FULFILLMENT' && request.receiver.type === 'SELLER') {
            // Фулфилмент принимает заявку от селлера - создаем запись склада
            try {
              await autoCreateWarehouseEntry(request.receiverId, request.senderId)
              console.warn(`✅ AUTO WAREHOUSE ENTRY: Created for seller ${request.receiverId} with fulfillment ${request.senderId}`)
            } catch (error) {
              console.error(`❌ AUTO WAREHOUSE ENTRY ERROR:`, error)
            }
          }
        }

        // Оповещаем обе стороны об обновлении заявки и возможном изменении списка контрагентов
        try {
          notifyMany([request.senderId, request.receiverId], {
            type: 'counterparty:request:updated',
            payload: { requestId: updatedRequest.id, status: updatedRequest.status },
          })
        } catch {}

        return {
          success: true,
          message: args.accept ? 'Заявка принята' : 'Заявка отклонена',
          request: updatedRequest,
        }
      } catch (error) {
        console.error('Error responding to counterparty request:', error)
        return {
          success: false,
          message: 'Ошибка при обработке заявки',
        }
      }
    },

    // Отменить заявку
    cancelCounterpartyRequest: async (_: unknown, args: { requestId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        const request = await prisma.counterpartyRequest.findUnique({
          where: { id: args.requestId },
        })

        if (!request) {
          throw new GraphQLError('Заявка не найдена')
        }

        if (request.senderId !== currentUser.organization.id) {
          throw new GraphQLError('Можно отменить только свои заявки')
        }

        if (request.status !== 'PENDING') {
          throw new GraphQLError('Можно отменить только ожидающие заявки')
        }

        await prisma.counterpartyRequest.update({
          where: { id: args.requestId },
          data: { status: 'CANCELLED' },
        })

        return true
      } catch (error) {
        console.error('Error cancelling counterparty request:', error)
        return false
      }
    },

    // Удалить контрагента
    removeCounterparty: async (_: unknown, args: { organizationId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Удаляем связь в обе стороны
        await prisma.$transaction([
          prisma.counterparty.deleteMany({
            where: {
              organizationId: currentUser.organization.id,
              counterpartyId: args.organizationId,
            },
          }),
          prisma.counterparty.deleteMany({
            where: {
              organizationId: args.organizationId,
              counterpartyId: currentUser.organization.id,
            },
          }),
        ])

        return true
      } catch (error) {
        console.error('Error removing counterparty:', error)
        return false
      }
    },

    // Автоматическое создание записи в таблице склада
    autoCreateWarehouseEntry: async (_: unknown, args: { partnerId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что текущая организация - фулфилмент
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Только фулфилмент может создавать записи склада')
      }

      try {
        // Получаем данные партнера-селлера
        const partnerOrg = await prisma.organization.findUnique({
          where: { id: args.partnerId },
        })

        if (!partnerOrg) {
          throw new GraphQLError('Партнер не найден')
        }

        if (partnerOrg.type !== 'SELLER') {
          throw new GraphQLError('Автозаписи создаются только для партнеров-селлеров')
        }

        // Создаем запись склада
        const warehouseEntry = await autoCreateWarehouseEntry(args.partnerId, currentUser.organization.id)

        return {
          success: true,
          message: 'Запись склада создана успешно',
          warehouseEntry,
        }
      } catch (error) {
        console.error('Error creating auto warehouse entry:', error)
        return {
          success: false,
          message: error instanceof Error ? error.message : 'Ошибка создания записи склада',
        }
      }
    },

    // Отправить сообщение
    sendMessage: async (
      _: unknown,
      args: {
        receiverOrganizationId: string
        content?: string
        type?: 'TEXT' | 'VOICE'
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что получатель является контрагентом
      const isCounterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.receiverOrganizationId,
        },
      })

      if (!isCounterparty) {
        throw new GraphQLError('Можно отправлять сообщения только контрагентам')
      }

      // Получаем организацию получателя
      const receiverOrganization = await prisma.organization.findUnique({
        where: { id: args.receiverOrganizationId },
      })

      if (!receiverOrganization) {
        throw new GraphQLError('Организация получателя не найдена')
      }

      try {
        // Создаем сообщение
        const message = await prisma.message.create({
          data: {
            content: args.content?.trim() || null,
            type: args.type || 'TEXT',
            senderId: context.user.id,
            senderOrganizationId: currentUser.organization.id,
            receiverOrganizationId: args.receiverOrganizationId,
          },
          include: {
            sender: true,
            senderOrganization: {
              include: {
                users: true,
              },
            },
            receiverOrganization: {
              include: {
                users: true,
              },
            },
          },
        })

        // Реалтайм нотификация для обеих организаций (отправитель и получатель)
        try {
          notifyMany([currentUser.organization.id, args.receiverOrganizationId], {
            type: 'message:new',
            payload: {
              messageId: message.id,
              senderOrgId: message.senderOrganizationId,
              receiverOrgId: message.receiverOrganizationId,
              type: message.type,
            },
          })
        } catch {}

        return {
          success: true,
          message: 'Сообщение отправлено',
          messageData: message,
        }
      } catch (error) {
        console.error('Error sending message:', error)
        return {
          success: false,
          message: 'Ошибка при отправке сообщения',
        }
      }
    },

    // Отправить голосовое сообщение
    sendVoiceMessage: async (
      _: unknown,
      args: {
        receiverOrganizationId: string
        voiceUrl: string
        voiceDuration: number
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что получатель является контрагентом
      const isCounterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.receiverOrganizationId,
        },
      })

      if (!isCounterparty) {
        throw new GraphQLError('Можно отправлять сообщения только контрагентам')
      }

      // Получаем организацию получателя
      const receiverOrganization = await prisma.organization.findUnique({
        where: { id: args.receiverOrganizationId },
      })

      if (!receiverOrganization) {
        throw new GraphQLError('Организация получателя не найдена')
      }

      try {
        // Создаем голосовое сообщение
        const message = await prisma.message.create({
          data: {
            content: null,
            type: 'VOICE',
            voiceUrl: args.voiceUrl,
            voiceDuration: args.voiceDuration,
            senderId: context.user.id,
            senderOrganizationId: currentUser.organization.id,
            receiverOrganizationId: args.receiverOrganizationId,
          },
          include: {
            sender: true,
            senderOrganization: {
              include: {
                users: true,
              },
            },
            receiverOrganization: {
              include: {
                users: true,
              },
            },
          },
        })

        try {
          notifyMany([currentUser.organization.id, args.receiverOrganizationId], {
            type: 'message:new',
            payload: {
              messageId: message.id,
              senderOrgId: message.senderOrganizationId,
              receiverOrgId: message.receiverOrganizationId,
              type: message.type,
            },
          })
        } catch {}

        return {
          success: true,
          message: 'Голосовое сообщение отправлено',
          messageData: message,
        }
      } catch (error) {
        console.error('Error sending voice message:', error)
        return {
          success: false,
          message: 'Ошибка при отправке голосового сообщения',
        }
      }
    },

    // Отправить изображение
    sendImageMessage: async (
      _: unknown,
      args: {
        receiverOrganizationId: string
        fileUrl: string
        fileName: string
        fileSize: number
        fileType: string
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что получатель является контрагентом
      const isCounterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.receiverOrganizationId,
        },
      })

      if (!isCounterparty) {
        throw new GraphQLError('Можно отправлять сообщения только контрагентам')
      }

      try {
        const message = await prisma.message.create({
          data: {
            content: null,
            type: 'IMAGE',
            fileUrl: args.fileUrl,
            fileName: args.fileName,
            fileSize: args.fileSize,
            fileType: args.fileType,
            senderId: context.user.id,
            senderOrganizationId: currentUser.organization.id,
            receiverOrganizationId: args.receiverOrganizationId,
          },
          include: {
            sender: true,
            senderOrganization: {
              include: {
                users: true,
              },
            },
            receiverOrganization: {
              include: {
                users: true,
              },
            },
          },
        })

        try {
          notifyMany([currentUser.organization.id, args.receiverOrganizationId], {
            type: 'message:new',
            payload: {
              messageId: message.id,
              senderOrgId: message.senderOrganizationId,
              receiverOrgId: message.receiverOrganizationId,
              type: message.type,
            },
          })
        } catch {}

        return {
          success: true,
          message: 'Изображение отправлено',
          messageData: message,
        }
      } catch (error) {
        console.error('Error sending image:', error)
        return {
          success: false,
          message: 'Ошибка при отправке изображения',
        }
      }
    },

    // Отправить файл
    sendFileMessage: async (
      _: unknown,
      args: {
        receiverOrganizationId: string
        fileUrl: string
        fileName: string
        fileSize: number
        fileType: string
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что получатель является контрагентом
      const isCounterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.receiverOrganizationId,
        },
      })

      if (!isCounterparty) {
        throw new GraphQLError('Можно отправлять сообщения только контрагентам')
      }

      try {
        const message = await prisma.message.create({
          data: {
            content: null,
            type: 'FILE',
            fileUrl: args.fileUrl,
            fileName: args.fileName,
            fileSize: args.fileSize,
            fileType: args.fileType,
            senderId: context.user.id,
            senderOrganizationId: currentUser.organization.id,
            receiverOrganizationId: args.receiverOrganizationId,
          },
          include: {
            sender: true,
            senderOrganization: {
              include: {
                users: true,
              },
            },
            receiverOrganization: {
              include: {
                users: true,
              },
            },
          },
        })

        try {
          notifyMany([currentUser.organization.id, args.receiverOrganizationId], {
            type: 'message:new',
            payload: {
              messageId: message.id,
              senderOrgId: message.senderOrganizationId,
              receiverOrgId: message.receiverOrganizationId,
              type: message.type,
            },
          })
        } catch {}

        return {
          success: true,
          message: 'Файл отправлен',
          messageData: message,
        }
      } catch (error) {
        console.error('Error sending file:', error)
        return {
          success: false,
          message: 'Ошибка при отправке файла',
        }
      }
    },

    // Отметить сообщения как прочитанные
    markMessagesAsRead: async (_: unknown, args: { conversationId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // conversationId имеет формат "currentOrgId-counterpartyId"
      const [, counterpartyId] = args.conversationId.split('-')

      if (!counterpartyId) {
        throw new GraphQLError('Неверный ID беседы')
      }

      // Помечаем все непрочитанные сообщения от контрагента как прочитанные
      await prisma.message.updateMany({
        where: {
          senderOrganizationId: counterpartyId,
          receiverOrganizationId: currentUser.organization.id,
          isRead: false,
        },
        data: {
          isRead: true,
        },
      })

      return true
    },

    // Создать услугу
    createService: async (
      _: unknown,
      args: {
        input: {
          name: string
          description?: string
          price: number
          imageUrl?: string
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Услуги доступны только для фулфилмент центров')
      }

      try {
        const service = await prisma.service.create({
          data: {
            name: args.input.name,
            description: args.input.description,
            price: args.input.price,
            imageUrl: args.input.imageUrl,
            organizationId: currentUser.organization.id,
          },
          include: { organization: true },
        })

        return {
          success: true,
          message: 'Услуга успешно создана',
          service,
        }
      } catch (error) {
        console.error('Error creating service:', error)
        return {
          success: false,
          message: 'Ошибка при создании услуги',
        }
      }
    },

    // Обновить услугу
    updateService: async (
      _: unknown,
      args: {
        id: string
        input: {
          name: string
          description?: string
          price: number
          imageUrl?: string
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что услуга принадлежит текущей организации
      const existingService = await prisma.service.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingService) {
        throw new GraphQLError('Услуга не найдена или нет доступа')
      }

      try {
        const service = await prisma.service.update({
          where: { id: args.id },
          data: {
            name: args.input.name,
            description: args.input.description,
            price: args.input.price,
            imageUrl: args.input.imageUrl,
          },
          include: { organization: true },
        })

        return {
          success: true,
          message: 'Услуга успешно обновлена',
          service,
        }
      } catch (error) {
        console.error('Error updating service:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении услуги',
        }
      }
    },

    // Удалить услугу
    deleteService: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что услуга принадлежит текущей организации
      const existingService = await prisma.service.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingService) {
        throw new GraphQLError('Услуга не найдена или нет доступа')
      }

      try {
        await prisma.service.delete({
          where: { id: args.id },
        })

        return true
      } catch (error) {
        console.error('Error deleting service:', error)
        return false
      }
    },

    // Обновить цену расходника (новая архитектура - только цену можно редактировать)
    updateSupplyPrice: async (
      _: unknown,
      args: {
        id: string
        input: {
          pricePerUnit?: number | null
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Обновление цен расходников доступно только для фулфилмент центров')
      }

      try {
        // Находим и обновляем расходник
        const existingSupply = await prisma.supply.findFirst({
          where: {
            id: args.id,
            organizationId: currentUser.organization.id,
          },
        })

        if (!existingSupply) {
          throw new GraphQLError('Расходник не найден')
        }

        const updatedSupply = await prisma.supply.update({
          where: { id: args.id },
          data: {
            pricePerUnit: args.input.pricePerUnit, // Обновляем цену продажи, НЕ цену закупки
            updatedAt: new Date(),
          },
          include: { organization: true },
        })

        // Преобразуем в новый формат для GraphQL
        const transformedSupply = {
          id: updatedSupply.id,
          name: updatedSupply.name,
          description: updatedSupply.description,
          pricePerUnit: updatedSupply.price ? parseFloat(updatedSupply.price.toString()) : null, // Конвертируем Decimal в Number
          unit: updatedSupply.unit || 'шт',
          imageUrl: updatedSupply.imageUrl,
          warehouseStock: updatedSupply.currentStock || 0,
          isAvailable: (updatedSupply.currentStock || 0) > 0,
          warehouseConsumableId: updatedSupply.id,
          createdAt: updatedSupply.createdAt,
          updatedAt: updatedSupply.updatedAt,
          organization: updatedSupply.organization,
        }

        console.warn('🔥 SUPPLY PRICE UPDATED:', {
          id: transformedSupply.id,
          name: transformedSupply.name,
          oldPrice: existingSupply.price,
          newPrice: transformedSupply.pricePerUnit,
        })

        return {
          success: true,
          message: 'Цена расходника успешно обновлена',
          supply: transformedSupply,
        }
      } catch (error) {
        console.error('Error updating supply price:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении цены расходника',
        }
      }
    },

    // Использовать расходники фулфилмента
    useFulfillmentSupplies: async (
      _: unknown,
      args: {
        input: {
          supplyId: string
          quantityUsed: number
          description?: string
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент центр
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Использование расходников доступно только для фулфилмент центров')
      }

      // Находим расходник
      const existingSupply = await prisma.supply.findFirst({
        where: {
          id: args.input.supplyId,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingSupply) {
        throw new GraphQLError('Расходник не найден или нет доступа')
      }

      // Проверяем, что достаточно расходников
      if (existingSupply.currentStock < args.input.quantityUsed) {
        throw new GraphQLError(
          `Недостаточно расходников. Доступно: ${existingSupply.currentStock}, требуется: ${args.input.quantityUsed}`,
        )
      }

      try {
        // Обновляем количество расходников
        const updatedSupply = await prisma.supply.update({
          where: { id: args.input.supplyId },
          data: {
            currentStock: existingSupply.currentStock - args.input.quantityUsed,
            updatedAt: new Date(),
          },
          include: { organization: true },
        })

        console.warn('🔧 Использованы расходники фулфилмента:', {
          supplyName: updatedSupply.name,
          quantityUsed: args.input.quantityUsed,
          remainingStock: updatedSupply.currentStock,
          description: args.input.description,
        })

        // Реалтайм: уведомляем о смене складских остатков
        try {
          notifyOrganization(currentUser.organization.id, {
            type: 'warehouse:changed',
            payload: { supplyId: updatedSupply.id, change: -args.input.quantityUsed },
          })
        } catch {}

        return {
          success: true,
          message: `Использовано ${args.input.quantityUsed} ${updatedSupply.unit} расходника "${updatedSupply.name}"`,
          supply: updatedSupply,
        }
      } catch (error) {
        console.error('Error using fulfillment supplies:', error)
        return {
          success: false,
          message: 'Ошибка при использовании расходников',
        }
      }
    },

    // Создать заказ поставки расходников
    // Два сценария:
    // 1. Селлер → Поставщик → Фулфилмент (селлер заказывает для фулфилмент-центра)
    // 2. Фулфилмент → Поставщик → Фулфилмент (фулфилмент заказывает для себя)
    //
    // Процесс: Заказчик → Поставщик → [Логистика] → Фулфилмент
    // 1. Заказчик (селлер или фулфилмент) создает заказ у поставщика расходников
    // 2. Поставщик получает заказ и готовит товары
    // 3. Логистика транспортирует товары на склад фулфилмента
    // 4. Фулфилмент принимает товары на склад
    // 5. Расходники создаются в системе фулфилмент-центра
    createSupplyOrder: async (
      _: unknown,
      args: {
        input: {
          partnerId: string
          deliveryDate: string
          fulfillmentCenterId?: string // ID фулфилмент-центра для доставки
          logisticsPartnerId?: string // ID логистической компании
          items: Array<{
            productId: string
            quantity: number
            recipe?: {
              services: string[]
              fulfillmentConsumables: string[]
              sellerConsumables: string[]
              marketplaceCardId?: string
            }
          }>
          notes?: string // Дополнительные заметки к заказу
          consumableType?: string // Классификация расходников
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      console.warn('🔍 Проверка пользователя:', {
        userId: context.user.id,
        userFound: !!currentUser,
        organizationFound: !!currentUser?.organization,
        organizationType: currentUser?.organization?.type,
        organizationId: currentUser?.organization?.id,
      })

      if (!currentUser) {
        throw new GraphQLError('Пользователь не найден')
      }

      if (!currentUser.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем тип организации и определяем роль в процессе поставки
      const allowedTypes = ['FULFILLMENT', 'SELLER', 'LOGIST']
      if (!allowedTypes.includes(currentUser.organization.type)) {
        throw new GraphQLError('Заказы поставок недоступны для данного типа организации')
      }

      // Определяем роль организации в процессе поставки
      const organizationRole = currentUser.organization.type
      let fulfillmentCenterId = args.input.fulfillmentCenterId

      // Если заказ создает фулфилмент-центр, он сам является получателем
      if (organizationRole === 'FULFILLMENT') {
        fulfillmentCenterId = currentUser.organization.id
      }

      // Если указан фулфилмент-центр, проверяем его существование
      if (fulfillmentCenterId) {
        const fulfillmentCenter = await prisma.organization.findFirst({
          where: {
            id: fulfillmentCenterId,
            type: 'FULFILLMENT',
          },
        })

        if (!fulfillmentCenter) {
          return {
            success: false,
            message: 'Указанный фулфилмент-центр не найден',
          }
        }
      }

      // Проверяем, что партнер существует и является поставщиком
      const partner = await prisma.organization.findFirst({
        where: {
          id: args.input.partnerId,
          type: 'WHOLESALE',
        },
      })

      if (!partner) {
        return {
          success: false,
          message: 'Партнер не найден или не является поставщиком',
        }
      }

      // Проверяем, что партнер является контрагентом
      const counterparty = await prisma.counterparty.findFirst({
        where: {
          organizationId: currentUser.organization.id,
          counterpartyId: args.input.partnerId,
        },
      })

      if (!counterparty) {
        return {
          success: false,
          message: 'Данная организация не является вашим партнером',
        }
      }

      // Получаем товары для проверки наличия и цен
      const productIds = args.input.items.map((item) => item.productId)
      const products = await prisma.product.findMany({
        where: {
          id: { in: productIds },
          organizationId: args.input.partnerId,
          isActive: true,
        },
      })

      if (products.length !== productIds.length) {
        return {
          success: false,
          message: 'Некоторые товары не найдены или неактивны',
        }
      }

      // Проверяем наличие товаров
      for (const item of args.input.items) {
        const product = products.find((p) => p.id === item.productId)
        if (!product) {
          return {
            success: false,
            message: `Товар ${item.productId} не найден`,
          }
        }
        if (product.quantity < item.quantity) {
          return {
            success: false,
            message: `Недостаточно товара "${product.name}". Доступно: ${product.quantity}, запрошено: ${item.quantity}`,
          }
        }
      }

      // Рассчитываем общую сумму и количество
      let totalAmount = 0
      let totalItems = 0
      const orderItems = args.input.items.map((item) => {
        const product = products.find((p) => p.id === item.productId)!
        const itemTotal = Number(product.price) * item.quantity
        totalAmount += itemTotal
        totalItems += item.quantity

        return {
          productId: item.productId,
          quantity: item.quantity,
          price: product.price,
          totalPrice: new Prisma.Decimal(itemTotal),
          // Передача данных рецептуры в Prisma модель
          services: item.recipe?.services || [],
          fulfillmentConsumables: item.recipe?.fulfillmentConsumables || [],
          sellerConsumables: item.recipe?.sellerConsumables || [],
          marketplaceCardId: item.recipe?.marketplaceCardId,
        }
      })

      try {
        // Определяем начальный статус в зависимости от роли организации
        let initialStatus: 'PENDING' | 'CONFIRMED' = 'PENDING'
        if (organizationRole === 'SELLER') {
          initialStatus = 'PENDING' // Селлер создает заказ, ждет подтверждения поставщика
        } else if (organizationRole === 'FULFILLMENT') {
          initialStatus = 'PENDING' // Фулфилмент заказывает для своего склада
        } else if (organizationRole === 'LOGIST') {
          initialStatus = 'CONFIRMED' // Логист может сразу подтверждать заказы
        }

        // Подготавливаем данные для создания заказа
        const createData: any = {
          partnerId: args.input.partnerId,
          deliveryDate: new Date(args.input.deliveryDate),
          totalAmount: new Prisma.Decimal(totalAmount),
          totalItems: totalItems,
          organizationId: currentUser.organization.id,
          fulfillmentCenterId: fulfillmentCenterId,
          consumableType: args.input.consumableType,
          status: initialStatus,
          items: {
            create: orderItems,
          },
        }

        // 🔄 ЛОГИСТИКА ОПЦИОНАЛЬНА: добавляем только если передана
        if (args.input.logisticsPartnerId) {
          createData.logisticsPartnerId = args.input.logisticsPartnerId
        }

        console.warn('🔍 Создаем SupplyOrder с данными:', {
          hasLogistics: !!args.input.logisticsPartnerId,
          logisticsId: args.input.logisticsPartnerId,
          createData: createData,
        })

        const supplyOrder = await prisma.supplyOrder.create({
          data: createData,
          include: {
            partner: {
              include: {
                users: true,
              },
            },
            organization: {
              include: {
                users: true,
              },
            },
            fulfillmentCenter: {
              include: {
                users: true,
              },
            },
            logisticsPartner: {
              include: {
                users: true,
              },
            },
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        // Реалтайм: уведомляем поставщика и вовлеченные стороны о новом заказе
        try {
          const orgIds = [
            currentUser.organization.id,
            args.input.partnerId,
            fulfillmentCenterId || undefined,
            args.input.logisticsPartnerId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:new',
            payload: { id: supplyOrder.id, organizationId: currentUser.organization.id },
          })
        } catch {}

        // 📦 РЕЗЕРВИРУЕМ ТОВАРЫ У ПОСТАВЩИКА
        // Увеличиваем поле "ordered" для каждого заказанного товара
        for (const item of args.input.items) {
          await prisma.product.update({
            where: { id: item.productId },
            data: {
              ordered: {
                increment: item.quantity,
              },
            },
          })
        }

        console.warn(
          `📦 Зарезервированы товары для заказа ${supplyOrder.id}:`,
          args.input.items.map((item) => `${item.productId}: +${item.quantity} шт.`).join(', '),
        )

        // Проверяем, является ли это первой сделкой организации
        const isFirstOrder = await prisma.supplyOrder.count({
          where: { 
            organizationId: currentUser.organization.id,
            id: { not: supplyOrder.id },
          },
        }) === 0

        // Если это первая сделка и организация была приглашена по реферальной ссылке
        if (isFirstOrder && currentUser.organization.referredById) {
          try {
            // Создаем транзакцию на 100 сфер за первую сделку
            await prisma.referralTransaction.create({
              data: {
                referrerId: currentUser.organization.referredById,
                referralId: currentUser.organization.id,
                points: 100,
                type: 'FIRST_ORDER',
                description: `Первая сделка реферала ${currentUser.organization.name || currentUser.organization.inn}`,
              },
            })

            // Увеличиваем счетчик сфер у реферера
            await prisma.organization.update({
              where: { id: currentUser.organization.referredById },
              data: { referralPoints: { increment: 100 } },
            })

            console.log(`💰 Начислено 100 сфер рефереру за первую сделку организации ${currentUser.organization.id}`)
          } catch (error) {
            console.error('Ошибка начисления сфер за первую сделку:', error)
            // Не прерываем создание заказа из-за ошибки начисления
          }
        }

        // Создаем расходники на основе заказанных товаров
        // Расходники создаются в организации получателя (фулфилмент-центре)
        const suppliesData = args.input.items.map((item) => {
          const product = products.find((p) => p.id === item.productId)!
          const productWithCategory = supplyOrder.items.find(
            (orderItem: { productId: string; product: { category?: { name: string } | null } }) =>
              orderItem.productId === item.productId,
          )?.product

          return {
            name: product.name,
            description: product.description || `Заказано у ${partner.name}`,
            price: product.price, // Цена закупки у поставщика
            quantity: item.quantity,
            unit: 'шт',
            category: productWithCategory?.category?.name || 'Расходники',
            status: 'planned', // Статус "запланировано" (ожидает одобрения поставщиком)
            date: new Date(args.input.deliveryDate),
            supplier: partner.name || partner.fullName || 'Не указан',
            minStock: Math.round(item.quantity * 0.1), // 10% от заказанного как минимальный остаток
            currentStock: 0, // Пока товар не пришел
            // Расходники создаются в организации получателя (фулфилмент-центре)
            organizationId: fulfillmentCenterId || currentUser.organization!.id,
          }
        })

        // Создаем расходники
        await prisma.supply.createMany({
          data: suppliesData,
        })

        // 🔔 ОТПРАВЛЯЕМ УВЕДОМЛЕНИЕ ПОСТАВЩИКУ О НОВОМ ЗАКАЗЕ
        try {
          const orderSummary = args.input.items
            .map((item) => {
              const product = products.find((p) => p.id === item.productId)!
              return `${product.name} - ${item.quantity} шт.`
            })
            .join(', ')

          const notificationMessage = `🔔 Новый заказ поставки от ${
            currentUser.organization.name || currentUser.organization.fullName
          }!\n\nТовары: ${orderSummary}\nДата доставки: ${new Date(args.input.deliveryDate).toLocaleDateString(
            'ru-RU',
          )}\nОбщая сумма: ${totalAmount.toLocaleString(
            'ru-RU',
          )} ₽\n\nПожалуйста, подтвердите заказ в разделе "Поставки".`

          await prisma.message.create({
            data: {
              content: notificationMessage,
              type: 'TEXT',
              senderId: context.user.id,
              senderOrganizationId: currentUser.organization.id,
              receiverOrganizationId: args.input.partnerId,
            },
          })

          console.warn(`✅ Уведомление отправлено поставщику ${partner.name}`)
        } catch (notificationError) {
          console.error('❌ Ошибка отправки уведомления:', notificationError)
          // Не прерываем выполнение, если уведомление не отправилось
        }

        // Формируем сообщение в зависимости от роли организации
        let successMessage = ''
        if (organizationRole === 'SELLER') {
          successMessage = `Заказ поставки расходников создан! Расходники будут доставлены ${
            fulfillmentCenterId ? 'на указанный фулфилмент-склад' : 'согласно настройкам'
          }. Ожидайте подтверждения от поставщика.`
        } else if (organizationRole === 'FULFILLMENT') {
          successMessage =
            'Заказ поставки расходников создан для вашего склада! Ожидайте подтверждения от поставщика и координации с логистикой.'
        } else if (organizationRole === 'LOGIST') {
          successMessage =
            'Заказ поставки создан и подтвержден! Координируйте доставку расходников от поставщика на фулфилмент-склад.'
        }

        return {
          success: true,
          message: successMessage,
          order: supplyOrder,
          processInfo: {
            role: organizationRole,
            supplier: partner.name || partner.fullName,
            fulfillmentCenter: fulfillmentCenterId,
            logistics: args.input.logisticsPartnerId,
            status: initialStatus,
          },
        }
      } catch (error) {
        console.error('Error creating supply order:', error)
        return {
          success: false,
          message: 'Ошибка при создании заказа поставки',
        }
      }
    },

    // Создать товар
    createProduct: async (
      _: unknown,
      args: {
        input: {
          name: string
          article: string
          description?: string
          price: number
          pricePerSet?: number
          quantity: number
          setQuantity?: number
          ordered?: number
          inTransit?: number
          stock?: number
          sold?: number
          type?: 'PRODUCT' | 'CONSUMABLE'
          categoryId?: string
          brand?: string
          color?: string
          size?: string
          weight?: number
          dimensions?: string
          material?: string
          images?: string[]
          mainImage?: string
          isActive?: boolean
        }
      },
      context: Context,
    ) => {
      console.warn('🆕 CREATE_PRODUCT RESOLVER - ВЫЗВАН:', {
        hasUser: !!context.user,
        userId: context.user?.id,
        inputData: args.input,
        timestamp: new Date().toISOString(),
      })

      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это поставщик
      if (currentUser.organization.type !== 'WHOLESALE') {
        throw new GraphQLError('Товары доступны только для поставщиков')
      }

      // Проверяем уникальность артикула в рамках организации
      const existingProduct = await prisma.product.findFirst({
        where: {
          article: args.input.article,
          organizationId: currentUser.organization.id,
        },
      })

      if (existingProduct) {
        return {
          success: false,
          message: 'Товар с таким артикулом уже существует',
        }
      }

      try {
        console.warn('🛍️ СОЗДАНИЕ ТОВАРА - НАЧАЛО:', {
          userId: currentUser.id,
          organizationId: currentUser.organization.id,
          organizationType: currentUser.organization.type,
          productData: {
            name: args.input.name,
            article: args.input.article,
            type: args.input.type || 'PRODUCT',
            isActive: args.input.isActive ?? true,
          },
        })

        const product = await prisma.product.create({
          data: {
            name: args.input.name,
            article: args.input.article,
            description: args.input.description,
            price: args.input.price,
            pricePerSet: args.input.pricePerSet,
            quantity: args.input.quantity,
            setQuantity: args.input.setQuantity,
            ordered: args.input.ordered,
            inTransit: args.input.inTransit,
            stock: args.input.stock,
            sold: args.input.sold,
            type: args.input.type || 'PRODUCT',
            categoryId: args.input.categoryId,
            brand: args.input.brand,
            color: args.input.color,
            size: args.input.size,
            weight: args.input.weight,
            dimensions: args.input.dimensions,
            material: args.input.material,
            images: JSON.stringify(args.input.images || []),
            mainImage: args.input.mainImage,
            isActive: args.input.isActive ?? true,
            organizationId: currentUser.organization.id,
          },
          include: {
            category: true,
            organization: true,
          },
        })

        console.warn('✅ ТОВАР УСПЕШНО СОЗДАН:', {
          productId: product.id,
          name: product.name,
          article: product.article,
          type: product.type,
          isActive: product.isActive,
          organizationId: product.organizationId,
          createdAt: product.createdAt,
        })

        return {
          success: true,
          message: 'Товар успешно создан',
          product,
        }
      } catch (error) {
        console.error('Error creating product:', error)
        return {
          success: false,
          message: 'Ошибка при создании товара',
        }
      }
    },

    // Обновить товар
    updateProduct: async (
      _: unknown,
      args: {
        id: string
        input: {
          name: string
          article: string
          description?: string
          price: number
          pricePerSet?: number
          quantity: number
          setQuantity?: number
          ordered?: number
          inTransit?: number
          stock?: number
          sold?: number
          type?: 'PRODUCT' | 'CONSUMABLE'
          categoryId?: string
          brand?: string
          color?: string
          size?: string
          weight?: number
          dimensions?: string
          material?: string
          images?: string[]
          mainImage?: string
          isActive?: boolean
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что товар принадлежит текущей организации
      const existingProduct = await prisma.product.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingProduct) {
        throw new GraphQLError('Товар не найден или нет доступа')
      }

      // Проверяем уникальность артикула (если он изменился)
      if (args.input.article !== existingProduct.article) {
        const duplicateProduct = await prisma.product.findFirst({
          where: {
            article: args.input.article,
            organizationId: currentUser.organization.id,
            NOT: { id: args.id },
          },
        })

        if (duplicateProduct) {
          return {
            success: false,
            message: 'Товар с таким артикулом уже существует',
          }
        }
      }

      try {
        const product = await prisma.product.update({
          where: { id: args.id },
          data: {
            name: args.input.name,
            article: args.input.article,
            description: args.input.description,
            price: args.input.price,
            pricePerSet: args.input.pricePerSet,
            quantity: args.input.quantity,
            setQuantity: args.input.setQuantity,
            ordered: args.input.ordered,
            inTransit: args.input.inTransit,
            stock: args.input.stock,
            sold: args.input.sold,
            ...(args.input.type && { type: args.input.type }),
            categoryId: args.input.categoryId,
            brand: args.input.brand,
            color: args.input.color,
            size: args.input.size,
            weight: args.input.weight,
            dimensions: args.input.dimensions,
            material: args.input.material,
            images: args.input.images ? JSON.stringify(args.input.images) : undefined,
            mainImage: args.input.mainImage,
            isActive: args.input.isActive ?? true,
          },
          include: {
            category: true,
            organization: true,
          },
        })

        return {
          success: true,
          message: 'Товар успешно обновлен',
          product,
        }
      } catch (error) {
        console.error('Error updating product:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении товара',
        }
      }
    },

    // Проверка уникальности артикула
    checkArticleUniqueness: async (_: unknown, args: { article: string; excludeId?: string }, context: Context) => {
      const { currentUser, prisma } = context

      if (!currentUser?.organization?.id) {
        return {
          isUnique: false,
          existingProduct: null,
        }
      }

      try {
        const existingProduct = await prisma.product.findFirst({
          where: {
            article: args.article,
            organizationId: currentUser.organization.id,
            ...(args.excludeId && { id: { not: args.excludeId } }),
          },
          select: {
            id: true,
            name: true,
            article: true,
          },
        })

        return {
          isUnique: !existingProduct,
          existingProduct,
        }
      } catch (error) {
        console.error('Error checking article uniqueness:', error)
        return {
          isUnique: false,
          existingProduct: null,
        }
      }
    },

    // Резервирование товара при создании заказа
    reserveProductStock: async (_: unknown, args: { productId: string; quantity: number }, context: Context) => {
      const { currentUser, prisma } = context

      if (!currentUser?.organization?.id) {
        return {
          success: false,
          message: 'Необходимо авторизоваться',
        }
      }

      try {
        const product = await prisma.product.findUnique({
          where: { id: args.productId },
        })

        if (!product) {
          return {
            success: false,
            message: 'Товар не найден',
          }
        }

        // Проверяем доступность товара
        const availableStock = (product.stock || product.quantity) - (product.ordered || 0)
        if (availableStock < args.quantity) {
          return {
            success: false,
            message: `Недостаточно товара на складе. Доступно: ${availableStock}, запрошено: ${args.quantity}`,
          }
        }

        // Резервируем товар (увеличиваем поле ordered)
        const updatedProduct = await prisma.product.update({
          where: { id: args.productId },
          data: {
            ordered: (product.ordered || 0) + args.quantity,
          },
        })

        console.warn(`📦 Зарезервировано ${args.quantity} единиц товара ${product.name}`)

        return {
          success: true,
          message: `Зарезервировано ${args.quantity} единиц товара`,
          product: updatedProduct,
        }
      } catch (error) {
        console.error('Error reserving product stock:', error)
        return {
          success: false,
          message: 'Ошибка при резервировании товара',
        }
      }
    },

    // Освобождение резерва при отмене заказа
    releaseProductReserve: async (_: unknown, args: { productId: string; quantity: number }, context: Context) => {
      const { currentUser, prisma } = context

      if (!currentUser?.organization?.id) {
        return {
          success: false,
          message: 'Необходимо авторизоваться',
        }
      }

      try {
        const product = await prisma.product.findUnique({
          where: { id: args.productId },
        })

        if (!product) {
          return {
            success: false,
            message: 'Товар не найден',
          }
        }

        // Освобождаем резерв (уменьшаем поле ordered)
        const newOrdered = Math.max((product.ordered || 0) - args.quantity, 0)

        const updatedProduct = await prisma.product.update({
          where: { id: args.productId },
          data: {
            ordered: newOrdered,
          },
        })

        console.warn(`🔄 Освобожден резерв ${args.quantity} единиц товара ${product.name}`)

        return {
          success: true,
          message: `Освобожден резерв ${args.quantity} единиц товара`,
          product: updatedProduct,
        }
      } catch (error) {
        console.error('Error releasing product reserve:', error)
        return {
          success: false,
          message: 'Ошибка при освобождении резерва',
        }
      }
    },

    // Обновление статуса "в пути"
    updateProductInTransit: async (
      _: unknown,
      args: { productId: string; quantity: number; operation: string },
      context: Context,
    ) => {
      const { currentUser, prisma } = context

      if (!currentUser?.organization?.id) {
        return {
          success: false,
          message: 'Необходимо авторизоваться',
        }
      }

      try {
        const product = await prisma.product.findUnique({
          where: { id: args.productId },
        })

        if (!product) {
          return {
            success: false,
            message: 'Товар не найден',
          }
        }

        let newInTransit = product.inTransit || 0
        let newOrdered = product.ordered || 0

        if (args.operation === 'ship') {
          // При отгрузке: переводим из "заказано" в "в пути"
          newInTransit = (product.inTransit || 0) + args.quantity
          newOrdered = Math.max((product.ordered || 0) - args.quantity, 0)
        } else if (args.operation === 'deliver') {
          // При доставке: убираем из "в пути", добавляем в "продано"
          newInTransit = Math.max((product.inTransit || 0) - args.quantity, 0)
        }

        const updatedProduct = await prisma.product.update({
          where: { id: args.productId },
          data: {
            inTransit: newInTransit,
            ordered: newOrdered,
            ...(args.operation === 'deliver' && {
              sold: (product.sold || 0) + args.quantity,
            }),
          },
        })

        console.warn(`🚚 Обновлен статус "в пути" для товара ${product.name}: ${args.operation}`)

        return {
          success: true,
          message: `Статус товара обновлен: ${args.operation}`,
          product: updatedProduct,
        }
      } catch (error) {
        console.error('Error updating product in transit:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении статуса товара',
        }
      }
    },

    // Удалить товар
    deleteProduct: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что товар принадлежит текущей организации
      const existingProduct = await prisma.product.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingProduct) {
        throw new GraphQLError('Товар не найден или нет доступа')
      }

      try {
        await prisma.product.delete({
          where: { id: args.id },
        })

        return true
      } catch (error) {
        console.error('Error deleting product:', error)
        return false
      }
    },

    // Создать категорию
    createCategory: async (_: unknown, args: { input: { name: string } }, context: Context) => {
      if (!context.user && !context.admin) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // Проверяем уникальность названия категории
      const existingCategory = await prisma.category.findUnique({
        where: { name: args.input.name },
      })

      if (existingCategory) {
        return {
          success: false,
          message: 'Категория с таким названием уже существует',
        }
      }

      try {
        const category = await prisma.category.create({
          data: {
            name: args.input.name,
          },
        })

        return {
          success: true,
          message: 'Категория успешно создана',
          category,
        }
      } catch (error) {
        console.error('Error creating category:', error)
        return {
          success: false,
          message: 'Ошибка при создании категории',
        }
      }
    },

    // Обновить категорию
    updateCategory: async (_: unknown, args: { id: string; input: { name: string } }, context: Context) => {
      if (!context.user && !context.admin) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // Проверяем существование категории
      const existingCategory = await prisma.category.findUnique({
        where: { id: args.id },
      })

      if (!existingCategory) {
        return {
          success: false,
          message: 'Категория не найдена',
        }
      }

      // Проверяем уникальность нового названия (если изменилось)
      if (args.input.name !== existingCategory.name) {
        const duplicateCategory = await prisma.category.findUnique({
          where: { name: args.input.name },
        })

        if (duplicateCategory) {
          return {
            success: false,
            message: 'Категория с таким названием уже существует',
          }
        }
      }

      try {
        const category = await prisma.category.update({
          where: { id: args.id },
          data: {
            name: args.input.name,
          },
        })

        return {
          success: true,
          message: 'Категория успешно обновлена',
          category,
        }
      } catch (error) {
        console.error('Error updating category:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении категории',
        }
      }
    },

    // Удалить категорию
    deleteCategory: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user && !context.admin) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      // Проверяем существование категории
      const existingCategory = await prisma.category.findUnique({
        where: { id: args.id },
        include: { products: true },
      })

      if (!existingCategory) {
        throw new GraphQLError('Категория не найдена')
      }

      // Проверяем, есть ли товары в этой категории
      if (existingCategory.products.length > 0) {
        throw new GraphQLError('Нельзя удалить категорию, в которой есть товары')
      }

      try {
        await prisma.category.delete({
          where: { id: args.id },
        })

        return true
      } catch (error) {
        console.error('Error deleting category:', error)
        return false
      }
    },

    // Добавить товар в корзину
    addToCart: async (_: unknown, args: { productId: string; quantity: number }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что товар существует и активен
      const product = await prisma.product.findFirst({
        where: {
          id: args.productId,
          isActive: true,
        },
        include: {
          organization: true,
        },
      })

      if (!product) {
        return {
          success: false,
          message: 'Товар не найден или неактивен',
        }
      }

      // Проверяем, что пользователь не пытается добавить свой собственный товар
      if (product.organizationId === currentUser.organization.id) {
        return {
          success: false,
          message: 'Нельзя добавлять собственные товары в корзину',
        }
      }

      // Найти или создать корзину
      let cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        cart = await prisma.cart.create({
          data: {
            organizationId: currentUser.organization.id,
          },
        })
      }

      try {
        // Проверяем, есть ли уже такой товар в корзине
        const existingCartItem = await prisma.cartItem.findUnique({
          where: {
            cartId_productId: {
              cartId: cart.id,
              productId: args.productId,
            },
          },
        })

        if (existingCartItem) {
          // Обновляем количество
          const newQuantity = existingCartItem.quantity + args.quantity

          if (newQuantity > product.quantity) {
            return {
              success: false,
              message: `Недостаточно товара в наличии. Доступно: ${product.quantity}`,
            }
          }

          await prisma.cartItem.update({
            where: { id: existingCartItem.id },
            data: { quantity: newQuantity },
          })
        } else {
          // Создаем новый элемент корзины
          if (args.quantity > product.quantity) {
            return {
              success: false,
              message: `Недостаточно товара в наличии. Доступно: ${product.quantity}`,
            }
          }

          await prisma.cartItem.create({
            data: {
              cartId: cart.id,
              productId: args.productId,
              quantity: args.quantity,
            },
          })
        }

        // Возвращаем обновленную корзину
        const updatedCart = await prisma.cart.findUnique({
          where: { id: cart.id },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
            },
            organization: true,
          },
        })

        return {
          success: true,
          message: 'Товар добавлен в корзину',
          cart: updatedCart,
        }
      } catch (error) {
        console.error('Error adding to cart:', error)
        return {
          success: false,
          message: 'Ошибка при добавлении в корзину',
        }
      }
    },

    // Обновить количество товара в корзине
    updateCartItem: async (_: unknown, args: { productId: string; quantity: number }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      const cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        return {
          success: false,
          message: 'Корзина не найдена',
        }
      }

      // Проверяем, что товар существует в корзине
      const cartItem = await prisma.cartItem.findUnique({
        where: {
          cartId_productId: {
            cartId: cart.id,
            productId: args.productId,
          },
        },
        include: {
          product: true,
        },
      })

      if (!cartItem) {
        return {
          success: false,
          message: 'Товар не найден в корзине',
        }
      }

      if (args.quantity <= 0) {
        return {
          success: false,
          message: 'Количество должно быть больше 0',
        }
      }

      if (args.quantity > cartItem.product.quantity) {
        return {
          success: false,
          message: `Недостаточно товара в наличии. Доступно: ${cartItem.product.quantity}`,
        }
      }

      try {
        await prisma.cartItem.update({
          where: { id: cartItem.id },
          data: { quantity: args.quantity },
        })

        // Возвращаем обновленную корзину
        const updatedCart = await prisma.cart.findUnique({
          where: { id: cart.id },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
            },
            organization: true,
          },
        })

        return {
          success: true,
          message: 'Количество товара обновлено',
          cart: updatedCart,
        }
      } catch (error) {
        console.error('Error updating cart item:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении корзины',
        }
      }
    },

    // Удалить товар из корзины
    removeFromCart: async (_: unknown, args: { productId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      const cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        return {
          success: false,
          message: 'Корзина не найдена',
        }
      }

      try {
        await prisma.cartItem.delete({
          where: {
            cartId_productId: {
              cartId: cart.id,
              productId: args.productId,
            },
          },
        })

        // Возвращаем обновленную корзину
        const updatedCart = await prisma.cart.findUnique({
          where: { id: cart.id },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: {
                      include: {
                        users: true,
                      },
                    },
                  },
                },
              },
            },
            organization: true,
          },
        })

        return {
          success: true,
          message: 'Товар удален из корзины',
          cart: updatedCart,
        }
      } catch (error) {
        console.error('Error removing from cart:', error)
        return {
          success: false,
          message: 'Ошибка при удалении из корзины',
        }
      }
    },

    // Очистить корзину
    clearCart: async (_: unknown, __: unknown, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      const cart = await prisma.cart.findUnique({
        where: { organizationId: currentUser.organization.id },
      })

      if (!cart) {
        return false
      }

      try {
        await prisma.cartItem.deleteMany({
          where: { cartId: cart.id },
        })

        return true
      } catch (error) {
        console.error('Error clearing cart:', error)
        return false
      }
    },

    // Добавить товар в избранное
    addToFavorites: async (_: unknown, args: { productId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что товар существует и активен
      const product = await prisma.product.findFirst({
        where: {
          id: args.productId,
          isActive: true,
        },
        include: {
          organization: true,
        },
      })

      if (!product) {
        return {
          success: false,
          message: 'Товар не найден или неактивен',
        }
      }

      // Проверяем, что пользователь не пытается добавить свой собственный товар
      if (product.organizationId === currentUser.organization.id) {
        return {
          success: false,
          message: 'Нельзя добавлять собственные товары в избранное',
        }
      }

      try {
        // Проверяем, есть ли уже такой товар в избранном
        const existingFavorite = await prisma.favorites.findUnique({
          where: {
            organizationId_productId: {
              organizationId: currentUser.organization.id,
              productId: args.productId,
            },
          },
        })

        if (existingFavorite) {
          return {
            success: false,
            message: 'Товар уже в избранном',
          }
        }

        // Добавляем товар в избранное
        await prisma.favorites.create({
          data: {
            organizationId: currentUser.organization.id,
            productId: args.productId,
          },
        })

        // Возвращаем обновленный список избранного
        const favorites = await prisma.favorites.findMany({
          where: { organizationId: currentUser.organization.id },
          include: {
            product: {
              include: {
                category: true,
                organization: {
                  include: {
                    users: true,
                  },
                },
              },
            },
          },
          orderBy: { createdAt: 'desc' },
        })

        return {
          success: true,
          message: 'Товар добавлен в избранное',
          favorites: favorites.map((favorite) => favorite.product),
        }
      } catch (error) {
        console.error('Error adding to favorites:', error)
        return {
          success: false,
          message: 'Ошибка при добавлении в избранное',
        }
      }
    },

    // Удалить товар из избранного
    removeFromFavorites: async (_: unknown, args: { productId: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Удаляем товар из избранного
        await prisma.favorites.deleteMany({
          where: {
            organizationId: currentUser.organization.id,
            productId: args.productId,
          },
        })

        // Возвращаем обновленный список избранного
        const favorites = await prisma.favorites.findMany({
          where: { organizationId: currentUser.organization.id },
          include: {
            product: {
              include: {
                category: true,
                organization: {
                  include: {
                    users: true,
                  },
                },
              },
            },
          },
          orderBy: { createdAt: 'desc' },
        })

        return {
          success: true,
          message: 'Товар удален из избранного',
          favorites: favorites.map((favorite) => favorite.product),
        }
      } catch (error) {
        console.error('Error removing from favorites:', error)
        return {
          success: false,
          message: 'Ошибка при удалении из избранного',
        }
      }
    },

    // Создать сотрудника
    createEmployee: async (_: unknown, args: { input: CreateEmployeeInput }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступно только для фулфилмент центров')
      }

      try {
        const employee = await prisma.employee.create({
          data: {
            ...args.input,
            organizationId: currentUser.organization.id,
            birthDate: args.input.birthDate ? new Date(args.input.birthDate) : undefined,
            passportDate: args.input.passportDate ? new Date(args.input.passportDate) : undefined,
            hireDate: new Date(args.input.hireDate),
          },
          include: {
            organization: true,
          },
        })

        return {
          success: true,
          message: 'Сотрудник успешно добавлен',
          employee,
        }
      } catch (error) {
        console.error('Error creating employee:', error)
        return {
          success: false,
          message: 'Ошибка при создании сотрудника',
        }
      }
    },

    // Обновить сотрудника
    updateEmployee: async (_: unknown, args: { id: string; input: UpdateEmployeeInput }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступно только для фулфилмент центров')
      }

      try {
        const employee = await prisma.employee.update({
          where: {
            id: args.id,
            organizationId: currentUser.organization.id,
          },
          data: {
            ...args.input,
            birthDate: args.input.birthDate ? new Date(args.input.birthDate) : undefined,
            passportDate: args.input.passportDate ? new Date(args.input.passportDate) : undefined,
            hireDate: args.input.hireDate ? new Date(args.input.hireDate) : undefined,
          },
          include: {
            organization: true,
          },
        })

        return {
          success: true,
          message: 'Сотрудник успешно обновлен',
          employee,
        }
      } catch (error) {
        console.error('Error updating employee:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении сотрудника',
        }
      }
    },

    // Удалить сотрудника
    deleteEmployee: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступно только для фулфилмент центров')
      }

      try {
        await prisma.employee.delete({
          where: {
            id: args.id,
            organizationId: currentUser.organization.id,
          },
        })

        return true
      } catch (error) {
        console.error('Error deleting employee:', error)
        return false
      }
    },

    // Обновить табель сотрудника
    updateEmployeeSchedule: async (_: unknown, args: { input: UpdateScheduleInput }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступно только для фулфилмент центров')
      }

      try {
        // Проверяем что сотрудник принадлежит организации
        const employee = await prisma.employee.findFirst({
          where: {
            id: args.input.employeeId,
            organizationId: currentUser.organization.id,
          },
        })

        if (!employee) {
          throw new GraphQLError('Сотрудник не найден')
        }

        // Создаем или обновляем запись табеля
        await prisma.employeeSchedule.upsert({
          where: {
            employeeId_date: {
              employeeId: args.input.employeeId,
              date: new Date(args.input.date),
            },
          },
          create: {
            employeeId: args.input.employeeId,
            date: new Date(args.input.date),
            status: args.input.status,
            hoursWorked: args.input.hoursWorked,
            overtimeHours: args.input.overtimeHours,
            notes: args.input.notes,
          },
          update: {
            status: args.input.status,
            hoursWorked: args.input.hoursWorked,
            overtimeHours: args.input.overtimeHours,
            notes: args.input.notes,
          },
        })

        return true
      } catch (error) {
        console.error('Error updating employee schedule:', error)
        return false
      }
    },

    // Создать поставку Wildberries
    createWildberriesSupply: async (
      _: unknown,
      args: {
        input: {
          cards: Array<{
            price: number
            discountedPrice?: number
            selectedQuantity: number
            selectedServices?: string[]
          }>
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Пока что просто логируем данные, так как таблицы еще нет
        console.warn('Создание поставки Wildberries с данными:', args.input)

        const totalAmount = args.input.cards.reduce((sum: number, card) => {
          const cardPrice = card.discountedPrice || card.price
          const servicesPrice = (card.selectedServices?.length || 0) * 50
          return sum + (cardPrice + servicesPrice) * card.selectedQuantity
        }, 0)

        const totalItems = args.input.cards.reduce((sum: number, card) => sum + card.selectedQuantity, 0)

        // Временная заглушка - вернем success без создания в БД
        return {
          success: true,
          message: `Поставка создана успешно! Товаров: ${totalItems}, Сумма: ${totalAmount} руб.`,
          supply: null, // Временно null
        }
      } catch (error) {
        console.error('Error creating Wildberries supply:', error)
        return {
          success: false,
          message: 'Ошибка при создании поставки Wildberries',
        }
      }
    },

    // Создать поставщика для поставки
    createSupplySupplier: async (
      _: unknown,
      args: {
        input: {
          name: string
          contactName: string
          phone: string
          market?: string
          address?: string
          place?: string
          telegram?: string
        }
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Создаем поставщика в базе данных
        const supplier = await prisma.supplySupplier.create({
          data: {
            name: args.input.name,
            contactName: args.input.contactName,
            phone: args.input.phone,
            market: args.input.market,
            address: args.input.address,
            place: args.input.place,
            telegram: args.input.telegram,
            organizationId: currentUser.organization.id,
          },
        })

        return {
          success: true,
          message: 'Поставщик добавлен успешно!',
          supplier: {
            id: supplier.id,
            name: supplier.name,
            contactName: supplier.contactName,
            phone: supplier.phone,
            market: supplier.market,
            address: supplier.address,
            place: supplier.place,
            telegram: supplier.telegram,
            createdAt: supplier.createdAt,
          },
        }
      } catch (error) {
        console.error('Error creating supply supplier:', error)
        return {
          success: false,
          message: 'Ошибка при добавлении поставщика',
        }
      }
    },

    // Обновить статус заказа поставки
    updateSupplyOrderStatus: async (
      _: unknown,
      args: {
        id: string
        status:
          | 'PENDING'
          | 'CONFIRMED'
          | 'IN_TRANSIT'
          | 'SUPPLIER_APPROVED'
          | 'LOGISTICS_CONFIRMED'
          | 'SHIPPED'
          | 'DELIVERED'
          | 'CANCELLED'
      },
      context: Context,
    ) => {
      console.warn(`[DEBUG] updateSupplyOrderStatus вызван для заказа ${args.id} со статусом ${args.status}`)
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Находим заказ поставки
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            OR: [
              { organizationId: currentUser.organization.id }, // Создатель заказа
              { partnerId: currentUser.organization.id }, // Поставщик
              { fulfillmentCenterId: currentUser.organization.id }, // Фулфилмент-центр
            ],
          },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                  },
                },
              },
            },
            partner: true,
            fulfillmentCenter: true,
          },
        })

        if (!existingOrder) {
          throw new GraphQLError('Заказ поставки не найден или нет доступа')
        }

        // Обновляем статус заказа
        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: args.status },
          include: {
            partner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                  },
                },
              },
            },
          },
        })

        // ОТКЛЮЧЕНО: Устаревшая логика для обновления расходников
        // Теперь используются специальные мутации для каждой роли
        const targetOrganizationId = existingOrder.fulfillmentCenterId || existingOrder.organizationId

        if (args.status === 'CONFIRMED') {
          console.warn(`[WARNING] Попытка использовать устаревший статус CONFIRMED для заказа ${args.id}`)
          // Не обновляем расходники для устаревших статусов
          // await prisma.supply.updateMany({
          //   where: {
          //     organizationId: targetOrganizationId,
          //     status: "planned",
          //     name: {
          //       in: existingOrder.items.map(item => item.product.name)
          //     }
          //   },
          //   data: {
          //     status: "confirmed"
          //   }
          // });

          console.warn("✅ Статусы расходников обновлены на 'confirmed'")
        }

        if (args.status === 'IN_TRANSIT') {
          // При отгрузке - переводим расходники в статус "in-transit"
          await prisma.supply.updateMany({
            where: {
              organizationId: targetOrganizationId,
              status: 'confirmed',
              name: {
                in: existingOrder.items.map((item) => item.product.name),
              },
            },
            data: {
              status: 'in-transit',
            },
          })

          console.warn("✅ Статусы расходников обновлены на 'in-transit'")
        }

        // Если статус изменился на DELIVERED, обновляем склад
        if (args.status === 'DELIVERED') {
          console.warn('🚚 Обновляем склад организации:', {
            targetOrganizationId,
            fulfillmentCenterId: existingOrder.fulfillmentCenterId,
            organizationId: existingOrder.organizationId,
            itemsCount: existingOrder.items.length,
            items: existingOrder.items.map((item) => ({
              productName: item.product.name,
              quantity: item.quantity,
            })),
          })

          // 🔄 СИНХРОНИЗАЦИЯ: Обновляем товары поставщика (переводим из "в пути" в "продано" + обновляем основные остатки)
          for (const item of existingOrder.items) {
            const product = await prisma.product.findUnique({
              where: { id: item.product.id },
            })

            if (product) {
              // ИСПРАВЛЕНО: НЕ списываем повторно, только переводим из inTransit в sold
              // Остаток уже был уменьшен при создании/одобрении заказа
              await prisma.product.update({
                where: { id: item.product.id },
                data: {
                  // НЕ ТРОГАЕМ stock - он уже правильно уменьшен при заказе
                  // Только переводим из inTransit в sold
                  inTransit: Math.max((product.inTransit || 0) - item.quantity, 0),
                  sold: (product.sold || 0) + item.quantity,
                },
              })
              console.warn(
                `✅ Товар поставщика "${product.name}" обновлен: доставлено ${
                  item.quantity
                } единиц (остаток НЕ ИЗМЕНЕН: ${product.stock || product.quantity || 0})`,
              )
            }
          }

          // Обновляем расходники
          for (const item of existingOrder.items) {
            console.warn('📦 Обрабатываем товар:', {
              productName: item.product.name,
              quantity: item.quantity,
              targetOrganizationId,
              consumableType: existingOrder.consumableType,
            })

            // ИСПРАВЛЕНИЕ: Определяем правильный тип расходников
            const isSellerSupply = existingOrder.consumableType === 'SELLER_CONSUMABLES'
            const supplyType = isSellerSupply ? 'SELLER_CONSUMABLES' : 'FULFILLMENT_CONSUMABLES'
            const sellerOwnerId = isSellerSupply ? existingOrder.organizationId : null

            console.warn('🔍 Определен тип расходников:', {
              isSellerSupply,
              supplyType,
              sellerOwnerId,
            })

            // ИСПРАВЛЕНИЕ: Ищем по Артикул СФ для уникальности вместо имени
            const whereCondition = isSellerSupply
              ? {
                  organizationId: targetOrganizationId,
                  article: item.product.article, // ИЗМЕНЕНО: поиск по article вместо name
                  type: 'SELLER_CONSUMABLES' as const,
                  sellerOwnerId: existingOrder.organizationId,
                }
              : {
                  organizationId: targetOrganizationId,
                  article: item.product.article, // ИЗМЕНЕНО: поиск по article вместо name
                  type: 'FULFILLMENT_CONSUMABLES' as const,
                  sellerOwnerId: null, // Для фулфилмента sellerOwnerId должен быть null
                }

            console.warn('🔍 Ищем существующий расходник с условиями:', whereCondition)

            const existingSupply = await prisma.supply.findFirst({
              where: whereCondition,
            })

            if (existingSupply) {
              console.warn('📈 ОБНОВЛЯЕМ существующий расходник:', {
                id: existingSupply.id,
                oldStock: existingSupply.currentStock,
                oldQuantity: existingSupply.quantity,
                addingQuantity: item.quantity,
              })

              // ОБНОВЛЯЕМ существующий расходник
              const updatedSupply = await prisma.supply.update({
                where: { id: existingSupply.id },
                data: {
                  currentStock: existingSupply.currentStock + item.quantity,
                  quantity: existingSupply.quantity + item.quantity, // Обновляем общее количество
                  status: 'in-stock', // Меняем статус на "на складе"
                  updatedAt: new Date(),
                },
              })

              console.warn('✅ Расходник ОБНОВЛЕН (НЕ создан дубликат):', {
                id: updatedSupply.id,
                name: updatedSupply.name,
                newCurrentStock: updatedSupply.currentStock,
                newTotalQuantity: updatedSupply.quantity,
                type: updatedSupply.type,
              })
            } else {
              console.warn('➕ СОЗДАЕМ новый расходник (не найден существующий):', {
                name: item.product.name,
                quantity: item.quantity,
                organizationId: targetOrganizationId,
                type: supplyType,
                sellerOwnerId: sellerOwnerId,
              })

              // СОЗДАЕМ новый расходник
              const newSupply = await prisma.supply.create({
                data: {
                  name: item.product.name,
                  article: item.product.article, // ДОБАВЛЕНО: Артикул СФ для уникальности
                  description: item.product.description || `Поставка от ${existingOrder.partner.name}`,
                  price: item.price, // Цена закупки у поставщика
                  quantity: item.quantity,
                  unit: 'шт',
                  category: item.product.category?.name || 'Расходники',
                  status: 'in-stock',
                  date: new Date(),
                  supplier: existingOrder.partner.name || existingOrder.partner.fullName || 'Не указан',
                  minStock: Math.round(item.quantity * 0.1),
                  currentStock: item.quantity,
                  organizationId: targetOrganizationId,
                  type: supplyType as 'SELLER_CONSUMABLES' | 'FULFILLMENT_CONSUMABLES',
                  sellerOwnerId: sellerOwnerId,
                },
              })

              console.warn('✅ Новый расходник СОЗДАН:', {
                id: newSupply.id,
                name: newSupply.name,
                currentStock: newSupply.currentStock,
                type: newSupply.type,
                sellerOwnerId: newSupply.sellerOwnerId,
              })
            }
          }

          console.warn('🎉 Склад организации успешно обновлен!')
        }

        // Уведомляем вовлеченные организации об изменении статуса заказа
        try {
          const orgIds = [
            existingOrder.organizationId,
            existingOrder.partnerId,
            existingOrder.fulfillmentCenterId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: `Статус заказа поставки обновлен на "${args.status}"`,
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error updating supply order status:', error)
        return {
          success: false,
          message: 'Ошибка при обновлении статуса заказа поставки',
        }
      }
    },

    // Назначение логистики фулфилментом на заказ селлера
    assignLogisticsToSupply: async (
      _: unknown,
      args: {
        supplyOrderId: string
        logisticsPartnerId: string
        responsibleId?: string
      },
      context: Context,
    ) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что пользователь - фулфилмент
      if (currentUser.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Только фулфилмент может назначать логистику')
      }

      try {
        // Находим заказ
        const existingOrder = await prisma.supplyOrder.findUnique({
          where: { id: args.supplyOrderId },
          include: {
            partner: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: { product: true },
            },
          },
        })

        if (!existingOrder) {
          throw new GraphQLError('Заказ поставки не найден')
        }

        // Проверяем, что это заказ для нашего фулфилмент-центра
        if (existingOrder.fulfillmentCenterId !== currentUser.organization.id) {
          throw new GraphQLError('Нет доступа к этому заказу')
        }

        // Проверяем, что статус позволяет назначить логистику
        if (existingOrder.status !== 'SUPPLIER_APPROVED') {
          throw new GraphQLError(`Нельзя назначить логистику для заказа со статусом ${existingOrder.status}`)
        }

        // Проверяем, что логистическая компания существует
        const logisticsPartner = await prisma.organization.findUnique({
          where: { id: args.logisticsPartnerId },
        })

        if (!logisticsPartner || logisticsPartner.type !== 'LOGIST') {
          throw new GraphQLError('Логистическая компания не найдена')
        }

        // Обновляем заказ
        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.supplyOrderId },
          data: {
            logisticsPartner: {
              connect: { id: args.logisticsPartnerId },
            },
            status: 'CONFIRMED', // Переводим в статус "подтвержден фулфилментом"
          },
          include: {
            partner: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: { product: true },
            },
          },
        })

        console.warn(`✅ Логистика назначена на заказ ${args.supplyOrderId}:`, {
          logisticsPartner: logisticsPartner.name,
          responsible: args.responsibleId,
          newStatus: 'CONFIRMED',
        })

        try {
          const orgIds = [
            existingOrder.organizationId,
            existingOrder.partnerId,
            existingOrder.fulfillmentCenterId || undefined,
            args.logisticsPartnerId,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: 'Логистика успешно назначена',
          order: updatedOrder,
        }
      } catch (error) {
        console.error('❌ Ошибка при назначении логистики:', error)
        return {
          success: false,
          message: error instanceof Error ? error.message : 'Ошибка при назначении логистики',
        }
      }
    },

    // Резолверы для новых действий с заказами поставок
    supplierApproveOrder: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        // Проверяем, что пользователь - поставщик этого заказа
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            partnerId: currentUser.organization.id, // Только поставщик может одобрить
            status: 'PENDING', // Можно одобрить только заказы в статусе PENDING
          },
        })

        if (!existingOrder) {
          return {
            success: false,
            message: 'Заказ не найден или недоступен для одобрения',
          }
        }

        console.warn(`[DEBUG] Поставщик ${currentUser.organization.name} одобряет заказ ${args.id}`)

        // 🔄 СИНХРОНИЗАЦИЯ ОСТАТКОВ: Резервируем товары у поставщика
        const orderWithItems = await prisma.supplyOrder.findUnique({
          where: { id: args.id },
          include: {
            items: {
              include: {
                product: true,
              },
            },
          },
        })

        if (orderWithItems) {
          for (const item of orderWithItems.items) {
            // Резервируем товар (увеличиваем поле ordered)
            const product = await prisma.product.findUnique({
              where: { id: item.product.id },
            })

            if (product) {
              const availableStock = (product.stock || product.quantity) - (product.ordered || 0)

              if (availableStock < item.quantity) {
                return {
                  success: false,
                  message: `Недостаточно товара "${product.name}" на складе. Доступно: ${availableStock}, требуется: ${item.quantity}`,
                }
              }

              // Согласно правилам: при одобрении заказа остаток должен уменьшиться
              const currentStock = product.stock || product.quantity || 0
              const newStock = Math.max(currentStock - item.quantity, 0)

              await prisma.product.update({
                where: { id: item.product.id },
                data: {
                  // Уменьшаем основной остаток (товар зарезервирован для заказа)
                  stock: newStock,
                  quantity: newStock, // Синхронизируем оба поля для совместимости
                  // Увеличиваем количество заказанного (для отслеживания)
                  ordered: (product.ordered || 0) + item.quantity,
                },
              })

              console.warn(`📦 Товар "${product.name}" зарезервирован: ${item.quantity} единиц`)
              console.warn(`   📊 Остаток: ${currentStock} -> ${newStock} (уменьшен на ${item.quantity})`)
              console.warn(`   📋 Заказано: ${product.ordered || 0} -> ${(product.ordered || 0) + item.quantity}`)
            }
          }
        }

        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: 'SUPPLIER_APPROVED' },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        console.warn(`[DEBUG] Заказ ${args.id} успешно обновлен до статуса: ${updatedOrder.status}`)
        try {
          const orgIds = [
            updatedOrder.organizationId,
            updatedOrder.partnerId,
            updatedOrder.fulfillmentCenterId || undefined,
            updatedOrder.logisticsPartnerId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: 'Заказ поставки одобрен поставщиком. Товары зарезервированы, остатки обновлены.',
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error approving supply order:', error)
        return {
          success: false,
          message: 'Ошибка при одобрении заказа поставки',
        }
      }
    },

    supplierRejectOrder: async (_: unknown, args: { id: string; reason?: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            partnerId: currentUser.organization.id,
            status: 'PENDING',
          },
        })

        if (!existingOrder) {
          return {
            success: false,
            message: 'Заказ не найден или недоступен для отклонения',
          }
        }

        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: 'CANCELLED' },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        // 📦 СНИМАЕМ РЕЗЕРВАЦИЮ ПРИ ОТКЛОНЕНИИ
        // Восстанавливаем остатки и убираем резервацию для каждого отклоненного товара
        for (const item of updatedOrder.items) {
          const product = await prisma.product.findUnique({
            where: { id: item.productId },
          })

          if (product) {
            // Восстанавливаем основные остатки (на случай, если заказ был одобрен, а затем отклонен)
            const currentStock = product.stock || product.quantity || 0
            const restoredStock = currentStock + item.quantity

            await prisma.product.update({
              where: { id: item.productId },
              data: {
                // Восстанавливаем основной остаток
                stock: restoredStock,
                quantity: restoredStock,
                // Уменьшаем количество заказанного
                ordered: Math.max((product.ordered || 0) - item.quantity, 0),
              },
            })

            console.warn(
              `🔄 Восстановлены остатки товара "${product.name}": ${currentStock} -> ${restoredStock}, ordered: ${
                product.ordered
              } -> ${Math.max((product.ordered || 0) - item.quantity, 0)}`,
            )
          }
        }

        console.warn(
          `📦 Снята резервация при отклонении заказа ${updatedOrder.id}:`,
          updatedOrder.items.map((item) => `${item.productId}: -${item.quantity} шт.`).join(', '),
        )

        try {
          const orgIds = [
            updatedOrder.organizationId,
            updatedOrder.partnerId,
            updatedOrder.fulfillmentCenterId || undefined,
            updatedOrder.logisticsPartnerId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: args.reason ? `Заказ отклонен поставщиком. Причина: ${args.reason}` : 'Заказ отклонен поставщиком',
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error rejecting supply order:', error)
        return {
          success: false,
          message: 'Ошибка при отклонении заказа поставки',
        }
      }
    },

    supplierShipOrder: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            partnerId: currentUser.organization.id,
            status: 'LOGISTICS_CONFIRMED',
          },
        })

        if (!existingOrder) {
          return {
            success: false,
            message: 'Заказ не найден или недоступен для отправки',
          }
        }

        // 🔄 СИНХРОНИЗАЦИЯ ОСТАТКОВ: Переводим товары из "заказано" в "в пути"
        const orderWithItems = await prisma.supplyOrder.findUnique({
          where: { id: args.id },
          include: {
            items: {
              include: {
                product: true,
              },
            },
          },
        })

        if (orderWithItems) {
          for (const item of orderWithItems.items) {
            const product = await prisma.product.findUnique({
              where: { id: item.product.id },
            })

            if (product) {
              await prisma.product.update({
                where: { id: item.product.id },
                data: {
                  ordered: Math.max((product.ordered || 0) - item.quantity, 0),
                  inTransit: (product.inTransit || 0) + item.quantity,
                },
              })

              console.warn(`🚚 Товар "${product.name}" переведен в статус "в пути": ${item.quantity} единиц`)
            }
          }
        }

        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: 'SHIPPED' },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        try {
          const orgIds = [
            updatedOrder.organizationId,
            updatedOrder.partnerId,
            updatedOrder.fulfillmentCenterId || undefined,
            updatedOrder.logisticsPartnerId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: "Заказ отправлен поставщиком. Товары переведены в статус 'в пути'.",
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error shipping supply order:', error)
        return {
          success: false,
          message: 'Ошибка при отправке заказа поставки',
        }
      }
    },

    logisticsConfirmOrder: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            logisticsPartnerId: currentUser.organization.id,
            OR: [{ status: 'SUPPLIER_APPROVED' }, { status: 'CONFIRMED' }],
          },
        })

        if (!existingOrder) {
          return {
            success: false,
            message: 'Заказ не найден или недоступен для подтверждения логистикой',
          }
        }

        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: 'LOGISTICS_CONFIRMED' },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        try {
          const orgIds = [
            updatedOrder.organizationId,
            updatedOrder.partnerId,
            updatedOrder.fulfillmentCenterId || undefined,
            updatedOrder.logisticsPartnerId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: 'Заказ подтвержден логистической компанией',
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error confirming supply order:', error)
        return {
          success: false,
          message: 'Ошибка при подтверждении заказа логистикой',
        }
      }
    },

    logisticsRejectOrder: async (_: unknown, args: { id: string; reason?: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            logisticsPartnerId: currentUser.organization.id,
            OR: [{ status: 'SUPPLIER_APPROVED' }, { status: 'CONFIRMED' }],
          },
        })

        if (!existingOrder) {
          return {
            success: false,
            message: 'Заказ не найден или недоступен для отклонения логистикой',
          }
        }

        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: 'CANCELLED' },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        try {
          const orgIds = [
            updatedOrder.organizationId,
            updatedOrder.partnerId,
            updatedOrder.fulfillmentCenterId || undefined,
            updatedOrder.logisticsPartnerId || undefined,
          ].filter(Boolean) as string[]
          notifyMany(orgIds, {
            type: 'supply-order:updated',
            payload: { id: updatedOrder.id, status: updatedOrder.status },
          })
        } catch {}

        return {
          success: true,
          message: args.reason
            ? `Заказ отклонен логистической компанией. Причина: ${args.reason}`
            : 'Заказ отклонен логистической компанией',
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error rejecting supply order:', error)
        return {
          success: false,
          message: 'Ошибка при отклонении заказа логистикой',
        }
      }
    },

    fulfillmentReceiveOrder: async (_: unknown, args: { id: string }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      const currentUser = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!currentUser?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      try {
        const existingOrder = await prisma.supplyOrder.findFirst({
          where: {
            id: args.id,
            fulfillmentCenterId: currentUser.organization.id,
            status: 'SHIPPED',
          },
          include: {
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                  },
                },
              },
            },
            organization: true, // Селлер-создатель заказа
            partner: true, // Поставщик
          },
        })

        if (!existingOrder) {
          return {
            success: false,
            message: 'Заказ не найден или недоступен для приема',
          }
        }

        // Обновляем статус заказа
        const updatedOrder = await prisma.supplyOrder.update({
          where: { id: args.id },
          data: { status: 'DELIVERED' },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: {
                  include: {
                    category: true,
                    organization: true,
                  },
                },
              },
            },
          },
        })

        // 🔄 СИНХРОНИЗАЦИЯ СКЛАДА ПОСТАВЩИКА: Обновляем остатки поставщика согласно правилам
        console.warn('🔄 Начинаем синхронизацию остатков поставщика...')
        for (const item of existingOrder.items) {
          const product = await prisma.product.findUnique({
            where: { id: item.product.id },
          })

          if (product) {
            // ИСПРАВЛЕНО: НЕ списываем повторно, только переводим из inTransit в sold
            // Остаток уже был уменьшен при создании/одобрении заказа
            await prisma.product.update({
              where: { id: item.product.id },
              data: {
                // НЕ ТРОГАЕМ stock - он уже правильно уменьшен при заказе
                // Только переводим из inTransit в sold
                inTransit: Math.max((product.inTransit || 0) - item.quantity, 0),
                sold: (product.sold || 0) + item.quantity,
              },
            })
            console.warn(`✅ Товар поставщика "${product.name}" обновлен: получено ${item.quantity} единиц`)
            console.warn(
              `   📊 Остаток: ${product.stock || product.quantity || 0} (НЕ ИЗМЕНЕН - уже списан при заказе)`,
            )
            console.warn(
              `   🚚 В пути: ${product.inTransit || 0} -> ${Math.max(
                (product.inTransit || 0) - item.quantity,
                0,
              )} (УБЫЛО: ${item.quantity})`,
            )
            console.warn(
              `   💰 Продано: ${product.sold || 0} -> ${
                (product.sold || 0) + item.quantity
              } (ПРИБЫЛО: ${item.quantity})`,
            )
          }
        }

        // Обновляем склад фулфилмента с учетом типа расходников
        console.warn('📦 Обновляем склад фулфилмента...')
        console.warn(`🏷️ Тип поставки: ${existingOrder.consumableType || 'FULFILLMENT_CONSUMABLES'}`)

        for (const item of existingOrder.items) {
          // Определяем тип расходников и владельца
          const isSellerSupply = existingOrder.consumableType === 'SELLER_CONSUMABLES'
          const supplyType = isSellerSupply ? 'SELLER_CONSUMABLES' : 'FULFILLMENT_CONSUMABLES'
          const sellerOwnerId = isSellerSupply ? updatedOrder.organization?.id : null

          // Для расходников селлеров ищем по Артикул СФ И по владельцу
          const whereCondition = isSellerSupply
            ? {
                organizationId: currentUser.organization.id,
                article: item.product.article, // ИЗМЕНЕНО: поиск по article вместо name
                type: 'SELLER_CONSUMABLES' as const,
                sellerOwnerId: sellerOwnerId,
              }
            : {
                organizationId: currentUser.organization.id,
                article: item.product.article, // ИЗМЕНЕНО: поиск по article вместо name
                type: 'FULFILLMENT_CONSUMABLES' as const,
              }

          const existingSupply = await prisma.supply.findFirst({
            where: whereCondition,
          })

          if (existingSupply) {
            await prisma.supply.update({
              where: { id: existingSupply.id },
              data: {
                currentStock: existingSupply.currentStock + item.quantity,
                quantity: existingSupply.quantity + item.quantity,
                status: 'in-stock',
              },
            })
            console.warn(
              `📈 Обновлен существующий ${
                isSellerSupply ? 'расходник селлера' : 'расходник фулфилмента'
              } "${item.product.name}" ${
                isSellerSupply ? `(владелец: ${updatedOrder.organization?.name})` : ''
              }: ${existingSupply.currentStock} -> ${existingSupply.currentStock + item.quantity}`,
            )
          } else {
            await prisma.supply.create({
              data: {
                name: item.product.name,
                article: item.product.article, // ДОБАВЛЕНО: Артикул СФ для уникальности
                description: isSellerSupply
                  ? `Расходники селлера ${updatedOrder.organization?.name || updatedOrder.organization?.fullName}`
                  : item.product.description || `Расходники от ${updatedOrder.partner.name}`,
                price: item.price, // Цена закупки у поставщика
                quantity: item.quantity,
                currentStock: item.quantity,
                usedStock: 0,
                unit: 'шт',
                category: item.product.category?.name || 'Расходники',
                status: 'in-stock',
                supplier: updatedOrder.partner.name || updatedOrder.partner.fullName || 'Поставщик',
                type: supplyType as 'SELLER_CONSUMABLES' | 'FULFILLMENT_CONSUMABLES',
                sellerOwnerId: sellerOwnerId,
                organizationId: currentUser.organization.id,
              },
            })
            console.warn(
              `➕ Создан новый ${
                isSellerSupply ? 'расходник селлера' : 'расходник фулфилмента'
              } "${item.product.name}" ${
                isSellerSupply ? `(владелец: ${updatedOrder.organization?.name})` : ''
              }: ${item.quantity} единиц`,
            )
          }
        }

        console.warn('🎉 Синхронизация склада завершена успешно!')

        return {
          success: true,
          message: 'Заказ принят фулфилментом. Склад обновлен. Остатки поставщика синхронизированы.',
          order: updatedOrder,
        }
      } catch (error) {
        console.error('Error receiving supply order:', error)
        return {
          success: false,
          message: 'Ошибка при приеме заказа поставки',
        }
      }
    },

    updateExternalAdClicks: async (_: unknown, { id, clicks }: { id: string; clicks: number }, context: Context) => {
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user.id },
          include: { organization: true },
        })

        if (!user?.organization) {
          throw new GraphQLError('Организация не найдена')
        }

        // Проверяем, что реклама принадлежит организации пользователя
        const existingAd = await prisma.externalAd.findFirst({
          where: {
            id,
            organizationId: user.organization.id,
          },
        })

        if (!existingAd) {
          throw new GraphQLError('Внешняя реклама не найдена')
        }

        await prisma.externalAd.update({
          where: { id },
          data: { clicks },
        })

        return {
          success: true,
          message: 'Клики успешно обновлены',
          externalAd: null,
        }
      } catch (error) {
        console.error('Error updating external ad clicks:', error)
        return {
          success: false,
          message: error instanceof Error ? error.message : 'Ошибка обновления кликов',
          externalAd: null,
        }
      }
    },
  },

  // Резолверы типов
  Organization: {
    users: async (parent: { id: string; users?: unknown[] }) => {
      // Если пользователи уже загружены через include, возвращаем их
      if (parent.users) {
        return parent.users
      }

      // Иначе загружаем отдельно
      return await prisma.user.findMany({
        where: { organizationId: parent.id },
      })
    },
    services: async (parent: { id: string; services?: unknown[] }) => {
      // Если услуги уже загружены через include, возвращаем их
      if (parent.services) {
        return parent.services
      }

      // Иначе загружаем отдельно
      return await prisma.service.findMany({
        where: { organizationId: parent.id },
        include: { organization: true },
        orderBy: { createdAt: 'desc' },
      })
    },
    supplies: async (parent: { id: string; supplies?: unknown[] }) => {
      // Если расходники уже загружены через include, возвращаем их
      if (parent.supplies) {
        return parent.supplies
      }

      // Иначе загружаем отдельно
      return await prisma.supply.findMany({
        where: { organizationId: parent.id },
        include: {
          organization: true,
          sellerOwner: true, // Включаем информацию о селлере-владельце
        },
        orderBy: { createdAt: 'desc' },
      })
    },
  },

  Cart: {
    totalPrice: (parent: { items: Array<{ product: { price: number }; quantity: number }> }) => {
      return parent.items.reduce((total, item) => {
        return total + Number(item.product.price) * item.quantity
      }, 0)
    },
    totalItems: (parent: { items: Array<{ quantity: number }> }) => {
      return parent.items.reduce((total, item) => total + item.quantity, 0)
    },
  },

  CartItem: {
    totalPrice: (parent: { product: { price: number }; quantity: number }) => {
      return Number(parent.product.price) * parent.quantity
    },
    isAvailable: (parent: { product: { quantity: number; isActive: boolean }; quantity: number }) => {
      return parent.product.isActive && parent.product.quantity >= parent.quantity
    },
    availableQuantity: (parent: { product: { quantity: number } }) => {
      return parent.product.quantity
    },
  },

  User: {
    organization: async (parent: { organizationId?: string; organization?: unknown }) => {
      // Если организация уже загружена через include, возвращаем её
      if (parent.organization) {
        return parent.organization
      }

      // Иначе загружаем отдельно если есть organizationId
      if (parent.organizationId) {
        return await prisma.organization.findUnique({
          where: { id: parent.organizationId },
          include: {
            apiKeys: true,
            users: true,
          },
        })
      }

      return null
    },
  },

  Product: {
    type: (parent: { type?: string | null }) => parent.type || 'PRODUCT',
    images: (parent: { images: unknown }) => {
      // Если images это строка JSON, парсим её в массив
      if (typeof parent.images === 'string') {
        try {
          return JSON.parse(parent.images)
        } catch {
          return []
        }
      }
      // Если это уже массив, возвращаем как есть
      if (Array.isArray(parent.images)) {
        return parent.images
      }
      // Иначе возвращаем пустой массив
      return []
    },
  },

  Message: {
    type: (parent: { type?: string | null }) => {
      return parent.type || 'TEXT'
    },
    createdAt: (parent: { createdAt: Date | string }) => {
      if (parent.createdAt instanceof Date) {
        return parent.createdAt.toISOString()
      }
      return parent.createdAt
    },
    updatedAt: (parent: { updatedAt: Date | string }) => {
      if (parent.updatedAt instanceof Date) {
        return parent.updatedAt.toISOString()
      }
      return parent.updatedAt
    },
  },

  Employee: {
    fullName: (parent: { firstName: string; lastName: string; middleName?: string }) => {
      const parts = [parent.lastName, parent.firstName]
      if (parent.middleName) {
        parts.push(parent.middleName)
      }
      return parts.join(' ')
    },
    name: (parent: { firstName: string; lastName: string }) => {
      return `${parent.firstName} ${parent.lastName}`
    },
    birthDate: (parent: { birthDate?: Date | string | null }) => {
      if (!parent.birthDate) return null
      if (parent.birthDate instanceof Date) {
        return parent.birthDate.toISOString()
      }
      return parent.birthDate
    },
    passportDate: (parent: { passportDate?: Date | string | null }) => {
      if (!parent.passportDate) return null
      if (parent.passportDate instanceof Date) {
        return parent.passportDate.toISOString()
      }
      return parent.passportDate
    },
    hireDate: (parent: { hireDate: Date | string }) => {
      if (parent.hireDate instanceof Date) {
        return parent.hireDate.toISOString()
      }
      return parent.hireDate
    },
    createdAt: (parent: { createdAt: Date | string }) => {
      if (parent.createdAt instanceof Date) {
        return parent.createdAt.toISOString()
      }
      return parent.createdAt
    },
    updatedAt: (parent: { updatedAt: Date | string }) => {
      if (parent.updatedAt instanceof Date) {
        return parent.updatedAt.toISOString()
      }
      return parent.updatedAt
    },
  },

  EmployeeSchedule: {
    date: (parent: { date: Date | string }) => {
      if (parent.date instanceof Date) {
        return parent.date.toISOString()
      }
      return parent.date
    },
    createdAt: (parent: { createdAt: Date | string }) => {
      if (parent.createdAt instanceof Date) {
        return parent.createdAt.toISOString()
      }
      return parent.createdAt
    },
    updatedAt: (parent: { updatedAt: Date | string }) => {
      if (parent.updatedAt instanceof Date) {
        return parent.updatedAt.toISOString()
      }
      return parent.updatedAt
    },
    employee: async (parent: { employeeId: string }) => {
      return await prisma.employee.findUnique({
        where: { id: parent.employeeId },
      })
    },
  },
}

// Мутации для категорий
const categoriesMutations = {
  // Создать категорию
  createCategory: async (_: unknown, args: { input: { name: string } }) => {
    try {
      // Проверяем есть ли уже категория с таким именем
      const existingCategory = await prisma.category.findUnique({
        where: { name: args.input.name },
      })

      if (existingCategory) {
        return {
          success: false,
          message: 'Категория с таким названием уже существует',
        }
      }

      const category = await prisma.category.create({
        data: {
          name: args.input.name,
        },
      })

      return {
        success: true,
        message: 'Категория успешно создана',
        category,
      }
    } catch (error) {
      console.error('Ошибка создания категории:', error)
      return {
        success: false,
        message: 'Ошибка при создании категории',
      }
    }
  },

  // Обновить категорию
  updateCategory: async (_: unknown, args: { id: string; input: { name: string } }) => {
    try {
      // Проверяем существует ли категория
      const existingCategory = await prisma.category.findUnique({
        where: { id: args.id },
      })

      if (!existingCategory) {
        return {
          success: false,
          message: 'Категория не найдена',
        }
      }

      // Проверяем не занято ли имя другой категорией
      const duplicateCategory = await prisma.category.findFirst({
        where: {
          name: args.input.name,
          id: { not: args.id },
        },
      })

      if (duplicateCategory) {
        return {
          success: false,
          message: 'Категория с таким названием уже существует',
        }
      }

      const category = await prisma.category.update({
        where: { id: args.id },
        data: {
          name: args.input.name,
        },
      })

      return {
        success: true,
        message: 'Категория успешно обновлена',
        category,
      }
    } catch (error) {
      console.error('Ошибка обновления категории:', error)
      return {
        success: false,
        message: 'Ошибка при обновлении категории',
      }
    }
  },

  // Удалить категорию
  deleteCategory: async (_: unknown, args: { id: string }) => {
    try {
      // Проверяем существует ли категория
      const existingCategory = await prisma.category.findUnique({
        where: { id: args.id },
      })

      if (!existingCategory) {
        throw new GraphQLError('Категория не найдена')
      }

      // Проверяем есть ли товары в этой категории
      const productsCount = await prisma.product.count({
        where: { categoryId: args.id },
      })

      if (productsCount > 0) {
        throw new GraphQLError('Нельзя удалить категорию, в которой есть товары')
      }

      await prisma.category.delete({
        where: { id: args.id },
      })

      return true
    } catch (error) {
      console.error('Ошибка удаления категории:', error)
      if (error instanceof GraphQLError) {
        throw error
      }
      throw new GraphQLError('Ошибка при удалении категории')
    }
  },
}

// Логистические мутации
const logisticsMutations = {
  // Создать логистический маршрут
  createLogistics: async (
    _: unknown,
    args: {
      input: {
        fromLocation: string
        toLocation: string
        priceUnder1m3: number
        priceOver1m3: number
        description?: string
      }
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    const currentUser = await prisma.user.findUnique({
      where: { id: context.user.id },
      include: { organization: true },
    })

    if (!currentUser?.organization) {
      throw new GraphQLError('У пользователя нет организации')
    }

    try {
      const logistics = await prisma.logistics.create({
        data: {
          fromLocation: args.input.fromLocation,
          toLocation: args.input.toLocation,
          priceUnder1m3: args.input.priceUnder1m3,
          priceOver1m3: args.input.priceOver1m3,
          description: args.input.description,
          organizationId: currentUser.organization.id,
        },
        include: {
          organization: true,
        },
      })

      console.warn('✅ Logistics created:', logistics.id)

      return {
        success: true,
        message: 'Логистический маршрут создан',
        logistics,
      }
    } catch (error) {
      console.error('❌ Error creating logistics:', error)
      return {
        success: false,
        message: 'Ошибка при создании логистического маршрута',
      }
    }
  },

  // Обновить логистический маршрут
  updateLogistics: async (
    _: unknown,
    args: {
      id: string
      input: {
        fromLocation: string
        toLocation: string
        priceUnder1m3: number
        priceOver1m3: number
        description?: string
      }
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    const currentUser = await prisma.user.findUnique({
      where: { id: context.user.id },
      include: { organization: true },
    })

    if (!currentUser?.organization) {
      throw new GraphQLError('У пользователя нет организации')
    }

    try {
      // Проверяем, что маршрут принадлежит организации пользователя
      const existingLogistics = await prisma.logistics.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingLogistics) {
        throw new GraphQLError('Логистический маршрут не найден')
      }

      const logistics = await prisma.logistics.update({
        where: { id: args.id },
        data: {
          fromLocation: args.input.fromLocation,
          toLocation: args.input.toLocation,
          priceUnder1m3: args.input.priceUnder1m3,
          priceOver1m3: args.input.priceOver1m3,
          description: args.input.description,
        },
        include: {
          organization: true,
        },
      })

      console.warn('✅ Logistics updated:', logistics.id)

      return {
        success: true,
        message: 'Логистический маршрут обновлен',
        logistics,
      }
    } catch (error) {
      console.error('❌ Error updating logistics:', error)
      return {
        success: false,
        message: 'Ошибка при обновлении логистического маршрута',
      }
    }
  },

  // Удалить логистический маршрут
  deleteLogistics: async (_: unknown, args: { id: string }, context: Context) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    const currentUser = await prisma.user.findUnique({
      where: { id: context.user.id },
      include: { organization: true },
    })

    if (!currentUser?.organization) {
      throw new GraphQLError('У пользователя нет организации')
    }

    try {
      // Проверяем, что маршрут принадлежит организации пользователя
      const existingLogistics = await prisma.logistics.findFirst({
        where: {
          id: args.id,
          organizationId: currentUser.organization.id,
        },
      })

      if (!existingLogistics) {
        throw new GraphQLError('Логистический маршрут не найден')
      }

      await prisma.logistics.delete({
        where: { id: args.id },
      })

      console.warn('✅ Logistics deleted:', args.id)
      return true
    } catch (error) {
      console.error('❌ Error deleting logistics:', error)
      return false
    }
  },
}

// Добавляем дополнительные мутации к основным резолверам
resolvers.Mutation = {
  ...resolvers.Mutation,
  ...categoriesMutations,
  ...logisticsMutations,
}

// Админ резолверы
const adminQueries = {
  adminMe: async (_: unknown, __: unknown, context: Context) => {
    if (!context.admin) {
      throw new GraphQLError('Требуется авторизация администратора', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    const admin = await prisma.admin.findUnique({
      where: { id: context.admin.id },
    })

    if (!admin) {
      throw new GraphQLError('Администратор не найден')
    }

    return admin
  },

  allUsers: async (_: unknown, args: { search?: string; limit?: number; offset?: number }, context: Context) => {
    if (!context.admin) {
      throw new GraphQLError('Требуется авторизация администратора', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    const limit = args.limit || 50
    const offset = args.offset || 0

    // Строим условие поиска
    const whereCondition: Prisma.UserWhereInput = args.search
      ? {
          OR: [
            { phone: { contains: args.search, mode: 'insensitive' } },
            { managerName: { contains: args.search, mode: 'insensitive' } },
            {
              organization: {
                OR: [
                  { name: { contains: args.search, mode: 'insensitive' } },
                  { fullName: { contains: args.search, mode: 'insensitive' } },
                  { inn: { contains: args.search, mode: 'insensitive' } },
                ],
              },
            },
          ],
        }
      : {}

    // Получаем пользователей с пагинацией
    const [users, total] = await Promise.all([
      prisma.user.findMany({
        where: whereCondition,
        include: {
          organization: true,
        },
        take: limit,
        skip: offset,
        orderBy: { createdAt: 'desc' },
      }),
      prisma.user.count({
        where: whereCondition,
      }),
    ])

    return {
      users,
      total,
      hasMore: offset + limit < total,
    }
  },
}

const adminMutations = {
  adminLogin: async (_: unknown, args: { username: string; password: string }) => {
    try {
      // Найти администратора
      const admin = await prisma.admin.findUnique({
        where: { username: args.username },
      })

      if (!admin) {
        return {
          success: false,
          message: 'Неверные учетные данные',
        }
      }

      // Проверить активность
      if (!admin.isActive) {
        return {
          success: false,
          message: 'Аккаунт заблокирован',
        }
      }

      // Проверить пароль
      const isPasswordValid = await bcrypt.compare(args.password, admin.password)

      if (!isPasswordValid) {
        return {
          success: false,
          message: 'Неверные учетные данные',
        }
      }

      // Обновить время последнего входа
      await prisma.admin.update({
        where: { id: admin.id },
        data: { lastLogin: new Date() },
      })

      // Создать токен
      const token = jwt.sign(
        {
          adminId: admin.id,
          username: admin.username,
          type: 'admin',
        },
        process.env.JWT_SECRET!,
        { expiresIn: '24h' },
      )

      return {
        success: true,
        message: 'Успешная авторизация',
        token,
        admin: {
          ...admin,
          password: undefined, // Не возвращаем пароль
        },
      }
    } catch (error) {
      console.error('Admin login error:', error)
      return {
        success: false,
        message: 'Ошибка авторизации',
      }
    }
  },

  adminLogout: async (_: unknown, __: unknown, context: Context) => {
    if (!context.admin) {
      throw new GraphQLError('Требуется авторизация администратора', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    return true
  },
}

// Wildberries статистика
const wildberriesQueries = {
  debugWildberriesAdverts: async (_: unknown, __: unknown, context: Context) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user?.organization || user.organization.type !== 'SELLER') {
        throw new GraphQLError('Доступно только для продавцов')
      }

      const wbApiKeyRecord = user.organization.apiKeys?.find((key) => key.marketplace === 'WILDBERRIES' && key.isActive)

      if (!wbApiKeyRecord) {
        throw new GraphQLError('WB API ключ не настроен')
      }

      const wbService = new WildberriesService(wbApiKeyRecord.apiKey)

      // Получаем кампании во всех статусах
      const [active, completed, paused] = await Promise.all([
        wbService.getAdverts(9).catch(() => []), // активные
        wbService.getAdverts(7).catch(() => []), // завершенные
        wbService.getAdverts(11).catch(() => []), // на паузе
      ])

      const allCampaigns = [...active, ...completed, ...paused]

      return {
        success: true,
        message: `Found ${active.length} active, ${completed.length} completed, ${paused.length} paused campaigns`,
        campaignsCount: allCampaigns.length,
        campaigns: allCampaigns.map((c) => ({
          id: c.advertId,
          name: c.name,
          status: c.status,
          type: c.type,
        })),
      }
    } catch (error) {
      console.error('Error debugging WB adverts:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Unknown error',
        campaignsCount: 0,
        campaigns: [],
      }
    }
  },

  getWildberriesStatistics: async (
    _: unknown,
    {
      period,
      startDate,
      endDate,
    }: {
      period?: 'week' | 'month' | 'quarter'
      startDate?: string
      endDate?: string
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      // Получаем организацию пользователя и её WB API ключ
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      if (user.organization.type !== 'SELLER') {
        throw new GraphQLError('Доступно только для продавцов')
      }

      const wbApiKeyRecord = user.organization.apiKeys?.find((key) => key.marketplace === 'WILDBERRIES' && key.isActive)

      if (!wbApiKeyRecord) {
        throw new GraphQLError('WB API ключ не настроен')
      }

      // Создаем экземпляр сервиса
      const wbService = new WildberriesService(wbApiKeyRecord.apiKey)

      // Получаем даты
      let dateFrom: string
      let dateTo: string

      if (startDate && endDate) {
        // Используем пользовательские даты
        dateFrom = startDate
        dateTo = endDate
      } else if (period) {
        // Используем предустановленный период
        dateFrom = WildberriesService.getDatePeriodAgo(period)
        dateTo = WildberriesService.formatDate(new Date())
      } else {
        throw new GraphQLError('Необходимо указать либо period, либо startDate и endDate')
      }

      // Получаем статистику
      const statistics = await wbService.getStatistics(dateFrom, dateTo)

      return {
        success: true,
        data: statistics,
        message: null,
      }
    } catch (error) {
      console.error('Error fetching WB statistics:', error)
      // Фолбэк: пробуем вернуть последние данные из кеша статистики селлера
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { organization: true },
        })

        if (user?.organization) {
          const whereCache: any = {
            organizationId: user.organization.id,
            period: startDate && endDate ? 'custom' : period ?? 'week',
          }
          if (startDate && endDate) {
            whereCache.dateFrom = new Date(startDate)
            whereCache.dateTo = new Date(endDate)
          }

          const cache = await prisma.sellerStatsCache.findFirst({
            where: whereCache,
            orderBy: { createdAt: 'desc' },
          })

          if (cache?.productsData) {
            // Ожидаем, что productsData — строка JSON с полями, сохраненными клиентом
            const parsed = JSON.parse(cache.productsData as unknown as string) as {
              tableData?: Array<{
                date: string
                salesUnits: number
                orders: number
                advertising: number
                refusals: number
                returns: number
                revenue: number
                buyoutPercentage: number
              }>
            }

            const table = parsed.tableData ?? []
            const dataFromCache = table.map((row) => ({
              date: row.date,
              sales: row.salesUnits,
              orders: row.orders,
              advertising: row.advertising,
              refusals: row.refusals,
              returns: row.returns,
              revenue: row.revenue,
              buyoutPercentage: row.buyoutPercentage,
            }))

            if (dataFromCache.length > 0) {
              return {
                success: true,
                data: dataFromCache,
                message: 'Данные возвращены из кеша из-за ошибки WB API',
              }
            }
          } else if (cache?.advertisingData) {
            // Fallback №2: если нет productsData, но есть advertisingData —
            // формируем минимальный набор данных по дням на основе затрат на рекламу
            try {
              const adv = JSON.parse(cache.advertisingData as unknown as string) as {
                dailyData?: Array<{
                  date: string
                  totalSum?: number
                  totalOrders?: number
                  totalRevenue?: number
                }>
              }

              const daily = adv.dailyData ?? []
              const dataFromAdv = daily.map((d) => ({
                date: d.date,
                sales: 0,
                orders: typeof d.totalOrders === 'number' ? d.totalOrders : 0,
                advertising: typeof d.totalSum === 'number' ? d.totalSum : 0,
                refusals: 0,
                returns: 0,
                revenue: typeof d.totalRevenue === 'number' ? d.totalRevenue : 0,
                buyoutPercentage: 0,
              }))

              if (dataFromAdv.length > 0) {
                return {
                  success: true,
                  data: dataFromAdv,
                  message:
                    'Данные по продажам недоступны из-за ошибки WB API. Показаны данные по рекламе из кеша.',
                }
              }
            } catch (parseErr) {
              console.error('Failed to parse advertisingData from cache:', parseErr)
            }
          }
        }
      } catch (fallbackErr) {
        console.error('Seller stats cache fallback failed:', fallbackErr)
      }

      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка получения статистики',
        data: [],
      }
    }
  },

  getWildberriesCampaignStats: async (
    _: unknown,
    {
      input,
    }: {
      input: {
        campaigns: Array<{
          id: number
          dates?: string[]
          interval?: {
            begin: string
            end: string
          }
        }>
      }
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      // Получаем организацию пользователя и её WB API ключ
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      if (user.organization.type !== 'SELLER') {
        throw new GraphQLError('Доступно только для продавцов')
      }

      const wbApiKeyRecord = user.organization.apiKeys?.find((key) => key.marketplace === 'WILDBERRIES' && key.isActive)

      if (!wbApiKeyRecord) {
        throw new GraphQLError('WB API ключ не настроен')
      }

      // Создаем экземпляр сервиса
      const wbService = new WildberriesService(wbApiKeyRecord.apiKey)

      // Преобразуем запросы в нужный формат
      const requests = input.campaigns.map((campaign) => {
        if (campaign.dates && campaign.dates.length > 0) {
          return {
            id: campaign.id,
            dates: campaign.dates,
          }
        } else if (campaign.interval) {
          return {
            id: campaign.id,
            interval: campaign.interval,
          }
        } else {
          // Если не указаны ни даты, ни интервал, возвращаем данные только за последние сутки
          return {
            id: campaign.id,
          }
        }
      })

      // Получаем статистику кампаний
      const campaignStats = await wbService.getCampaignStats(requests)

      return {
        success: true,
        data: campaignStats,
        message: null,
      }
    } catch (error) {
      console.error('Error fetching WB campaign stats:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка получения статистики кампаний',
        data: [],
      }
    }
  },

  getWildberriesCampaignsList: async (_: unknown, __: unknown, context: Context) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      // Получаем организацию пользователя и её WB API ключ
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: {
            include: {
              apiKeys: true,
            },
          },
        },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      if (user.organization.type !== 'SELLER') {
        throw new GraphQLError('Доступно только для продавцов')
      }

      const wbApiKeyRecord = user.organization.apiKeys?.find((key) => key.marketplace === 'WILDBERRIES' && key.isActive)

      if (!wbApiKeyRecord) {
        throw new GraphQLError('WB API ключ не настроен')
      }

      // Создаем экземпляр сервиса
      const wbService = new WildberriesService(wbApiKeyRecord.apiKey)

      // Получаем список кампаний
      const campaignsList = await wbService.getCampaignsList()

      return {
        success: true,
        data: campaignsList,
        message: null,
      }
    } catch (error) {
      console.error('Error fetching WB campaigns list:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка получения списка кампаний',
        data: {
          adverts: [],
          all: 0,
        },
      }
    }
  },

  // Получение заявок покупателей на возврат от Wildberries от всех партнеров-селлеров
  wbReturnClaims: async (
    _: unknown,
    { isArchive, limit, offset }: { isArchive: boolean; limit?: number; offset?: number },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      // Получаем текущую организацию пользователя (фулфилмент)
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: {
          organization: true,
        },
      })

      if (!user?.organization) {
        throw new GraphQLError('У пользователя нет организации')
      }

      // Проверяем, что это фулфилмент организация
      if (user.organization.type !== 'FULFILLMENT') {
        throw new GraphQLError('Доступ только для фулфилмент организаций')
      }

      // Получаем всех партнеров-селлеров с активными WB API ключами
      const partnerSellerOrgs = await prisma.counterparty.findMany({
        where: {
          organizationId: user.organization.id,
        },
        include: {
          counterparty: {
            include: {
              apiKeys: {
                where: {
                  marketplace: 'WILDBERRIES',
                  isActive: true,
                },
              },
            },
          },
        },
      })

      // Фильтруем только селлеров с WB API ключами
      const sellersWithWbKeys = partnerSellerOrgs.filter(
        (partner) => partner.counterparty.type === 'SELLER' && partner.counterparty.apiKeys.length > 0,
      )

      if (sellersWithWbKeys.length === 0) {
        return {
          claims: [],
          total: 0,
        }
      }

      console.warn(`Found ${sellersWithWbKeys.length} seller partners with WB keys`)

      // Получаем заявки от всех селлеров параллельно
      const claimsPromises = sellersWithWbKeys.map(async (partner) => {
        const wbApiKey = partner.counterparty.apiKeys[0].apiKey
        const wbService = new WildberriesService(wbApiKey)

        try {
          const claimsResponse = await wbService.getClaims({
            isArchive,
            limit: Math.ceil((limit || 50) / sellersWithWbKeys.length), // Распределяем лимит между селлерами
            offset: 0,
          })

          // Добавляем информацию о селлере к каждой заявке
          const claimsWithSeller = claimsResponse.claims.map((claim) => ({
            ...claim,
            sellerOrganization: {
              id: partner.counterparty.id,
              name: partner.counterparty.name || 'Неизвестная организация',
              inn: partner.counterparty.inn || '',
            },
          }))

          console.warn(`Got ${claimsWithSeller.length} claims from seller ${partner.counterparty.name}`)
          return claimsWithSeller
        } catch (error) {
          console.error(`Error fetching claims for seller ${partner.counterparty.name}:`, error)
          return []
        }
      })

      const allClaims = (await Promise.all(claimsPromises)).flat()
      console.warn(`Total claims aggregated: ${allClaims.length}`)

      // Сортируем по дате создания (новые первыми)
      allClaims.sort((a, b) => new Date(b.dt).getTime() - new Date(a.dt).getTime())

      // Применяем пагинацию
      const paginatedClaims = allClaims.slice(offset || 0, (offset || 0) + (limit || 50))
      console.warn(`Paginated claims: ${paginatedClaims.length}`)

      // Преобразуем в формат фронтенда
      const transformedClaims = paginatedClaims.map((claim) => ({
        id: claim.id,
        claimType: claim.claim_type,
        status: claim.status,
        statusEx: claim.status_ex,
        nmId: claim.nm_id,
        userComment: claim.user_comment || '',
        wbComment: claim.wb_comment || null,
        dt: claim.dt,
        imtName: claim.imt_name,
        orderDt: claim.order_dt,
        dtUpdate: claim.dt_update,
        photos: claim.photos || [],
        videoPaths: claim.video_paths || [],
        actions: claim.actions || [],
        price: claim.price,
        currencyCode: claim.currency_code,
        srid: claim.srid,
        sellerOrganization: claim.sellerOrganization,
      }))

      console.warn(`Returning ${transformedClaims.length} transformed claims to frontend`)

      return {
        claims: transformedClaims,
        total: allClaims.length,
      }
    } catch (error) {
      console.error('Error fetching WB return claims:', error)
      throw new GraphQLError(error instanceof Error ? error.message : 'Ошибка получения заявок на возврат')
    }
  },
}

// Резолверы для внешней рекламы
const externalAdQueries = {
  getExternalAds: async (_: unknown, { dateFrom, dateTo }: { dateFrom: string; dateTo: string }, context: Context) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      const externalAds = await prisma.externalAd.findMany({
        where: {
          organizationId: user.organization.id,
          date: {
            gte: new Date(dateFrom),
            lte: new Date(dateTo + 'T23:59:59.999Z'),
          },
        },
        orderBy: {
          date: 'desc',
        },
      })

      return {
        success: true,
        message: null,
        externalAds: externalAds.map((ad) => ({
          ...ad,
          cost: parseFloat(ad.cost.toString()),
          date: ad.date.toISOString().split('T')[0],
          createdAt: ad.createdAt.toISOString(),
          updatedAt: ad.updatedAt.toISOString(),
        })),
      }
    } catch (error) {
      console.error('Error fetching external ads:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка получения внешней рекламы',
        externalAds: [],
      }
    }
  },
}

const externalAdMutations = {
  createExternalAd: async (
    _: unknown,
    {
      input,
    }: {
      input: {
        name: string
        url: string
        cost: number
        date: string
        nmId: string
      }
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      const externalAd = await prisma.externalAd.create({
        data: {
          name: input.name,
          url: input.url,
          cost: input.cost,
          date: new Date(input.date),
          nmId: input.nmId,
          organizationId: user.organization.id,
        },
      })

      return {
        success: true,
        message: 'Внешняя реклама успешно создана',
        externalAd: {
          ...externalAd,
          cost: parseFloat(externalAd.cost.toString()),
          date: externalAd.date.toISOString().split('T')[0],
          createdAt: externalAd.createdAt.toISOString(),
          updatedAt: externalAd.updatedAt.toISOString(),
        },
      }
    } catch (error) {
      console.error('Error creating external ad:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка создания внешней рекламы',
        externalAd: null,
      }
    }
  },

  updateExternalAd: async (
    _: unknown,
    {
      id,
      input,
    }: {
      id: string
      input: {
        name: string
        url: string
        cost: number
        date: string
        nmId: string
      }
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      // Проверяем, что реклама принадлежит организации пользователя
      const existingAd = await prisma.externalAd.findFirst({
        where: {
          id,
          organizationId: user.organization.id,
        },
      })

      if (!existingAd) {
        throw new GraphQLError('Внешняя реклама не найдена')
      }

      const externalAd = await prisma.externalAd.update({
        where: { id },
        data: {
          name: input.name,
          url: input.url,
          cost: input.cost,
          date: new Date(input.date),
          nmId: input.nmId,
        },
      })

      return {
        success: true,
        message: 'Внешняя реклама успешно обновлена',
        externalAd: {
          ...externalAd,
          cost: parseFloat(externalAd.cost.toString()),
          date: externalAd.date.toISOString().split('T')[0],
          createdAt: externalAd.createdAt.toISOString(),
          updatedAt: externalAd.updatedAt.toISOString(),
        },
      }
    } catch (error) {
      console.error('Error updating external ad:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка обновления внешней рекламы',
        externalAd: null,
      }
    }
  },

  deleteExternalAd: async (_: unknown, { id }: { id: string }, context: Context) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      // Проверяем, что реклама принадлежит организации пользователя
      const existingAd = await prisma.externalAd.findFirst({
        where: {
          id,
          organizationId: user.organization.id,
        },
      })

      if (!existingAd) {
        throw new GraphQLError('Внешняя реклама не найдена')
      }

      await prisma.externalAd.delete({
        where: { id },
      })

      return {
        success: true,
        message: 'Внешняя реклама успешно удалена',
        externalAd: null,
      }
    } catch (error) {
      console.error('Error deleting external ad:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка удаления внешней рекламы',
        externalAd: null,
      }
    }
  },
}

// Резолверы для кеша склада WB
const wbWarehouseCacheQueries = {
  getWBWarehouseData: async (_: unknown, __: unknown, context: Context) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      // Получаем текущую дату без времени
      const today = new Date()
      today.setHours(0, 0, 0, 0)

      // Ищем кеш за сегодня
      const cache = await prisma.wBWarehouseCache.findFirst({
        where: {
          organizationId: user.organization.id,
          cacheDate: today,
        },
        orderBy: {
          createdAt: 'desc',
        },
      })

      if (cache) {
        // Возвращаем данные из кеша
        return {
          success: true,
          message: 'Данные получены из кеша',
          cache: {
            ...cache,
            cacheDate: cache.cacheDate.toISOString().split('T')[0],
            createdAt: cache.createdAt.toISOString(),
            updatedAt: cache.updatedAt.toISOString(),
          },
          fromCache: true,
        }
      } else {
        // Кеша нет, нужно загрузить данные из API
        return {
          success: true,
          message: 'Кеш не найден, требуется загрузка из API',
          cache: null,
          fromCache: false,
        }
      }
    } catch (error) {
      console.error('Error getting WB warehouse cache:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка получения кеша склада WB',
        cache: null,
        fromCache: false,
      }
    }
  },
}

const wbWarehouseCacheMutations = {
  saveWBWarehouseCache: async (
    _: unknown,
    {
      input,
    }: {
      input: {
        data: string
        totalProducts: number
        totalStocks: number
        totalReserved: number
      }
    },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      // Получаем текущую дату без времени
      const today = new Date()
      today.setHours(0, 0, 0, 0)

      // Используем upsert для создания или обновления кеша
      const cache = await prisma.wBWarehouseCache.upsert({
        where: {
          organizationId_cacheDate: {
            organizationId: user.organization.id,
            cacheDate: today,
          },
        },
        update: {
          data: input.data,
          totalProducts: input.totalProducts,
          totalStocks: input.totalStocks,
          totalReserved: input.totalReserved,
        },
        create: {
          organizationId: user.organization.id,
          cacheDate: today,
          data: input.data,
          totalProducts: input.totalProducts,
          totalStocks: input.totalStocks,
          totalReserved: input.totalReserved,
        },
      })

      return {
        success: true,
        message: 'Кеш склада WB успешно сохранен',
        cache: {
          ...cache,
          cacheDate: cache.cacheDate.toISOString().split('T')[0],
          createdAt: cache.createdAt.toISOString(),
          updatedAt: cache.updatedAt.toISOString(),
        },
        fromCache: false,
      }
    } catch (error) {
      console.error('Error saving WB warehouse cache:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка сохранения кеша склада WB',
        cache: null,
        fromCache: false,
      }
    }
  },
}

// Добавляем админ запросы и мутации к основным резолверам
resolvers.Query = {
  ...resolvers.Query,
  ...adminQueries,
  ...wildberriesQueries,
  ...externalAdQueries,
  ...wbWarehouseCacheQueries,
  // Кеш статистики селлера
  getSellerStatsCache: async (
    _: unknown,
    args: { period: string; dateFrom?: string | null; dateTo?: string | null },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      const today = new Date()
      today.setHours(0, 0, 0, 0)

      // Для custom учитываем диапазон, иначе только period
      const where: any = {
        organizationId: user.organization.id,
        cacheDate: today,
        period: args.period,
      }
      if (args.period === 'custom') {
        if (!args.dateFrom || !args.dateTo) {
          throw new GraphQLError('Для custom необходимо указать dateFrom и dateTo')
        }
        where.dateFrom = new Date(args.dateFrom)
        where.dateTo = new Date(args.dateTo)
      }

      const cache = await prisma.sellerStatsCache.findFirst({
        where,
        orderBy: { createdAt: 'desc' },
      })

      if (!cache) {
        return {
          success: true,
          message: 'Кеш не найден',
          cache: null,
          fromCache: false,
        }
      }

      // Если кеш просрочен — не используем его, как и для склада WB (сервер решает, годен ли кеш)
      const now = new Date()
      if (cache.expiresAt && cache.expiresAt <= now) {
        return {
          success: true,
          message: 'Кеш устарел, требуется загрузка из API',
          cache: null,
          fromCache: false,
        }
      }

      return {
        success: true,
        message: 'Данные получены из кеша',
        cache: {
          ...cache,
          cacheDate: cache.cacheDate.toISOString().split('T')[0],
          dateFrom: cache.dateFrom ? cache.dateFrom.toISOString().split('T')[0] : null,
          dateTo: cache.dateTo ? cache.dateTo.toISOString().split('T')[0] : null,
          productsTotalSales: cache.productsTotalSales ? Number(cache.productsTotalSales) : null,
          advertisingTotalCost: cache.advertisingTotalCost ? Number(cache.advertisingTotalCost) : null,
          // Возвращаем expiresAt в ISO, чтобы клиент корректно парсил дату
          expiresAt: cache.expiresAt.toISOString(),
          createdAt: cache.createdAt.toISOString(),
          updatedAt: cache.updatedAt.toISOString(),
        },
        fromCache: true,
      }
    } catch (error) {
      console.error('Error getting Seller Stats cache:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка получения кеша статистики',
        cache: null,
        fromCache: false,
      }
    }
  },
}

resolvers.Mutation = {
  ...resolvers.Mutation,
  ...adminMutations,
  ...externalAdMutations,
  ...wbWarehouseCacheMutations,
  // Сохранение кеша статистики селлера
  saveSellerStatsCache: async (
    _: unknown,
    { input }: { input: { period: string; dateFrom?: string | null; dateTo?: string | null; productsData?: string | null; productsTotalSales?: number | null; productsTotalOrders?: number | null; productsCount?: number | null; advertisingData?: string | null; advertisingTotalCost?: number | null; advertisingTotalViews?: number | null; advertisingTotalClicks?: number | null; expiresAt: string } },
    context: Context,
  ) => {
    if (!context.user) {
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }

    try {
      const user = await prisma.user.findUnique({
        where: { id: context.user.id },
        include: { organization: true },
      })

      if (!user?.organization) {
        throw new GraphQLError('Организация не найдена')
      }

      const today = new Date()
      today.setHours(0, 0, 0, 0)

      const data: any = {
        organizationId: user.organization.id,
        cacheDate: today,
        period: input.period,
        dateFrom: input.period === 'custom' && input.dateFrom ? new Date(input.dateFrom) : null,
        dateTo: input.period === 'custom' && input.dateTo ? new Date(input.dateTo) : null,
        productsData: input.productsData ?? null,
        productsTotalSales: input.productsTotalSales ?? null,
        productsTotalOrders: input.productsTotalOrders ?? null,
        productsCount: input.productsCount ?? null,
        advertisingData: input.advertisingData ?? null,
        advertisingTotalCost: input.advertisingTotalCost ?? null,
        advertisingTotalViews: input.advertisingTotalViews ?? null,
        advertisingTotalClicks: input.advertisingTotalClicks ?? null,
        expiresAt: new Date(input.expiresAt),
      }

      // upsert с составным уникальным ключом, содержащим NULL, в Prisma вызывает валидацию.
      // Делаем вручную: findFirst по уникальному набору, затем update или create.
      const existing = await prisma.sellerStatsCache.findFirst({
        where: {
          organizationId: user.organization.id,
          cacheDate: today,
          period: input.period,
          dateFrom: data.dateFrom,
          dateTo: data.dateTo,
        },
      })

      const cache = existing
        ? await prisma.sellerStatsCache.update({ where: { id: existing.id }, data })
        : await prisma.sellerStatsCache.create({ data })

      return {
        success: true,
        message: 'Кеш статистики сохранен',
        cache: {
          ...cache,
          cacheDate: cache.cacheDate.toISOString().split('T')[0],
          dateFrom: cache.dateFrom ? cache.dateFrom.toISOString().split('T')[0] : null,
          dateTo: cache.dateTo ? cache.dateTo.toISOString().split('T')[0] : null,
          productsTotalSales: cache.productsTotalSales ? Number(cache.productsTotalSales) : null,
          advertisingTotalCost: cache.advertisingTotalCost ? Number(cache.advertisingTotalCost) : null,
          createdAt: cache.createdAt.toISOString(),
          updatedAt: cache.updatedAt.toISOString(),
        },
        fromCache: false,
      }
    } catch (error) {
      console.error('Error saving Seller Stats cache:', error)
      return {
        success: false,
        message: error instanceof Error ? error.message : 'Ошибка сохранения кеша статистики',
        cache: null,
        fromCache: false,
      }
    }
  },
}
