import { GraphQLError } from 'graphql'
import * as jwt from 'jsonwebtoken'

import { prisma } from '../../../lib/prisma'
import { SmsService } from '../../../services/sms-service'
import { Context } from '../../context'
import { DomainResolvers } from '../shared/types'

// Auth Domain Resolvers - аутентификация и авторизация
console.warn('🔥 МОДУЛЬ AUTH DOMAIN ЗАГРУЖАЕТСЯ')

// Инициализируем SMS сервис
const smsService = new SmsService()

// =============================================================================
// 🔐 ТИПЫ И ИНТЕРФЕЙСЫ
// =============================================================================

interface AuthTokenPayload {
  userId: string
  phone: string
}

interface AuthUser {
  id: string
  phone: string
  organizationId?: string | null
  organization?: any
}

// =============================================================================
// 🛡️ JWT УТИЛИТЫ
// =============================================================================

const generateToken = (payload: AuthTokenPayload): string => {
  if (!process.env.JWT_SECRET) {
    throw new Error('JWT_SECRET не настроен')
  }
  return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '30d' })
}

const verifyToken = (token: string): AuthTokenPayload => {
  if (!process.env.JWT_SECRET) {
    throw new Error('JWT_SECRET не настроен')
  }
  try {
    return jwt.verify(token, process.env.JWT_SECRET) as AuthTokenPayload
  } catch (error) {
    throw new GraphQLError('Недействительный токен', {
      extensions: { code: 'UNAUTHENTICATED' },
    })
  }
}

// =============================================================================
// 🔐 AUTH DOMAIN RESOLVERS
// =============================================================================

export const authResolvers: DomainResolvers = {
  Query: {
    // Получить текущего пользователя
    me: async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 ME QUERY STARTED:', { hasUser: !!context.user, userId: context.user?.id })
      
      if (!context.user) {
        throw new GraphQLError('Требуется авторизация', {
          extensions: { code: 'UNAUTHENTICATED' },
        })
      }

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

        if (!user) {
          throw new GraphQLError('Пользователь не найден')
        }

        console.log('✅ ME QUERY SUCCESS:', { userId: user.id, hasOrganization: !!user.organization })
        return user
      } catch (error) {
        console.error('❌ ME QUERY ERROR:', error)
        throw error
      }
    },

    // Проверить статус авторизации
    authStatus: async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 AUTH_STATUS QUERY STARTED:', { hasUser: !!context.user })
      
      return {
        isAuthenticated: !!context.user,
        userId: context.user?.id || null,
        hasOrganization: !!context.user?.organizationId,
      }
    },
  },

  Mutation: {
    // Отправить SMS код
    sendSmsCode: async (_: unknown, args: { phone: string }) => {
      console.log('🔍 SEND_SMS_CODE MUTATION STARTED:', { phone: args.phone })
      
      try {
        // Валидация номера телефона
        const phoneRegex = /^\+?[1-9]\d{1,14}$/
        if (!phoneRegex.test(args.phone)) {
          return {
            success: false,
            message: 'Неверный формат номера телефона',
          }
        }

        // Используем SMS сервис для отправки кода
        const smsResult = await smsService.sendSmsCode(args.phone)
        
        console.log('✅ SEND_SMS_CODE RESULT:', { phone: args.phone, success: smsResult.success })
        return smsResult
      } catch (error) {
        console.error('❌ SEND_SMS_CODE ERROR:', error)
        return {
          success: false,
          message: 'Ошибка при отправке SMS кода',
        }
      }
    },

    // Верификация SMS кода и авторизация
    verifySmsCode: async (_: unknown, args: { phone: string; code: string }) => {
      console.log('🔍 VERIFY_SMS_CODE MUTATION STARTED:', { phone: args.phone, code: args.code })
      
      try {
        const user = await prisma.user.findUnique({
          where: { phone: args.phone },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })

        if (!user) {
          return {
            success: false,
            message: 'Пользователь не найден',
            token: null,
            user: null,
          }
        }

        // Проверяем код через SMS сервис
        const verificationResult = await smsService.verifySmsCode(args.phone, args.code)
        
        if (!verificationResult.success) {
          return {
            success: false,
            message: verificationResult.message,
            token: null,
            user: null,
          }
        }

        // Обновляем время последнего входа
        const updatedUser = await prisma.user.update({
          where: { id: user.id },
          data: {
            lastLoginAt: new Date(),
          },
          include: {
            organization: {
              include: {
                apiKeys: true,
              },
            },
          },
        })

        // Генерируем JWT токен
        const token = generateToken({
          userId: user.id,
          phone: user.phone,
        })

        console.log('✅ VERIFY_SMS_CODE SUCCESS:', { 
          userId: user.id, 
          phone: user.phone,
          hasOrganization: !!user.organization,
        })

        return {
          success: true,
          message: 'Авторизация успешна',
          token,
          user: updatedUser,
        }
      } catch (error) {
        console.error('❌ VERIFY_SMS_CODE ERROR:', error)
        return {
          success: false,
          message: 'Ошибка при верификации кода',
          token: null,
          user: null,
        }
      }
    },

    // Выход из системы
    logout: async (_: unknown, __: unknown, context: Context) => {
      console.log('🔍 LOGOUT MUTATION STARTED:', { userId: context.user?.id })
      
      if (!context.user) {
        return {
          success: false,
          message: 'Пользователь не авторизован',
        }
      }

      try {
        // Обновляем время последнего выхода
        await prisma.user.update({
          where: { id: context.user.id },
          data: {
            lastLogoutAt: new Date(),
          },
        })

        console.log('✅ LOGOUT SUCCESS:', { userId: context.user.id })
        return {
          success: true,
          message: 'Выход выполнен успешно',
        }
      } catch (error) {
        console.error('❌ LOGOUT ERROR:', error)
        return {
          success: false,
          message: 'Ошибка при выходе из системы',
        }
      }
    },
  },
}

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