import { GraphQLError } from 'graphql'

import { prisma } from '../../../lib/prisma'
import { Context } from '../../context'
import { DomainResolvers } from '../shared/types'

// Analytics Domain Resolvers - управление аналитикой и статистикой

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

const withAuth = (resolver: any) => {
  return async (parent: any, args: any, context: Context) => {
    console.log('🔐 ANALYTICS 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
    }
  }
}

// =============================================================================
// 📊 ANALYTICS DOMAIN RESOLVERS
// =============================================================================

export const analyticsResolvers: DomainResolvers = {
  Query: {
    // Статистика склада фулфилмента с изменениями за сутки (V2 - только модульные модели)
    fulfillmentWarehouseStats: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 FULFILLMENT_WAREHOUSE_STATS V2 DOMAIN QUERY STARTED:', { userId: context.user?.id })
      
      try {
        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

        // Временные периоды для анализа изменений
        const yesterday = new Date()
        yesterday.setDate(yesterday.getDate() - 1)
        yesterday.setHours(0, 0, 0, 0)

        const today = new Date()
        today.setHours(0, 0, 0, 0)

        console.log('📊 Calculating V2 warehouse stats:', {
          organizationId,
          yesterday: yesterday.toISOString(),
          today: today.toISOString(),
        })

        // =============================================================================
        // 📦 V2 МОДЕЛЬ: FulfillmentConsumableInventory - расходники на складе ФФ
        // =============================================================================
        
        const [consumableInventory, consumableLowStock, yesterdayConsumableStock] = await Promise.all([
          // Текущий остаток расходников
          prisma.fulfillmentConsumableInventory.aggregate({
            where: { fulfillmentCenterId: organizationId },
            _sum: { currentStock: true },
            _count: true,
          }),
          
          // Расходники с низким остатком
          prisma.fulfillmentConsumableInventory.count({
            where: { 
              fulfillmentCenterId: organizationId,
              OR: [
                { currentStock: { lte: 10 } }, // Критический остаток
                // TODO: Добавить поле minStock в схему для точного расчета
              ],
            },
          }),

          // Вчерашний остаток расходников (для расчета изменений)
          prisma.fulfillmentConsumableInventory.aggregate({
            where: { 
              fulfillmentCenterId: organizationId,
              updatedAt: { gte: yesterday, lt: today },
            },
            _sum: { currentStock: true },
          }),
        ])

        // =============================================================================
        // 📋 V2 МОДЕЛЬ: FulfillmentConsumableSupplyOrder - заказы расходников
        // =============================================================================

        const [recentSupplyOrders, pendingSupplyOrders, todaySupplyOrders] = await Promise.all([
          // Недавние заказы расходников (за сутки)
          prisma.fulfillmentConsumableSupplyOrder.count({
            where: { 
              fulfillmentCenterId: organizationId,
              createdAt: { gte: yesterday },
            },
          }),
          
          // Ожидающие заказы расходников
          prisma.fulfillmentConsumableSupplyOrder.count({
            where: { 
              fulfillmentCenterId: organizationId,
              status: 'PENDING',
            },
          }),

          // Заказы расходников за сегодня
          prisma.fulfillmentConsumableSupplyOrder.count({
            where: { 
              fulfillmentCenterId: organizationId,
              createdAt: { gte: today },
            },
          }),
        ])

        // =============================================================================
        // 📦 V2 МОДЕЛЬ: SellerGoodsInventory - товары селлеров на складе ФФ
        // =============================================================================

        const [sellerGoodsInventory] = await Promise.all([
          // Товары селлеров на складе ФФ
          prisma.sellerGoodsInventory.aggregate({
            where: { 
              fulfillmentCenterId: organizationId, // товары хранятся у этого ФФ
            },
            _sum: { currentStock: true },
            _count: true,
          }),
        ])

        // =============================================================================
        // 🧮 РАСЧЕТ ИЗМЕНЕНИЙ ЗА СУТКИ
        // =============================================================================

        const consumableStockChange = (consumableInventory._sum.currentStock || 0) - (yesterdayConsumableStock._sum.currentStock || 0)
        const supplyOrdersChange = todaySupplyOrders

        // =============================================================================
        // 📊 ФОРМИРОВАНИЕ СТАТИСТИКИ ПО СПЕЦИФИКАЦИИ GraphQL
        // =============================================================================

        const warehouseStats = {
          // Товары (Products) - расходники на складе ФФ
          products: {
            current: consumableInventory._sum.currentStock || 0,
            change: consumableStockChange,
            percentChange: (yesterdayConsumableStock._sum.currentStock || 0) > 0 
              ? (consumableStockChange / (yesterdayConsumableStock._sum.currentStock || 1)) * 100 
              : 0,
          },
          
          // Товары селлеров (Goods) - готовая продукция на складе ФФ
          goods: {
            current: sellerGoodsInventory._sum.currentStock || 0,
            change: 0, // TODO: добавить расчет изменений товаров за сутки
            percentChange: 0,
          },
          
          // Дефекты (пока заглушка - в V2 системе пока нет отдельной модели дефектов)
          defects: {
            current: 0,
            change: 0,
            percentChange: 0,
          },
          
          // Возвраты с ПВЗ (пока заглушка - в V2 системе пока нет модели возвратов)
          pvzReturns: {
            current: 0,
            change: 0,
            percentChange: 0,
          },
          
          // Поставки расходников фулфилменту
          fulfillmentSupplies: {
            current: recentSupplyOrders,
            change: supplyOrdersChange,
            percentChange: recentSupplyOrders > 0 ? (supplyOrdersChange / recentSupplyOrders) * 100 : 0,
          },
          
          // Расходники селлеров (низкий остаток = требует внимания)
          sellerSupplies: {
            current: consumableLowStock,
            change: 0, // TODO: добавить расчет изменения критических остатков
            percentChange: 0,
          },
        }

        console.log('✅ FULFILLMENT_WAREHOUSE_STATS V2 DOMAIN SUCCESS:', {
          consumableStock: consumableInventory._sum.currentStock,
          sellerGoodsStock: sellerGoodsInventory._sum.currentStock,
          pendingOrders: pendingSupplyOrders,
          lowStockItems: consumableLowStock,
          migration: 'V2_MODELS_ONLY',
        })

        return warehouseStats
      } catch (error) {
        console.error('❌ FULFILLMENT_WAREHOUSE_STATS V2 DOMAIN ERROR:', error)
        throw error
      }
    }),

    // УДАЛЕН: myReferralStats перемещен в referrals.ts для устранения конфликта resolver'ов

    // УДАЛЕН: getAvailableSuppliesForRecipe - неиспользуемый стаб резолвер V1

    // УДАЛЕН: supplyMovements - неиспользуемый стаб резолвер V1

    // Получение кеша статистики селлера
    getSellerStatsCache: withAuth(async (
      _: unknown,
      args: { period: string; dateFrom?: string | null; dateTo?: string | null },
      context: Context,
    ) => {
      console.log('🔍 GET_SELLER_STATS_CACHE DOMAIN QUERY STARTED:', { 
        userId: context.user?.id,
        period: args.period,
        dateFrom: args.dateFrom,
        dateTo: args.dateTo,
      })

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

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

        // TODO: Реализовать получение кеша из отдельной таблицы или Redis
        // Пока возвращаем базовую структуру
        const cacheKey = `seller_stats_${user.organization.id}_${args.period}_${args.dateFrom || 'null'}_${args.dateTo || 'null'}`
        
        console.log('🔍 Looking for cache:', { cacheKey })

        // Заглушка для кеша - в реальной системе здесь будет запрос к кеш-хранилищу
        const mockCacheData = {
          period: args.period,
          dateFrom: args.dateFrom,
          dateTo: args.dateTo,
          productsData: null,
          productsTotalSales: 0,
          totalRevenue: 0,
          totalOrders: 0,
          averageOrderValue: 0,
          topProducts: [],
          cachedAt: new Date().toISOString(),
          organizationId: user.organization.id,
        }

        console.log('✅ GET_SELLER_STATS_CACHE DOMAIN SUCCESS:', {
          organizationId: user.organization.id,
          period: args.period,
          hasCachedData: false, // В реальной системе проверить наличие кеша
        })

        return mockCacheData
      } catch (error: any) {
        console.error('❌ GET_SELLER_STATS_CACHE DOMAIN ERROR:', error)
        return {
          period: args.period,
          dateFrom: args.dateFrom,
          dateTo: args.dateTo,
          productsData: null,
          productsTotalSales: null,
          totalRevenue: null,
          totalOrders: null,
          averageOrderValue: null,
          topProducts: null,
          cachedAt: null,
          organizationId: null,
        }
      }
    }),
  },

  Mutation: {

    // Сохранение кеша статистики селлера
    saveSellerStatsCache: withAuth(async (
      _: unknown,
      {
        input,
      }: {
        input: {
          period: string
          dateFrom?: string | null
          dateTo?: string | null
          productsData?: string | null
          productsTotalSales?: number | null
          totalRevenue?: number | null
          totalOrders?: number | null
          averageOrderValue?: number | null
          topProducts?: string | null
        }
      },
      context: Context,
    ) => {
      console.log('🔍 SAVE_SELLER_STATS_CACHE DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        period: input.period,
        dateFrom: input.dateFrom,
        dateTo: input.dateTo,
      })

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

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

        const cacheKey = `seller_stats_${user.organization.id}_${input.period}_${input.dateFrom || 'null'}_${input.dateTo || 'null'}`
        
        console.log('💾 Saving cache:', { 
          cacheKey,
          dataSize: JSON.stringify(input).length,
        })

        // TODO: Реализовать сохранение в отдельной таблице кеша или Redis
        // await saveToCache(cacheKey, input)

        console.log('✅ SAVE_SELLER_STATS_CACHE DOMAIN SUCCESS:', {
          organizationId: user.organization.id,
          period: input.period,
          cacheKey,
        })

        return {
          success: true,
          message: 'Кеш статистики селлера сохранен',
          cachedAt: new Date().toISOString(),
        }
      } catch (error: any) {
        console.error('❌ SAVE_SELLER_STATS_CACHE DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при сохранении кеша статистики',
          cachedAt: null,
        }
      }
    }),
  },
}

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