import { GraphQLError } from 'graphql'

import { prisma } from '../../../lib/prisma'
import { MarketplaceService } from '../../../services/marketplace-service'
import { WildberriesService } from '../../../services/wildberries-service'
import { Context } from '../../context'
import { DomainResolvers } from '../shared/types'

// Wildberries & Marketplace Domain Resolvers - управление интеграцией с маркетплейсами

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

const withAuth = (resolver: any) => {
  return async (parent: any, args: any, context: Context) => {
    console.log('🔐 WILDBERRIES 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 marketplaceService = new MarketplaceService()
// WildberriesService требует API ключ в конструкторе, создадим экземпляры в резолверах

// =============================================================================
// 🛍️ WILDBERRIES & MARKETPLACE DOMAIN RESOLVERS
// =============================================================================

export const wildberriesResolvers: DomainResolvers = {
  Query: {
    // Мои поставки Wildberries
    myWildberriesSupplies: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 MY_WILDBERRIES_SUPPLIES 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('У пользователя нет организации')
        }

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

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

    // Отладка рекламных кампаний Wildberries
    debugWildberriesAdverts: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 DEBUG_WILDBERRIES_ADVERTS DOMAIN QUERY STARTED:', { userId: context.user?.id })
      
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { 
            organization: {
              include: { apiKeys: true },
            },
          },
        })

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

        const wbApiKey = user.organization.apiKeys.find(key => key.marketplace === 'WILDBERRIES')
        if (!wbApiKey) {
          throw new GraphQLError('API ключ Wildberries не найден')
        }

        console.log('🚀 FETCHING WB ADVERTS WITH API KEY:', { 
          organizationId: user.organization.id,
          hasApiKey: !!wbApiKey.apiKey, 
        })

        const campaigns = await wildberriesService.getAdvertCampaigns(wbApiKey.apiKey)
        
        console.log('✅ DEBUG_WILDBERRIES_ADVERTS SUCCESS:', { campaignsCount: campaigns.length })
        
        return {
          success: true,
          message: 'Кампании получены успешно',
          campaignsCount: campaigns.length,
          campaigns: campaigns.slice(0, 5), // Первые 5 для отладки
        }
      } catch (error) {
        console.error('❌ DEBUG_WILDBERRIES_ADVERTS ERROR:', error)
        return {
          success: false,
          message: `Ошибка получения кампаний: ${error instanceof Error ? error.message : 'Unknown error'}`,
          campaignsCount: 0,
          campaigns: [],
        }
      }
    }),

    // Получение статистики Wildberries
    getWildberriesStatistics: withAuth(async (
      _: unknown, 
      args: { period: string; startDate: string; endDate: string }, 
      context: Context,
    ) => {
      console.log('🔍 GET_WILDBERRIES_STATISTICS DOMAIN QUERY STARTED:', { 
        userId: context.user?.id,
        period: args.period,
        startDate: args.startDate,
        endDate: args.endDate,
      })

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

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

        const apiKey = user.organization.apiKeys.find(
          key => key.marketplace === 'WILDBERRIES' && key.isActive,
        )

        if (!apiKey) {
          return {
            success: false,
            message: 'API ключ Wildberries не найден',
            data: [],
          }
        }

        const wbService = new WildberriesService(apiKey.apiKey)
        console.log('🔑 API Key length:', apiKey.apiKey?.length)
        console.log('📅 Date params:', { startDate: args.startDate, endDate: args.endDate, period: args.period })
        
        // Если нет конкретных дат, генерируем их на основе периода
        let startDate = args.startDate
        let endDate = args.endDate
        
        if (!startDate || !endDate) {
          const now = new Date()
          const today = now.toISOString().split('T')[0] // YYYY-MM-DD
          
          switch (args.period) {
            case 'week':
              const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
              startDate = weekAgo.toISOString().split('T')[0]
              endDate = today
              break
            case 'month':
              const monthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000)
              startDate = monthAgo.toISOString().split('T')[0]
              endDate = today
              break
            default:
              // По умолчанию неделя
              const defaultWeekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
              startDate = defaultWeekAgo.toISOString().split('T')[0]
              endDate = today
          }
        }
        
        console.log('📅 Calculated dates:', { startDate, endDate })
        
        const statistics = await wbService.getStatistics(startDate, endDate)
        
        console.log('📊 Statistics result:', {
          type: typeof statistics,
          isArray: Array.isArray(statistics),
          length: statistics?.length,
          firstItem: statistics?.[0] ? Object.keys(statistics[0]) : null,
        })
        
        // Сохраняем успешные данные в кеш для будущего использования при rate limit
        if (statistics && statistics.length > 0) {
          const cacheKey = `wb_stats_${user.organization.id}_${startDate}_${endDate}`
          try {
            // Пока используем простое логирование, позже можно добавить Redis или таблицу кеша
            console.log('💾 CACHING SUCCESS DATA:', { cacheKey, dataLength: statistics.length })
            // TODO: Сохранить в Redis или БД
            // await redis.setex(cacheKey, 3600, JSON.stringify(statistics)) // 1 час TTL
          } catch (cacheError) {
            console.error('❌ Failed to cache statistics:', cacheError)
          }
        }
        
        console.log('✅ GET_WILDBERRIES_STATISTICS DOMAIN SUCCESS')

        return {
          success: true,
          message: 'Статистика получена',
          data: statistics,
        }
      } catch (error: any) {
        console.error('❌ GET_WILDBERRIES_STATISTICS DOMAIN ERROR:', error)
        
        // Если ошибка rate limit (429), пытаемся получить последние кешированные данные
        if (error.message && error.message.includes('429')) {
          console.warn('🔄 RATE LIMIT: Checking for cached statistics data')
          
          // Ищем последние кешированные данные для этой организации и периода
          const cacheKey = `wb_stats_${user?.organization?.id}_${startDate}_${endDate}`
          
          try {
            // Проверяем кеш в БД (можно использовать отдельную таблицу или Redis)
            // Пока что возвращаем информативное сообщение
            return {
              success: false,
              message: 'Достигнут лимит запросов WB API. Подождите и попробуйте снова через несколько минут.',
              data: [],
            }
          } catch (cacheError) {
            console.error('❌ Cache lookup failed:', cacheError)
          }
        }
        
        return {
          success: false,
          message: error.message || 'Ошибка при получении статистики',
          data: [],
        }
      }
    }),

    // Получение статистики кампаний Wildberries
    getWildberriesCampaignStats: withAuth(async (
      _: unknown, 
      args: { input: { campaigns: { id: number; dates?: string[]; interval?: { begin: string; end: string } }[] } }, 
      context: Context,
    ) => {
      console.log('🔍 GET_WILDBERRIES_CAMPAIGN_STATS DOMAIN QUERY STARTED:', { 
        userId: context.user?.id,
        campaigns: args.input.campaigns.map(c => c.id),
      })

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

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

        const apiKey = user.organization.apiKeys.find(
          key => key.marketplace === 'WILDBERRIES' && key.isActive,
        )

        if (!apiKey) {
          return {
            success: false,
            message: 'API ключ Wildberries не найден',
            data: [],
          }
        }

        const wbService = new WildberriesService(apiKey.apiKey)
        const stats = await wbService.getCampaignStats(args.input.campaigns)
        
        console.log('✅ GET_WILDBERRIES_CAMPAIGN_STATS DOMAIN SUCCESS')

        return {
          success: true,
          message: 'Статистика кампаний получена',
          data: stats,
        }
      } catch (error: any) {
        console.error('❌ GET_WILDBERRIES_CAMPAIGN_STATS DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при получении статистики кампаний',
          data: [],
        }
      }
    }),

    // Получение списка кампаний Wildberries
    getWildberriesCampaignsList: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 GET_WILDBERRIES_CAMPAIGNS_LIST DOMAIN QUERY STARTED:', { userId: context.user?.id })
      
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { 
            organization: {
              include: { apiKeys: true },
            },
          },
        })

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

        const apiKey = user.organization.apiKeys.find(
          key => key.marketplace === 'WILDBERRIES' && key.isActive,
        )

        if (!apiKey) {
          return {
            success: false,
            message: 'API ключ Wildberries не найден',
            data: { adverts: [], all: 0 },
          }
        }

        const wbService = new WildberriesService(apiKey.apiKey)
        const campaignsList = await wbService.getCampaignsList()
        
        console.log('✅ GET_WILDBERRIES_CAMPAIGNS_LIST DOMAIN SUCCESS')

        return {
          success: true,
          message: 'Список кампаний получен',
          data: campaignsList,
        }
      } catch (error: any) {
        console.error('❌ GET_WILDBERRIES_CAMPAIGNS_LIST DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при получении списка кампаний',
          data: { adverts: [], all: 0 },
        }
      }
    }),

    // Возвратные претензии Wildberries
    wbReturnClaims: withAuth(async (_: unknown, args: { isArchive: boolean; limit?: number; offset?: number }, context: Context) => {
      console.log('🔍 WB_RETURN_CLAIMS DOMAIN QUERY STARTED:', { 
        userId: context.user?.id,
        isArchive: args.isArchive,
        limit: args.limit,
        offset: args.offset,
      })

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

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

        const apiKey = user.organization.apiKeys.find(
          key => key.marketplace === 'WILDBERRIES' && key.isActive,
        )

        if (!apiKey) {
          return {
            claims: [],
            total: 0,
          }
        }

        const wbService = new WildberriesService(apiKey.apiKey)
        // TODO: Реализовать метод getReturnClaims в WildberriesService
        const claims = []
        
        console.log('✅ WB_RETURN_CLAIMS DOMAIN SUCCESS:', { 
          claimsCount: claims?.length || 0,
        })

        return {
          claims: claims || [],
          total: claims?.length || 0,
        }
      } catch (error: any) {
        console.error('❌ WB_RETURN_CLAIMS DOMAIN ERROR:', error)
        return {
          claims: [],
          total: 0,
        }
      }
    }),

    // Получение данных о складах WB
    getWBWarehouseData: withAuth(async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 GET_WB_WAREHOUSE_DATA DOMAIN QUERY STARTED:', { userId: context.user?.id })

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

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

        const apiKey = user.organization.apiKeys.find(
          key => key.marketplace === 'WILDBERRIES' && key.isActive,
        )

        if (!apiKey) {
          return {
            success: false,
            message: 'API ключ Wildberries не найден',
            cache: null,
            fromCache: false,
          }
        }

        const wbService = new WildberriesService(apiKey.apiKey)
        const warehouseData = await wbService.getWarehouses()
        
        console.log('✅ GET_WB_WAREHOUSE_DATA DOMAIN SUCCESS:', { 
          stocksCount: warehouseData?.stocks?.length || 0,
        })

        return {
          success: true,
          message: 'Данные о складах получены',
          cache: warehouseData,
          fromCache: false,
        }
      } catch (error: any) {
        console.error('❌ GET_WB_WAREHOUSE_DATA DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при получении данных о складах',
          cache: null,
          fromCache: false,
        }
      }
    }),
  },

  Mutation: {
    // Добавление API ключа маркетплейса
    addMarketplaceApiKey: async (
      _: unknown,
      args: {
        input: {
          marketplace: 'WILDBERRIES' | 'OZON'
          apiKey: string
          clientId?: string
          validateOnly?: boolean
        }
      },
      context: Context,
    ) => {
      console.log('🔍 ADD_MARKETPLACE_API_KEY DOMAIN MUTATION STARTED:', { 
        marketplace: args.input.marketplace,
        validateOnly: args.input.validateOnly,
        hasUser: !!context.user,
      })

      // Разрешаем валидацию без авторизации
      if (!args.input.validateOnly && !context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

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

      // Только валидация ключа
      if (validateOnly) {
        try {
          const isValid = await marketplaceService.validateApiKey(marketplace, apiKey, clientId)
          if (isValid) {
            return {
              success: true,
              message: `API ключ ${marketplace} действителен`,
              organization: null,
            }
          } else {
            return {
              success: false,
              message: `Недействительный API ключ ${marketplace}`,
              organization: null,
            }
          }
        } catch (error: any) {
          return {
            success: false,
            message: error.message || 'Ошибка при проверке API ключа',
            organization: null,
          }
        }
      }

      // Полное добавление ключа (требует авторизацию)
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация')
      }

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

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

      try {
        // Валидация ключа
        const isValid = await marketplaceService.validateApiKey(marketplace, apiKey, clientId)
        if (!isValid) {
          return {
            success: false,
            message: `Недействительный API ключ ${marketplace}`,
            organization: null,
          }
        }

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

        if (existing) {
          // Обновляем существующий
          await prisma.apiKey.update({
            where: {
              organizationId_marketplace: {
                organizationId: user.organization.id,
                marketplace,
              },
            },
            data: {
              apiKey: apiKey,
              isActive: true,
              validationData: clientId ? { clientId, validatedAt: new Date() } : { validatedAt: new Date() },
            },
          })
        } else {
          // Создаем новый
          await prisma.apiKey.create({
            data: {
              organizationId: user.organization.id,
              marketplace,
              apiKey: apiKey,
              isActive: true,
              validationData: clientId ? { clientId, validatedAt: new Date() } : { validatedAt: new Date() },
            },
          })
        }

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

        console.log('✅ ADD_MARKETPLACE_API_KEY DOMAIN SUCCESS:', { 
          organizationId: user.organization.id,
          marketplace,
        })

        return {
          success: true,
          message: `API ключ ${marketplace} успешно добавлен`,
          organization: updatedOrganization,
        }
      } catch (error: any) {
        console.error('❌ ADD_MARKETPLACE_API_KEY DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при добавлении API ключа',
          organization: null,
        }
      }
    },

    // Удаление API ключа маркетплейса
    removeMarketplaceApiKey: withAuth(async (
      _: unknown, 
      args: { marketplace: 'WILDBERRIES' | 'OZON' }, 
      context: Context,
    ) => {
      console.log('🔍 REMOVE_MARKETPLACE_API_KEY DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        marketplace: args.marketplace,
      })
      
      try {
        const user = await prisma.user.findUnique({
          where: { id: context.user!.id },
          include: { organization: true },
        })

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

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

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

        console.log('✅ REMOVE_MARKETPLACE_API_KEY DOMAIN SUCCESS:', { 
          organizationId: user.organization.id,
          marketplace: args.marketplace,
        })

        return {
          success: true,
          message: `API ключ ${args.marketplace} успешно удален`,
          organization: updatedOrganization,
        }
      } catch (error: any) {
        console.error('❌ REMOVE_MARKETPLACE_API_KEY DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при удалении API ключа',
          organization: null,
        }
      }
    }),

    // Создание поставки на Wildberries
    createWildberriesSupply: withAuth(async (
      _: unknown,
      args: {
        input: {
          cards: Array<{
            price: number
            discountedPrice?: number
            selectedQuantity: number
            selectedServices?: string[]
          }>
        }
      },
      context: Context,
    ) => {
      console.log('🔍 CREATE_WILDBERRIES_SUPPLY DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        cardsCount: args.input.cards.length,
      })

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

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

        // Проверка API ключа
        const apiKey = currentUser.organization.apiKeys.find(
          key => key.marketplace === 'WILDBERRIES' && key.isActive,
        )

        if (!apiKey) {
          return {
            success: false,
            message: 'Не найден активный API ключ Wildberries',
            supply: null,
          }
        }

        // Создаем экземпляр WildberriesService с API ключом
        const wbService = new WildberriesService(apiKey.apiKey)
        
        // Получаем каталог с карточками
        const catalogData = await wbService.getProducts()
        const catalog = catalogData?.data || []
        if (catalog.length === 0) {
          return {
            success: false,
            message: 'Не удалось получить каталог товаров',
            supply: null,
          }
        }

        // Создаем поставку
        const supply = await prisma.wildberriesSupply.create({
          data: {
            organizationId: currentUser.organization.id,
            status: 'DRAFT',
            totalCards: args.input.cards.length,
            totalQuantity: args.input.cards.reduce((sum, card) => sum + card.selectedQuantity, 0),
            cards: {
              create: args.input.cards.map((card, index) => ({
                vendorCode: catalog[index]?.vendorCode || `ART${index}`,
                title: catalog[index]?.title || `Товар ${index + 1}`,
                selectedQuantity: card.selectedQuantity,
                price: card.price,
                discountedPrice: card.discountedPrice || card.price,
                quantity: card.selectedQuantity,
                warehouseId: catalog[index]?.skus?.[0]?.warehouses?.[0]?.warehouseId || 0,
                services: card.selectedServices || [],
              })),
            },
          },
          include: {
            organization: true,
            cards: true,
          },
        })

        // TODO: Интеграция с WB API для создания поставки
        // const wbSupplyId = await wbService.createSupply(...)
        // Пока просто обновляем статус
        await prisma.wildberriesSupply.update({
          where: { id: supply.id },
          data: {
            status: 'CREATED',
          },
        })

        console.log('✅ CREATE_WILDBERRIES_SUPPLY DOMAIN SUCCESS:', { 
          supplyId: supply.id,
          externalId: wbSupplyId,
        })

        return {
          success: true,
          message: 'Поставка успешно создана',
          supply,
        }
      } catch (error: any) {
        console.error('❌ CREATE_WILDBERRIES_SUPPLY DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при создании поставки',
          supply: null,
        }
      }
    }),

    // Сохранение кеша данных складов WB
    saveWBWarehouseCache: withAuth(async (
      _: unknown, 
      args: { 
        input: {
          data: string;
          totalProducts: number;
          totalStocks: number;
          totalReserved: number;
        }
      }, 
      context: Context,
    ) => {
      console.log('🔍 SAVE_WB_WAREHOUSE_CACHE DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        hasData: !!args.input.data,
        totalProducts: args.input.totalProducts,
        totalStocks: args.input.totalStocks,
      })

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

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

        // TODO: Реализовать кеширование в отдельной таблице или через Redis
        console.log('✅ SAVE_WB_WAREHOUSE_CACHE DOMAIN SUCCESS:', { 
          organizationId: user.organization.id,
          dataSize: args.input.data.length,
        })

        return {
          success: true,
          message: 'Кеш данных складов сохранен',
          cache: {
            id: `cache_${user.organization.id}_${Date.now()}`,
            organizationId: user.organization.id,
            cacheDate: new Date().toISOString(),
            data: args.input.data,
            totalProducts: args.input.totalProducts,
            totalStocks: args.input.totalStocks,
            totalReserved: args.input.totalReserved,
            createdAt: new Date().toISOString(),
            updatedAt: new Date().toISOString(),
          },
          fromCache: false,
        }
      } catch (error: any) {
        console.error('❌ SAVE_WB_WAREHOUSE_CACHE DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка при сохранении кеша',
          cache: null,
          fromCache: false,
        }
      }
    }),
  },
}

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