import { GraphQLError } from 'graphql'

import { processSellerGoodsSupplyReceipt } from '../../../lib/inventory-management-goods'
import { prisma } from '../../../lib/prisma'
import { notifyOrganization } from '../../../lib/realtime'
import { Context } from '../../context'
import { DomainResolvers } from '../shared/types'

// Seller Goods Domain Resolvers - управление товарными поставками селлеров (мигрировано из goods-supply-v2.ts)

// =============================================================================
// 🔐 AUTHENTICATION HELPERS
// =============================================================================

const withAuth = (resolver: any) => {
  return async (parent: any, args: any, context: Context) => {
    console.log('🔐 SELLER GOODS DOMAIN AUTH CHECK:', { 
      hasUser: !!context.user, 
      userId: context.user?.id,
      organizationId: context.user?.organizationId, 
    })
    if (!context.user) {
      console.error('❌ AUTH FAILED: No user in context')
      throw new GraphQLError('Требуется авторизация', {
        extensions: { code: 'UNAUTHENTICATED' },
      })
    }
    console.log('✅ AUTH PASSED: Calling resolver')
    try {
      const result = await resolver(parent, args, context)
      console.log('🎯 RESOLVER RESULT TYPE:', typeof result, result === null ? 'NULL RESULT!' : 'Has result')
      return result
    } catch (error) {
      console.error('💥 RESOLVER ERROR:', error)
      throw error
    }
  }
}

const checkSellerAccess = async (userId: string) => {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    include: { organization: true },
  })

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

  if (!user.organization || user.organization.type !== 'SELLER') {
    throw new GraphQLError('Доступно только для селлеров', {
      extensions: { code: 'FORBIDDEN' },
    })
  }

  return user
}

const checkFulfillmentAccess = async (userId: string) => {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    include: { organization: true },
  })

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

  if (!user.organization || user.organization.type !== 'FULFILLMENT') {
    throw new GraphQLError('Доступно только для фулфилмента', {
      extensions: { code: 'FORBIDDEN' },
    })
  }

  return user
}

const checkWholesaleAccess = async (userId: string) => {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    include: { organization: true },
  })

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

  if (!user.organization || user.organization.type !== 'WHOLESALE') {
    throw new GraphQLError('Доступно только для поставщиков', {
      extensions: { code: 'FORBIDDEN' },
    })
  }

  return user
}

// =============================================================================
// 🛒 SELLER GOODS DOMAIN RESOLVERS
// =============================================================================

