import { GraphQLError } from 'graphql'

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

// External Ads Domain Resolvers - управление внешней рекламой и маркетинговыми кампаниями

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

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

// =============================================================================
// 📢 EXTERNAL ADS DOMAIN RESOLVERS
// =============================================================================

export const externalAdsResolvers: DomainResolvers = {
  Query: {
    // Получение всех внешних рекламных кампаний за период
    getExternalAds: withAuth(async (
      _: unknown, 
      args: { dateFrom: string; dateTo: string }, 
      context: Context,
    ) => {
      console.log('🔍 GET_EXTERNAL_ADS DOMAIN QUERY STARTED:', { 
        userId: context.user?.id,
        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('Организация не найдена')
        }

        console.log('🔍 GET_EXTERNAL_ADS: Fetching ads for organization:', { 
          organizationId: user.organization.id,
          dateRange: `${args.dateFrom} - ${args.dateTo}`,
        })

        const externalAds = await prisma.externalAd.findMany({
          where: {
            organizationId: user.organization.id,
            date: {
              gte: new Date(args.dateFrom),
              lte: new Date(args.dateTo + 'T23:59:59.999Z'),
            },
          },
          orderBy: {
            date: 'desc',
          },
        })

        console.log('✅ GET_EXTERNAL_ADS DOMAIN SUCCESS:', { 
          organizationId: user.organization.id,
          foundAds: externalAds.length,
          totalCost: externalAds.reduce((sum, ad) => sum + Number(ad.cost), 0),
        })

        return {
          success: true,
          message: null,
          externalAds: externalAds.map((ad) => ({
            ...ad,
            cost: parseFloat(ad.cost.toString()),
            date: ad.date.toISOString().split('T')[0],
            createdAt: ad.createdAt.toISOString(),
            updatedAt: ad.updatedAt.toISOString(),
          })),
        }
      } catch (error: any) {
        console.error('❌ GET_EXTERNAL_ADS DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка получения внешней рекламы',
          externalAds: [],
        }
      }
    }),
  },

  Mutation: {
    // Создание новой рекламной кампании
    createExternalAd: withAuth(async (
      _: unknown,
      args: {
        input: {
          name: string
          url: string
          cost: number
          date: string
          nmId: string
        }
      },
      context: Context,
    ) => {
      console.log('🔍 CREATE_EXTERNAL_AD DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        adName: args.input.name,
        cost: args.input.cost,
        date: args.input.date,
        nmId: args.input.nmId,
      })

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

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

        console.log('💰 Creating external ad:', {
          organizationId: user.organization.id,
          name: args.input.name,
          url: args.input.url,
          cost: args.input.cost,
        })

        const externalAd = await prisma.externalAd.create({
          data: {
            name: args.input.name,
            url: args.input.url,
            cost: args.input.cost,
            date: new Date(args.input.date),
            nmId: args.input.nmId,
            organizationId: user.organization.id,
          },
        })

        console.log('✅ CREATE_EXTERNAL_AD DOMAIN SUCCESS:', { 
          adId: externalAd.id,
          organizationId: user.organization.id,
          cost: args.input.cost,
        })

        return {
          success: true,
          message: 'Внешняя реклама успешно создана',
          externalAd: {
            ...externalAd,
            cost: parseFloat(externalAd.cost.toString()),
            date: externalAd.date.toISOString().split('T')[0],
            createdAt: externalAd.createdAt.toISOString(),
            updatedAt: externalAd.updatedAt.toISOString(),
          },
        }
      } catch (error: any) {
        console.error('❌ CREATE_EXTERNAL_AD DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка создания внешней рекламы',
          externalAd: null,
        }
      }
    }),

    // Обновление рекламной кампании
    updateExternalAd: withAuth(async (
      _: unknown,
      args: {
        id: string
        input: {
          name: string
          url: string
          cost: number
          date: string
          nmId: string
        }
      },
      context: Context,
    ) => {
      console.log('🔍 UPDATE_EXTERNAL_AD DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        adId: args.id,
        newCost: args.input.cost,
        newName: args.input.name,
      })

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

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

        // Проверяем, что реклама принадлежит организации пользователя
        const existingAd = await prisma.externalAd.findFirst({
          where: {
            id: args.id,
            organizationId: user.organization.id,
          },
        })

        if (!existingAd) {
          throw new GraphQLError('Внешняя реклама не найдена')
        }

        console.log('📝 Updating external ad:', {
          adId: args.id,
          oldCost: Number(existingAd.cost),
          newCost: args.input.cost,
          organizationId: user.organization.id,
        })

        const externalAd = await prisma.externalAd.update({
          where: { id: args.id },
          data: {
            name: args.input.name,
            url: args.input.url,
            cost: args.input.cost,
            date: new Date(args.input.date),
            nmId: args.input.nmId,
          },
        })

        console.log('✅ UPDATE_EXTERNAL_AD DOMAIN SUCCESS:', { 
          adId: externalAd.id,
          updatedCost: args.input.cost,
        })

        return {
          success: true,
          message: 'Внешняя реклама успешно обновлена',
          externalAd: {
            ...externalAd,
            cost: parseFloat(externalAd.cost.toString()),
            date: externalAd.date.toISOString().split('T')[0],
            createdAt: externalAd.createdAt.toISOString(),
            updatedAt: externalAd.updatedAt.toISOString(),
          },
        }
      } catch (error: any) {
        console.error('❌ UPDATE_EXTERNAL_AD DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка обновления внешней рекламы',
          externalAd: null,
        }
      }
    }),

    // Удаление рекламной кампании
    deleteExternalAd: withAuth(async (
      _: unknown, 
      args: { id: string }, 
      context: Context,
    ) => {
      console.log('🔍 DELETE_EXTERNAL_AD DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        adId: args.id,
      })

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

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

        // Проверяем, что реклама принадлежит организации пользователя
        const existingAd = await prisma.externalAd.findFirst({
          where: {
            id: args.id,
            organizationId: user.organization.id,
          },
        })

        if (!existingAd) {
          throw new GraphQLError('Внешняя реклама не найдена')
        }

        console.log('🗑️ Deleting external ad:', {
          adId: args.id,
          adName: existingAd.name,
          adCost: Number(existingAd.cost),
          organizationId: user.organization.id,
        })

        await prisma.externalAd.delete({
          where: { id: args.id },
        })

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

        return {
          success: true,
          message: 'Внешняя реклама успешно удалена',
          externalAd: null,
        }
      } catch (error: any) {
        console.error('❌ DELETE_EXTERNAL_AD DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка удаления внешней рекламы',
          externalAd: null,
        }
      }
    }),

    // Обновление количества кликов по рекламе
    updateExternalAdClicks: withAuth(async (
      _: unknown, 
      args: { id: string; clicks: number }, 
      context: Context,
    ) => {
      console.log('🔍 UPDATE_EXTERNAL_AD_CLICKS DOMAIN MUTATION STARTED:', { 
        userId: context.user?.id,
        adId: args.id,
        clicks: args.clicks,
      })

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

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

        // Проверяем, что реклама принадлежит организации пользователя
        const existingAd = await prisma.externalAd.findFirst({
          where: {
            id: args.id,
            organizationId: user.organization.id,
          },
        })

        if (!existingAd) {
          throw new GraphQLError('Внешняя реклама не найдена')
        }

        console.log('👆 Updating ad clicks:', {
          adId: args.id,
          adName: existingAd.name,
          oldClicks: existingAd.clicks || 0,
          newClicks: args.clicks,
        })

        await prisma.externalAd.update({
          where: { id: args.id },
          data: { clicks: args.clicks },
        })

        console.log('✅ UPDATE_EXTERNAL_AD_CLICKS DOMAIN SUCCESS:', { 
          adId: args.id,
          updatedClicks: args.clicks,
        })

        return {
          success: true,
          message: 'Клики успешно обновлены',
          externalAd: null,
        }
      } catch (error: any) {
        console.error('❌ UPDATE_EXTERNAL_AD_CLICKS DOMAIN ERROR:', error)
        return {
          success: false,
          message: error.message || 'Ошибка обновления кликов внешней рекламы',
          externalAd: null,
        }
      }
    }),
  },
}

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