import { GraphQLError } from 'graphql'

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

// Supply Orders Domain Resolvers - изолированная логика заказов поставок
export const supplyOrdersResolvers: DomainResolvers = {
  Query: {
    // Мои заказы поставок
    mySupplyOrders: async (_: unknown, __: unknown, context: Context) => {
      const currentUser = await getCurrentUser(context)

      console.warn('🔍 GET MY SUPPLY ORDERS:', {
        userId: currentUser.id,
        organizationType: currentUser.organization.type,
        organizationId: currentUser.organization.id,
      })

      // Определяем логику фильтрации в зависимости от типа организации
      let whereClause
      if (currentUser.organization.type === 'WHOLESALE') {
        // Поставщик видит заказы, где он является поставщиком (partnerId)
        whereClause = {
          partnerId: currentUser.organization.id,
        }
      } else {
        // Остальные (SELLER, FULFILLMENT) видят заказы, которые они создали (organizationId)
        whereClause = {
          organizationId: currentUser.organization.id,
        }
      }

      const supplyOrders = await prisma.supplyOrder.findMany({
        where: whereClause,
        select: {
          id: true,
          status: true,
          totalAmount: true,
          deliveryDate: true,
          createdAt: true,
          updatedAt: true,
          notes: true,
          consumableType: true,
          packagesCount: true,
          volume: true,
          partner: {
            select: { id: true, name: true, type: true },
          },
          organization: {
            select: { id: true, name: true, type: true },
          },
          fulfillmentCenter: {
            select: { id: true, name: true, type: true },
          },
          logisticsPartner: {
            select: { id: true, name: true, type: true },
          },
          items: {
            select: {
              id: true,
              quantity: true,
              price: true,
              total: true,
              product: {
                select: {
                  id: true,
                  name: true,
                  price: true,
                  category: {
                    select: { id: true, name: true },
                  },
                },
              },
            },
            orderBy: {
              createdAt: 'asc',
            },
          },
        },
        orderBy: {
          createdAt: 'desc',
        },
        take: 100, // Добавляем пагинацию
      })

      console.warn('📦 Найдено поставок:', supplyOrders.length, {
        organizationType: currentUser.organization.type,
        filterType: currentUser.organization.type === 'WHOLESALE' ? 'partnerId' : 'organizationId',
        organizationId: currentUser.organization.id,
      })

      return supplyOrders
    },

    // Количество ожидающих поставок
    pendingSuppliesCount: async (_: unknown, __: unknown, context: Context) => {
      const currentUser = await getCurrentUser(context)

      // Считаем заказы поставок, требующие действий
      
      // Расходники фулфилмента (созданные нами для себя) - требуют действий по статусам
      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: 'LOGISTICS_CONFIRMED', // Требует действий логистики
        },
      })

      // Считаем общее количество задач
      const totalPending = ourSupplyOrders + sellerSupplyOrders + incomingSupplierOrders + logisticsOrders

      console.warn('📊 PENDING SUPPLIES COUNT:', {
        userId: currentUser.id,
        organizationType: currentUser.organization.type,
        ourSupplyOrders,
        sellerSupplyOrders,
        incomingSupplierOrders,
        logisticsOrders,
        totalPending,
      })

      return {
        supplyOrders: totalPending,
        ourSupplyOrders,
        sellerSupplyOrders,
        incomingSupplierOrders,
        logisticsOrders,
        incomingRequests: incomingSupplierOrders, // Алиас для совместимости со schema
        total: totalPending, // Общий счетчик
      }
    },
  },

  Mutation: {
    // Создание заказа поставки
    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 // Классификация расходников
          // Новые поля для многоуровневой системы
          packagesCount?: number // Количество грузовых мест (заполняет поставщик)
          volume?: number // Объём товара в м³ (заполняет поставщик)
          routes?: Array<{
            logisticsId?: string // Ссылка на предустановленный маршрут
            fromLocation: string // Точка забора
            toLocation: string // Точка доставки
            fromAddress?: string // Полный адрес забора
            toAddress?: string // Полный адрес доставки
          }>
        }
      },
      context: Context,
    ) => {
      console.warn('🚀 CREATE_SUPPLY_ORDER RESOLVER - ВЫЗВАН:', {
        hasUser: !!context.user,
        userId: context.user?.id,
        inputData: args.input,
        timestamp: new Date().toISOString(),
      })

      const currentUser = await getCurrentUser(context)

      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
      }

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

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

        // Подсчитываем общую стоимость заказа - ОПТИМИЗИРОВАННО: один запрос вместо N
        const productIds = args.input.items.map(item => item.productId)
        const products = await prisma.product.findMany({
          where: { 
            id: { in: productIds },
            organizationId: args.input.partnerId, // Сразу фильтруем по поставщику
          },
          select: {
            id: true,
            name: true,
            price: true,
            organizationId: true,
          },
        })

        // Проверяем, что все товары найдены
        if (products.length !== args.input.items.length) {
          const foundProductIds = products.map(p => p.id)
          const missingProducts = args.input.items.filter(item => !foundProductIds.includes(item.productId))
          return {
            success: false,
            message: `Товары не найдены или не принадлежат поставщику: ${missingProducts.map(p => p.productId).join(', ')}`,
          }
        }

        // Создаем мапу продуктов для быстрого доступа
        const productMap = new Map(products.map(p => [p.id, p]))
        
        let totalAmount = 0
        const orderItems = []

        for (const item of args.input.items) {
          const product = productMap.get(item.productId)!
          const itemTotal = product.price * item.quantity
          totalAmount += itemTotal

          orderItems.push({
            productId: item.productId,
            quantity: item.quantity,
            price: product.price,
            total: itemTotal,
            services: item.recipe?.services ? JSON.stringify(item.recipe.services) : null,
            fulfillmentConsumables: item.recipe?.fulfillmentConsumables ? JSON.stringify(item.recipe.fulfillmentConsumables) : null,
            sellerConsumables: item.recipe?.sellerConsumables ? JSON.stringify(item.recipe.sellerConsumables) : null,
            marketplaceCardId: item.recipe?.marketplaceCardId || null,
          })
        }

        // Создаем заказ поставки
        const supplyOrder = await prisma.supplyOrder.create({
          data: {
            organizationId: currentUser.organization.id, // Кто создал заказ
            partnerId: args.input.partnerId, // Поставщик
            fulfillmentCenterId: fulfillmentCenterId || null, // Получатель
            logisticsPartnerId: args.input.logisticsPartnerId || null, // Логистическая компания
            deliveryDate: new Date(args.input.deliveryDate),
            status: 'PENDING', // Начальный статус
            totalAmount,
            notes: args.input.notes,
            consumableType: args.input.consumableType,
            packagesCount: args.input.packagesCount,
            volume: args.input.volume,
            routes: args.input.routes ? JSON.stringify(args.input.routes) : null,
            items: {
              create: orderItems,
            },
          },
          include: {
            partner: true,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
            items: {
              include: {
                product: true,
              },
            },
          },
        })

        console.warn('✅ ЗАКАЗ ПОСТАВКИ СОЗДАН:', {
          orderId: supplyOrder.id,
          organizationId: currentUser.organization.id,
          partnerId: args.input.partnerId,
          totalAmount,
          itemsCount: orderItems.length,
          status: supplyOrder.status,
        })

        return {
          success: true,
          message: 'Заказ поставки успешно создан',
          supplyOrder,
        }
      } catch (error) {
        console.error('Error creating supply order:', 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}`)
      const currentUser = await getCurrentUser(context)

      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,
            organization: true,
            fulfillmentCenter: true,
            logisticsPartner: true,
          },
        })

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

        // Проверяем валидность перехода статуса
        const validTransitions: Record<string, string[]> = {
          PENDING: ['SUPPLIER_APPROVED', 'CANCELLED'],
          SUPPLIER_APPROVED: ['LOGISTICS_CONFIRMED', 'CANCELLED'],
          LOGISTICS_CONFIRMED: ['IN_TRANSIT', 'CANCELLED'],
          IN_TRANSIT: ['DELIVERED', 'CANCELLED'],
          DELIVERED: [], // Финальный статус
          CANCELLED: [], // Финальный статус
        }

        const currentStatus = existingOrder.status
        if (!validTransitions[currentStatus]?.includes(args.status)) {
          return {
            success: false,
            message: `Нельзя изменить статус с "${currentStatus}" на "${args.status}"`,
          }
        }

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

        console.warn('✅ СТАТУС ЗАКАЗА ОБНОВЛЕН:', {
          orderId: args.id,
          oldStatus: currentStatus,
          newStatus: args.status,
          organizationId: currentUser.organization.id,
          organizationType: currentUser.organization.type,
        })

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