export const sellerGoodsResolvers: DomainResolvers = {
  Query: {
    // Мои товарные поставки (для селлеров - заказы которые я создал)
    mySellerGoodsSupplies: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 MY_SELLER_GOODS_SUPPLIES DOMAIN QUERY STARTED:', { userId: context.user?.id })
      try {
        const user = await checkSellerAccess(context.user!.id)

        const supplies = await prisma.sellerGoodsSupplyOrder.findMany({
          where: {
            sellerId: user.organizationId!,
          },
          include: {
            seller: true,
            fulfillmentCenter: true,
            supplier: true,
            logisticsPartner: true,
            receivedBy: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
          orderBy: {
            createdAt: 'desc',
          },
        })

        console.log('✅ MY_SELLER_GOODS_SUPPLIES DOMAIN SUCCESS:', { count: supplies.length })
        return supplies
      } catch (error) {
        console.error('❌ MY_SELLER_GOODS_SUPPLIES DOMAIN ERROR:', error)
        return []
      }
    }),

    // Входящие товарные заказы от селлеров (для фулфилмента)
    incomingSellerGoodsSupplies: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 INCOMING_SELLER_GOODS_SUPPLIES DOMAIN QUERY STARTED:', { userId: context.user?.id })
      try {
        const user = await checkFulfillmentAccess(context.user!.id)

        const supplies = await prisma.sellerGoodsSupplyOrder.findMany({
          where: {
            fulfillmentCenterId: user.organizationId!,
          },
          include: {
            seller: true,
            fulfillmentCenter: true,
            supplier: true,
            logisticsPartner: true,
            receivedBy: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
          orderBy: {
            createdAt: 'desc',
          },
        })

        console.log('✅ INCOMING_SELLER_GOODS_SUPPLIES DOMAIN SUCCESS:', { count: supplies.length })
        return supplies
      } catch (error) {
        console.error('❌ INCOMING_SELLER_GOODS_SUPPLIES DOMAIN ERROR:', error)
        return []
      }
    }),

    // Товарные заказы от селлеров (для поставщиков)
    mySellerGoodsSupplyRequests: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 MY_SELLER_GOODS_SUPPLY_REQUESTS DOMAIN QUERY STARTED:', { userId: context.user?.id })
      try {
        const user = await checkWholesaleAccess(context.user!.id)

        const supplies = await prisma.sellerGoodsSupplyOrder.findMany({
          where: {
            supplierId: user.organizationId!,
          },
          include: {
            seller: true,
            fulfillmentCenter: true,
            supplier: true,
            logisticsPartner: true,
            receivedBy: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
          orderBy: {
            createdAt: 'desc',
          },
        })

        console.log('✅ MY_SELLER_GOODS_SUPPLY_REQUESTS DOMAIN SUCCESS:', { count: supplies.length })
        return supplies
      } catch (error) {
        console.error('❌ MY_SELLER_GOODS_SUPPLY_REQUESTS DOMAIN ERROR:', error)
        return []
      }
    }),

    // Получение конкретной товарной поставки селлера
    sellerGoodsSupply: withAuth(async (_: unknown, args: { id: string }, context: Context) => {
      console.log('🔍 SELLER_GOODS_SUPPLY DOMAIN QUERY STARTED:', { 
        userId: context.user?.id,
        supplyId: args.id,
      })
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { organization: true },
        })

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

        const supply = await prisma.sellerGoodsSupplyOrder.findUnique({
          where: { id: args.id },
          include: {
            seller: true,
            fulfillmentCenter: true,
            supplier: true,
            logisticsPartner: true,
            receivedBy: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
        })

        if (!supply) {
          throw new GraphQLError('Поставка не найдена')
        }

        // Проверка доступа
        const hasAccess =
          (user.organization.type === 'SELLER' && supply.sellerId === user.organizationId) ||
          (user.organization.type === 'FULFILLMENT' && supply.fulfillmentCenterId === user.organizationId) ||
          (user.organization.type === 'WHOLESALE' && supply.supplierId === user.organizationId) ||
          (user.organization.type === 'LOGIST' && supply.logisticsPartnerId === user.organizationId)

        if (!hasAccess) {
          throw new GraphQLError('Нет доступа к этой поставке')
        }

        console.log('✅ SELLER_GOODS_SUPPLY DOMAIN SUCCESS:', { supplyId: supply.id })
        return supply
      } catch (error) {
        console.error('❌ SELLER_GOODS_SUPPLY DOMAIN ERROR:', error)
        throw error
      }
    }),

    // Инвентарь товаров селлера на складе фулфилмента
    mySellerGoodsInventory: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 MY_SELLER_GOODS_INVENTORY DOMAIN QUERY STARTED:', { userId: context.user?.id })
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { organization: true },
        })

        if (!user?.organization) {
          return []
        }

        let inventoryItems

        if (user.organization.type === 'SELLER') {
          // Селлер видит свои товары на всех складах
          inventoryItems = await prisma.sellerGoodsInventory.findMany({
            where: {
              sellerId: user.organizationId!,
            },
            include: {
              seller: true,
              fulfillmentCenter: true,
              product: true,
            },
            orderBy: {
              lastSupplyDate: 'desc',
            },
          })
        } else if (user.organization.type === 'FULFILLMENT') {
          // Фулфилмент видит все товары на своем складе
          inventoryItems = await prisma.sellerGoodsInventory.findMany({
            where: {
              fulfillmentCenterId: user.organizationId!,
            },
            include: {
              seller: true,
              fulfillmentCenter: true,
              product: true,
            },
            orderBy: {
              lastSupplyDate: 'desc',
            },
          })
        } else {
          return []
        }

        console.log('✅ MY_SELLER_GOODS_INVENTORY DOMAIN SUCCESS:', { count: inventoryItems.length })
        return inventoryItems
      } catch (error) {
        console.error('❌ MY_SELLER_GOODS_INVENTORY DOMAIN ERROR:', error)
        return []
      }
    }),
  },

  Mutation: {
    // Создание поставки товаров селлера
    createSellerGoodsSupply: withAuth(async (_: unknown, args: { input: any }, context: Context) => {
      console.log('🔍 CREATE_SELLER_GOODS_SUPPLY DOMAIN MUTATION STARTED:', { userId: context.user?.id })
      try {
        const user = await checkSellerAccess(context.user!.id)

        const { fulfillmentCenterId, supplierId, logisticsPartnerId, requestedDeliveryDate, notes, recipeItems } = args.input

        // 🔍 ВАЛИДАЦИЯ ПАРТНЕРОВ
        const fulfillmentCenter = await prisma.organization.findUnique({
          where: { id: fulfillmentCenterId },
          include: {
            counterpartyOf: {
              where: { organizationId: user.organizationId! },
            },
          },
        })

        if (!fulfillmentCenter || fulfillmentCenter.type !== 'FULFILLMENT') {
          throw new GraphQLError('Фулфилмент-центр не найден или имеет неверный тип')
        }

        if (fulfillmentCenter.counterpartyOf.length === 0) {
          throw new GraphQLError('Нет партнерских отношений с данным фулфилмент-центром')
        }

        const supplier = await prisma.organization.findUnique({
          where: { id: supplierId },
          include: {
            counterpartyOf: {
              where: { organizationId: user.organizationId! },
            },
          },
        })

        if (!supplier || supplier.type !== 'WHOLESALE') {
          throw new GraphQLError('Поставщик не найден или имеет неверный тип')
        }

        if (supplier.counterpartyOf.length === 0) {
          throw new GraphQLError('Нет партнерских отношений с данным поставщиком')
        }

        // 🔍 ВАЛИДАЦИЯ ТОВАРОВ И ОСТАТКОВ
        let totalCost = 0
        const mainProducts = recipeItems.filter((item: any) => item.recipeType === 'MAIN_PRODUCT')

        if (mainProducts.length === 0) {
          throw new GraphQLError('Должен быть хотя бы один основной товар')
        }

        // Проверяем только основные товары (MAIN_PRODUCT) в рецептуре
        for (const item of recipeItems) {
          // В V2 временно валидируем только основные товары
          if (item.recipeType !== 'MAIN_PRODUCT') {
            console.log(`⚠️ Пропускаем валидацию ${item.recipeType} товара ${item.productId} - не поддерживается в V2`)
            continue
          }

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

          if (!product) {
            throw new GraphQLError(`Товар с ID ${item.productId} не найден`)
          }

          if (product.organizationId !== supplierId) {
            throw new GraphQLError(`Товар ${product.name} не принадлежит выбранному поставщику`)
          }

          // Проверяем остатки основных товаров
          const availableStock = (product.stock || product.quantity || 0) - (product.ordered || 0)

          if (item.quantity > availableStock) {
            throw new GraphQLError(
              `Недостаточно остатков товара "${product.name}". ` +
              `Доступно: ${availableStock} шт., запрашивается: ${item.quantity} шт.`,
            )
          }

          totalCost += product.price.toNumber() * item.quantity
        }

        // 🚀 СОЗДАНИЕ ПОСТАВКИ В ТРАНЗАКЦИИ
        const supplyOrder = await prisma.$transaction(async (tx) => {
          // Создаем заказ поставки
          const newOrder = await tx.sellerGoodsSupplyOrder.create({
            data: {
              sellerId: user.organizationId!,
              fulfillmentCenterId,
              supplierId,
              logisticsPartnerId,
              requestedDeliveryDate: new Date(requestedDeliveryDate),
              notes,
              status: 'PENDING',
              totalCostWithDelivery: totalCost,
            },
          })

          // Создаем записи рецептуры только для MAIN_PRODUCT
          for (const item of recipeItems) {
            // В V2 временно создаем только основные товары
            if (item.recipeType !== 'MAIN_PRODUCT') {
              console.log(`⚠️ Пропускаем создание записи для ${item.recipeType} товара ${item.productId}`)
              continue
            }

            await tx.goodsSupplyRecipeItem.create({
              data: {
                supplyOrderId: newOrder.id,
                productId: item.productId,
                quantity: item.quantity,
                recipeType: item.recipeType,
              },
            })

            // Резервируем основные товары у поставщика
            await tx.product.update({
              where: { id: item.productId },
              data: {
                ordered: {
                  increment: item.quantity,
                },
              },
            })
          }

          return newOrder
        })

        // 📨 УВЕДОМЛЕНИЯ
        await notifyOrganization(
          supplierId, 
          `Новый заказ товаров от селлера ${user.organization!.name}`, 
          'GOODS_SUPPLY_ORDER_CREATED',
          { orderId: supplyOrder.id },
        )

        await notifyOrganization(
          fulfillmentCenterId,
          `Селлер ${user.organization!.name} оформил поставку товаров на ваш склад`,
          'INCOMING_GOODS_SUPPLY_ORDER',
          { orderId: supplyOrder.id },
        )

        // Получаем созданную поставку с полными данными
        const createdSupply = await prisma.sellerGoodsSupplyOrder.findUnique({
          where: { id: supplyOrder.id },
          include: {
            seller: true,
            fulfillmentCenter: true,
            supplier: true,
            logisticsPartner: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
        })

        const result = {
          success: true,
          message: 'Поставка товаров успешно создана',
          supplyOrder: createdSupply,
        }
        console.log('✅ CREATE_SELLER_GOODS_SUPPLY DOMAIN SUCCESS:', { supplyOrderId: supplyOrder.id })
        return result
      } catch (error: any) {
        console.error('❌ CREATE_SELLER_GOODS_SUPPLY DOMAIN ERROR:', error)
        
        if (error instanceof GraphQLError) {
          throw error
        }
        
        throw new GraphQLError('Ошибка создания товарной поставки')
      }
    }),

    // Обновление статуса товарной поставки
    updateSellerGoodsSupplyStatus: withAuth(async (
      _: unknown,
      args: { id: string; status: string; notes?: string },
      context: Context,
    ) => {
      console.log('🔍 UPDATE_SELLER_GOODS_SUPPLY_STATUS DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        supplyId: args.id,
        status: args.status,
      })
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { organization: true },
        })

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

        const supply = await prisma.sellerGoodsSupplyOrder.findUnique({
          where: { id: args.id },
          include: {
            seller: true,
            supplier: true,
            fulfillmentCenter: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
        })

        if (!supply) {
          throw new GraphQLError('Поставка не найдена')
        }

        // 🔐 ПРОВЕРКА ПРАВ И ЛОГИКИ ПЕРЕХОДОВ СТАТУСОВ
        const { status } = args
        const currentStatus = supply.status
        const orgType = user.organization.type

        // Только поставщики могут переводить PENDING → APPROVED
        if (status === 'APPROVED' && currentStatus === 'PENDING') {
          if (orgType !== 'WHOLESALE' || supply.supplierId !== user.organizationId) {
            throw new GraphQLError('Только поставщик может одобрить заказ')
          }
        }
        // Только поставщики могут переводить APPROVED → SHIPPED
        else if (status === 'SHIPPED' && currentStatus === 'APPROVED') {
          if (orgType !== 'WHOLESALE' || supply.supplierId !== user.organizationId) {
            throw new GraphQLError('Только поставщик может отметить отгрузку')
          }
        }
        // Только фулфилмент может переводить SHIPPED → DELIVERED
        else if (status === 'DELIVERED' && currentStatus === 'SHIPPED') {
          if (orgType !== 'FULFILLMENT' || supply.fulfillmentCenterId !== user.organizationId) {
            throw new GraphQLError('Только фулфилмент-центр может подтвердить получение')
          }
        }
        // Только фулфилмент может переводить DELIVERED → COMPLETED
        else if (status === 'COMPLETED' && currentStatus === 'DELIVERED') {
          if (orgType !== 'FULFILLMENT' || supply.fulfillmentCenterId !== user.organizationId) {
            throw new GraphQLError('Только фулфилмент-центр может завершить поставку')
          }
        } else {
          throw new GraphQLError('Недопустимый переход статуса')
        }

        // 📅 ОБНОВЛЕНИЕ ВРЕМЕННЫХ МЕТОК
        const updateData: any = {
          status,
          updatedAt: new Date(),
        }

        if (status === 'APPROVED' && orgType === 'WHOLESALE') {
          updateData.supplierApprovedAt = new Date()
          updateData.supplierNotes = args.notes
        }

        if (status === 'SHIPPED' && orgType === 'WHOLESALE') {
          updateData.shippedAt = new Date()
        }

        if (status === 'DELIVERED' && orgType === 'FULFILLMENT') {
          updateData.deliveredAt = new Date()
          updateData.receivedById = user.id
          updateData.receiptNotes = args.notes
        }

        // 🔄 ОБНОВЛЕНИЕ В БАЗЕ
        const updatedSupply = await prisma.sellerGoodsSupplyOrder.update({
          where: { id: args.id },
          data: updateData,
          include: {
            seller: true,
            fulfillmentCenter: true,
            supplier: true,
            logisticsPartner: true,
            receivedBy: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
        })

        // 📨 УВЕДОМЛЕНИЯ О СМЕНЕ СТАТУСА
        if (status === 'APPROVED') {
          await notifyOrganization(
            supply.sellerId,
            `Поставка товаров одобрена поставщиком ${user.organization.name}`,
            'GOODS_SUPPLY_APPROVED',
            { orderId: args.id },
          )
        }

        if (status === 'SHIPPED') {
          await notifyOrganization(
            supply.sellerId,
            `Поставка товаров отгружена поставщиком ${user.organization.name}`,
            'GOODS_SUPPLY_SHIPPED',
            { orderId: args.id },
          )

          await notifyOrganization(
            supply.fulfillmentCenterId,
            'Поставка товаров в пути. Ожидается доставка',
            'GOODS_SUPPLY_IN_TRANSIT',
            { orderId: args.id },
          )
        }

        if (status === 'DELIVERED') {
          // 📦 АВТОМАТИЧЕСКОЕ СОЗДАНИЕ/ОБНОВЛЕНИЕ ИНВЕНТАРЯ V2
          await processSellerGoodsSupplyReceipt(args.id)
          
          await notifyOrganization(
            supply.sellerId,
            `Поставка товаров доставлена в ${supply.fulfillmentCenter.name}`,
            'GOODS_SUPPLY_DELIVERED',
            { orderId: args.id },
          )
        }

        if (status === 'COMPLETED') {
          await notifyOrganization(
            supply.sellerId,
            `Поставка товаров завершена. Товары размещены на складе ${supply.fulfillmentCenter.name}`,
            'GOODS_SUPPLY_COMPLETED',
            { orderId: args.id },
          )
        }

        console.log('✅ UPDATE_SELLER_GOODS_SUPPLY_STATUS DOMAIN SUCCESS:', { 
          supplyId: updatedSupply.id,
          newStatus: status,
        })
        return updatedSupply
      } catch (error: any) {
        console.error('❌ UPDATE_SELLER_GOODS_SUPPLY_STATUS DOMAIN ERROR:', error)

        if (error instanceof GraphQLError) {
          throw error
        }

        throw new GraphQLError('Ошибка обновления статуса товарной поставки')
      }
    }),

    // Отмена товарной поставки селлером
    cancelSellerGoodsSupply: withAuth(async (_: unknown, args: { id: string }, context: Context) => {
      console.log('🔍 CANCEL_SELLER_GOODS_SUPPLY DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        supplyId: args.id,
      })
      try {
        const user = await checkSellerAccess(context.user!.id)

        const supply = await prisma.sellerGoodsSupplyOrder.findUnique({
          where: { id: args.id },
          include: {
            seller: true,
            recipeItems: {
              include: {
                product: true,
              },
            },
          },
        })

        if (!supply) {
          throw new GraphQLError('Поставка не найдена')
        }

        if (supply.sellerId !== user.organizationId) {
          throw new GraphQLError('Вы можете отменить только свои поставки')
        }

        // ✅ ПРОВЕРКА ВОЗМОЖНОСТИ ОТМЕНЫ (только PENDING и APPROVED)
        if (!['PENDING', 'APPROVED'].includes(supply.status)) {
          throw new GraphQLError('Поставку можно отменить только в статусе PENDING или APPROVED')
        }

        // 🔄 ОТМЕНА В ТРАНЗАКЦИИ
        const cancelledSupply = await prisma.$transaction(async (tx) => {
          // Обновляем статус
          const updated = await tx.sellerGoodsSupplyOrder.update({
            where: { id: args.id },
            data: {
              status: 'CANCELLED',
              updatedAt: new Date(),
            },
            include: {
              seller: true,
              fulfillmentCenter: true,
              supplier: true,
              recipeItems: {
                include: {
                  product: true,
                },
              },
            },
          })

          // Освобождаем зарезервированные товары у поставщика (только MAIN_PRODUCT)
          for (const item of supply.recipeItems) {
            if (item.recipeType === 'MAIN_PRODUCT') {
              await tx.product.update({
                where: { id: item.productId },
                data: {
                  ordered: {
                    decrement: item.quantity,
                  },
                },
              })
            }
          }

          return updated
        })

        // 📨 УВЕДОМЛЕНИЯ ОБ ОТМЕНЕ
        if (supply.supplierId) {
          await notifyOrganization(
            supply.supplierId,
            `Селлер ${user.organization!.name} отменил заказ товаров`,
            'GOODS_SUPPLY_CANCELLED',
            { orderId: args.id },
          )
        }

        await notifyOrganization(
          supply.fulfillmentCenterId,
          `Селлер ${user.organization!.name} отменил поставку товаров`,
          'GOODS_SUPPLY_CANCELLED',
          { orderId: args.id },
        )

        console.log('✅ CANCEL_SELLER_GOODS_SUPPLY DOMAIN SUCCESS:', { supplyId: args.id })
        return cancelledSupply
      } catch (error: any) {
        console.error('❌ CANCEL_SELLER_GOODS_SUPPLY DOMAIN ERROR:', error)

        if (error instanceof GraphQLError) {
          throw error
        }

        throw new GraphQLError('Ошибка отмены товарной поставки')
      }
    }),
  },
}

console.warn('🔥 SELLER GOODS DOMAIN МОДУЛЬ ЭКСПОРТЫ ГОТОВЫ')