import { ApolloServer } from '@apollo/server'
import { startServerAndCreateNextHandler } from '@as-integrations/next'
import jwt from 'jsonwebtoken'
import { NextRequest } from 'next/server'

import { Context } from '@/graphql/context'
import { resolvers } from '@/graphql/resolvers/index'
import { typeDefs } from '@/graphql/typedefs'
import { prisma } from '@/lib/prisma'

// Создаем Apollo Server
const server = new ApolloServer<Context>({
  typeDefs,
  resolvers,
  plugins: [
    {
      requestDidStart() {
        return Promise.resolve({
          didResolveOperation(requestContext: any): Promise<void> {
            const operationName = requestContext.request.operationName
            const operation = requestContext.document?.definitions[0]
            const operationType = operation?.kind === 'OperationDefinition' ? operation.operation : 'unknown'

            console.warn('🌐 GraphQL REQUEST:', {
              operationType,
              operationName,
              timestamp: new Date().toISOString(),
              variables: requestContext.request.variables,
            })
            return Promise.resolve()
          },
          didEncounterErrors(requestContext: any): Promise<void> {
            console.error('❌ GraphQL ERROR:', {
              errors: requestContext.errors?.map((e: any) => e.message),
              operationName: requestContext.request.operationName,
              timestamp: new Date().toISOString(),
            })
            return Promise.resolve()
          },
        })
      },
    },
  ],
})

// Создаем Next.js handler
const handler = startServerAndCreateNextHandler<NextRequest, Context>(server, {
  context: async (req: NextRequest) => {
    // Извлекаем токен из заголовка Authorization
    const authHeader = req.headers.get('authorization')
    const token = authHeader?.replace('Bearer ', '')

    if (!token) {
      return { 
        user: null, 
        currentUser: null,
        admin: null, 
        prisma,
        req: {
          ip: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'),
          get: (header: string) => req.headers.get(header),
        },
      }
    }

    try {
      // Верифицируем JWT токен
      const jwtSecret = process.env.JWT_SECRET
      if (!jwtSecret) {
        throw new Error('JWT_SECRET not configured')
      }

      const decoded = jwt.verify(token, jwtSecret) as {
        userId?: string
        phone?: string
        adminId?: string
        username?: string
        type?: string
      }

      // Проверяем тип токена
      if (decoded.type === 'admin' && decoded.adminId && decoded.username) {
        return {
          admin: {
            id: decoded.adminId,
            username: decoded.username,
          },
          user: null,
          currentUser: null,
          prisma,
          req: {
            ip: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'),
            get: (header: string) => req.headers.get(header),
          },
        }
      } else if (decoded.userId && decoded.phone) {
        // Получаем пользователя с организацией из базы
        const user = await prisma.user.findUnique({
          where: { id: decoded.userId },
          include: {
            organization: {
              select: { id: true, type: true },
            },
          },
        })

        return {
          user: user
            ? {
                id: user.id,
                phone: decoded.phone,
                organizationId: user.organization?.id,
                organization: user.organization,
              }
            : null,
          currentUser: user
            ? {
                id: user.id,
                organization: user.organization || { id: '', type: 'SELLER' },
              }
            : null,
          admin: null,
          prisma,
          req: {
            ip: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'),
            get: (header: string) => req.headers.get(header),
          },
        }
      }

      return { 
        user: null, 
        currentUser: null,
        admin: null, 
        prisma,
        req: {
          ip: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'),
          get: (header: string) => req.headers.get(header),
        },
      }
    } catch (error) {
      console.error('GraphQL Context - Invalid token:', error)
      return { 
        user: null, 
        currentUser: null,
        admin: null, 
        prisma,
        req: {
          ip: req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip'),
          get: (header: string) => req.headers.get(header),
        },
      }
    }
  },
})

export async function GET(request: NextRequest) {
  return handler(request)
}

export async function POST(request: NextRequest) {
  return handler(request)
}
