import { GraphQLError } from 'graphql'

import { prisma } from '../../../lib/prisma'
import { Context } from '../../context'
import { getCurrentUser, requireWholesaleAccess, withOrgTypeAuth } from '../shared/auth-utils'
import { DomainResolvers } from '../shared/types'

// Products Domain Resolvers - изолированная логика товаров и расходников
export const productsResolvers: DomainResolvers = {
  Query: {
    // Товары поставщика - ОПТИМИЗИРОВАНО
    myProducts: withOrgTypeAuth(['WHOLESALE'], async (_: unknown, __: unknown, context: Context, user: any) => {
      const products = await prisma.product.findMany({
        where: {
          organizationId: user.organizationId,
        },
        select: {
          id: true,
          name: true,
          article: true,
          description: true,
          type: true,
          isActive: true,
          price: true,
          pricePerSet: true,
          quantity: true,
          setQuantity: true,
          ordered: true,
          inTransit: true,
          stock: true,
          sold: true,
          brand: true,
          color: true,
          size: true,
          weight: true,
          dimensions: true,
          material: true,
          images: true,
          mainImage: true,
          createdAt: true,
          updatedAt: true,
          // Оптимизированные select для связанных объектов
          category: {
            select: { id: true, name: true },
          },
          organization: {
            select: { id: true, name: true, type: true, market: true },
          },
        },
        orderBy: { createdAt: 'desc' },
        take: 200, // Добавляем лимит для производительности
      })

      console.warn('🔥 MY_PRODUCTS RESOLVER DEBUG:', {
        userId: user.id,
        organizationId: user.organizationId,
        organizationType: user.organization.type,
        organizationName: user.organization.name,
        totalProducts: products.length,
      })

      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
    },
  },

  Mutation: {
    // Создать товар
    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,
        }
      }
    },

    // Удаление товара
    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
      }
    },
  },

  // Type resolvers для Product
  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 []
    },
  },
}