import { useMutation, gql } from '@apollo/client'
import { useState, useEffect } from 'react'

import { apolloClient } from '@/lib/apollo-client'

// GraphQL мутации и запросы
const ADMIN_LOGIN = gql`
  mutation AdminLogin($username: String!, $password: String!) {
    adminLogin(username: $username, password: $password) {
      success
      message
      token
      admin {
        id
        username
        email
        isActive
        lastLogin
        createdAt
        updatedAt
      }
    }
  }
`

const ADMIN_ME = gql`
  query AdminMe {
    adminMe {
      id
      username
      email
      isActive
      lastLogin
      createdAt
      updatedAt
    }
  }
`

const ADMIN_LOGOUT = gql`
  mutation AdminLogout {
    adminLogout
  }
`

interface Admin {
  id: string
  username: string
  email?: string
  isActive: boolean
  lastLogin?: string
  createdAt: string
  updatedAt: string
}

interface UseAdminAuthReturn {
  login: (username: string, password: string) => Promise<{ success: boolean; message: string; admin?: Admin }>
  logout: () => void
  admin: Admin | null
  isAuthenticated: boolean
  isLoading: boolean
  checkAuth: () => Promise<void>
}

// Утилиты для работы с токенами администратора
const ADMIN_TOKEN_KEY = 'adminAuthToken'
const ADMIN_DATA_KEY = 'adminData'

const setAdminToken = (token: string) => {
  if (typeof window !== 'undefined') {
    localStorage.setItem(ADMIN_TOKEN_KEY, token)
  }
}

const getAdminToken = (): string | null => {
  if (typeof window !== 'undefined') {
    return localStorage.getItem(ADMIN_TOKEN_KEY)
  }
  return null
}

const removeAdminToken = () => {
  if (typeof window !== 'undefined') {
    localStorage.removeItem(ADMIN_TOKEN_KEY)
    localStorage.removeItem(ADMIN_DATA_KEY)
  }
}

const setAdminData = (admin: Admin) => {
  if (typeof window !== 'undefined') {
    localStorage.setItem(ADMIN_DATA_KEY, JSON.stringify(admin))
  }
}

export const useAdminAuth = (): UseAdminAuthReturn => {
  const [isLoading, setIsLoading] = useState(false)
  const [admin, setAdmin] = useState<Admin | null>(null)
  const [isAuthenticated, setIsAuthenticated] = useState(() => {
    return !!getAdminToken()
  })
  const [isCheckingAuth, setIsCheckingAuth] = useState(false)

  const [adminLoginMutation] = useMutation(ADMIN_LOGIN)
  const [_adminLogoutMutation] = useMutation(ADMIN_LOGOUT)

  // Проверка авторизации администратора
  const checkAuth = async () => {
    if (isCheckingAuth) {
      return
    }

    const token = getAdminToken()
    console.warn('useAdminAuth - checkAuth called, token exists:', !!token)

    if (!token) {
      setIsAuthenticated(false)
      setAdmin(null)
      setIsCheckingAuth(false)
      return
    }

    setIsCheckingAuth(true)

    try {
      console.warn('useAdminAuth - Making ADMIN_ME query')
      const { data } = await apolloClient.query({
        query: ADMIN_ME,
        errorPolicy: 'all',
        fetchPolicy: 'network-only',
        context: {
          headers: {
            authorization: `Bearer ${token}`,
          },
        },
      })

      console.warn('useAdminAuth - ADMIN_ME response:', !!data?.adminMe)
      if (data?.adminMe) {
        setAdmin(data.adminMe)
        setIsAuthenticated(true)
        setAdminData(data.adminMe)
        console.warn('useAdminAuth - Admin authenticated:', data.adminMe.username)
      } else {
        setIsAuthenticated(false)
        setAdmin(null)
      }
    } catch (error: unknown) {
      console.warn('useAdminAuth - ADMIN_ME error:', error)
      if (
        (error as { graphQLErrors?: Array<{ extensions?: { code?: string } }> })?.graphQLErrors?.some(
          (e) => e.extensions?.code === 'UNAUTHENTICATED',
        )
      ) {
        logout()
      } else {
        setIsAuthenticated(false)
        setAdmin(null)
      }
    } finally {
      setIsCheckingAuth(false)
    }
  }

  // Проверяем авторизацию при загрузке компонента
  useEffect(() => {
    const token = getAdminToken()
    console.warn(
      'useAdminAuth - useEffect init, token exists:',
      !!token,
      'admin exists:',
      !!admin,
      'isChecking:',
      isCheckingAuth,
    )

    if (token && !admin && !isCheckingAuth) {
      console.warn('useAdminAuth - Running checkAuth because token exists but no admin data')
      checkAuth()
    } else if (!token) {
      console.warn('useAdminAuth - No token, setting unauthenticated state')
      setIsAuthenticated(false)
      setAdmin(null)
    }
  }, []) // eslint-disable-line react-hooks/exhaustive-deps

  const login = async (username: string, password: string) => {
    try {
      setIsLoading(true)
      console.warn('useAdminAuth - Starting adminLogin mutation')

      const { data } = await adminLoginMutation({
        variables: { username, password },
      })

      console.warn('useAdminAuth - GraphQL response data:', data)
      const result = data.adminLogin
      console.warn('useAdminAuth - Admin login result:', {
        success: result.success,
        hasToken: !!result.token,
        hasAdmin: !!result.admin,
        message: result.message,
      })

      if (result.success && result.token && result.admin) {
        // Сохраняем токен и данные администратора
        console.warn('useAdminAuth - Saving admin token')
        setAdminToken(result.token)
        setAdminData(result.admin)

        // Обновляем состояние хука
        setAdmin(result.admin)
        setIsAuthenticated(true)
        console.warn('useAdminAuth - State updated: admin set, isAuthenticated=true')

        // Принудительно обновляем Apollo Client
        apolloClient.resetStore()

        // Перенаправляем в админ-дашборд
        if (typeof window !== 'undefined') {
          window.location.href = '/admin/dashboard'
        }

        return {
          success: true,
          message: result.message,
          admin: result.admin,
        }
      }

      return {
        success: false,
        message: result.message,
      }
    } catch (error) {
      console.error('Error during admin login:', error)
      return {
        success: false,
        message: 'Ошибка при авторизации',
      }
    } finally {
      setIsLoading(false)
    }
  }

  const logout = () => {
    console.warn('useAdminAuth - Logging out')
    removeAdminToken()
    setAdmin(null)
    setIsAuthenticated(false)
    apolloClient.resetStore()

    // Перенаправляем на страницу входа администратора
    if (typeof window !== 'undefined') {
      window.location.href = '/admin'
    }
  }

  return {
    login,
    logout,
    admin,
    isAuthenticated,
    isLoading,
    checkAuth,
  }
}
