import { useMutation } from '@apollo/client'
import { useState, useEffect } from 'react'
import { 
  SEND_SMS_CODE, 
  VERIFY_SMS_CODE, 
  REGISTER_FULFILLMENT_ORGANIZATION,
  REGISTER_SELLER_ORGANIZATION
} from '@/graphql/mutations'
import { GET_ME } from '@/graphql/queries'
import { setAuthToken, setUserData, removeAuthToken, getAuthToken, apolloClient } from '@/lib/apollo-client'
import { useApolloRefresh } from './useApolloRefresh'

interface User {
  id: string
  phone: string
  avatar?: string
  managerName?: string
  createdAt?: string
  organization?: {
    id: string
    inn: string
    kpp?: string
    name?: string
    fullName?: string
    address?: string
    addressFull?: string
    ogrn?: string
    ogrnDate?: string
    status?: string
    actualityDate?: string
    registrationDate?: string
    liquidationDate?: string
    managementName?: string
    managementPost?: string
    opfCode?: string
    opfFull?: string
    opfShort?: string
    okato?: string
    oktmo?: string
    okpo?: string
    okved?: string
    employeeCount?: number
    revenue?: string
    taxSystem?: string
    phones?: unknown
    emails?: unknown
    type: 'FULFILLMENT' | 'SELLER' | 'LOGIST' | 'WHOLESALE'
    apiKeys: Array<{
      id: string
      marketplace: 'WILDBERRIES' | 'OZON'
      isActive: boolean
      validationData?: unknown
    }>
  }
}

interface UseAuthReturn {
  // SMS методы
  sendSmsCode: (phone: string) => Promise<{ success: boolean; message: string }>
  verifySmsCode: (phone: string, code: string) => Promise<{ 
    success: boolean
    message: string
    user?: User
  }>
  
  // Регистрация организаций
  registerFulfillmentOrganization: (phone: string, inn: string, type: 'FULFILLMENT' | 'LOGIST' | 'WHOLESALE') => Promise<{
    success: boolean
    message: string
    user?: User
  }>
  registerSellerOrganization: (data: {
    phone: string
    wbApiKey?: string
    ozonApiKey?: string
    ozonClientId?: string
  }) => Promise<{
    success: boolean
    message: string
    user?: User
  }>

  // Состояние
  user: User | null
  isAuthenticated: boolean
  isLoading: boolean
  checkAuth: () => Promise<void>
  updateUser: (updatedUser: Partial<User>) => void
  logout: () => void
}

export const useAuth = (): UseAuthReturn => {
  // Инициализируем состояния с проверкой токена
  const [isLoading, setIsLoading] = useState(false)
  const [user, setUser] = useState<User | null>(null)
  const [isAuthenticated, setIsAuthenticated] = useState(() => {
    // Проверяем наличие токена при инициализации
    return !!getAuthToken()
  })
  const [isCheckingAuth, setIsCheckingAuth] = useState(false) // Защита от повторных вызовов
  const { refreshApolloClient } = useApolloRefresh()

  // Функция для обновления данных пользователя
  const updateUser = (updatedUser: Partial<User>) => {
    setUser(currentUser => {
      if (!currentUser) return currentUser
      return { ...currentUser, ...updatedUser }
    })
  }

  const [sendSmsCodeMutation] = useMutation(SEND_SMS_CODE)
  const [verifySmsCodeMutation] = useMutation(VERIFY_SMS_CODE)
  const [registerFulfillmentMutation] = useMutation(REGISTER_FULFILLMENT_ORGANIZATION)
  const [registerSellerMutation] = useMutation(REGISTER_SELLER_ORGANIZATION)

  // Проверка авторизации при инициализации
  const checkAuth = async () => {
    if (isCheckingAuth) {
      console.log('useAuth - checkAuth already in progress, skipping')
      return
    }

    const token = getAuthToken()
    console.log('useAuth - checkAuth called, token exists:', !!token)
    
    if (!token) {
      setIsAuthenticated(false)
      setUser(null)
      setIsCheckingAuth(false)
      return
    }

    setIsCheckingAuth(true)
    
    try {
      console.log('useAuth - Making GET_ME query')
      const { data } = await apolloClient.query({
        query: GET_ME,
        errorPolicy: 'all',
        fetchPolicy: 'network-only' // Всегда делаем свежий запрос
      })
      
      console.log('useAuth - GET_ME response:', !!data?.me)
      if (data?.me) {
        setUser(data.me)
        setIsAuthenticated(true)
        setUserData(data.me)
        console.log('useAuth - User authenticated:', data.me.phone)
      } else {
        setIsAuthenticated(false)
        setUser(null)
      }
    } catch (error: unknown) {
      console.log('useAuth - GET_ME error:', error)
      if ((error as { graphQLErrors?: Array<{ extensions?: { code?: string } }> })?.graphQLErrors?.some((e) => e.extensions?.code === 'UNAUTHENTICATED')) {
        logout()
      } else {
        setIsAuthenticated(false)
        setUser(null)
      }
    } finally {
      setIsCheckingAuth(false)
    }
  }

  // Проверяем авторизацию при загрузке компонента только если нет данных пользователя
  useEffect(() => {
    const token = getAuthToken()
    console.log('useAuth - useEffect init, token exists:', !!token, 'user exists:', !!user, 'isChecking:', isCheckingAuth)
    
    if (token && !user && !isCheckingAuth) {
      console.log('useAuth - Running checkAuth because token exists but no user data')
      checkAuth()
    } else if (!token) {
      console.log('useAuth - No token, setting unauthenticated state')
      setIsAuthenticated(false)
      setUser(null)
    }
  }, []) // eslint-disable-line react-hooks/exhaustive-deps

  const sendSmsCode = async (phone: string) => {
    try {
      setIsLoading(true)
      const { data } = await sendSmsCodeMutation({
        variables: { phone }
      })
      
      return {
        success: data.sendSmsCode.success,
        message: data.sendSmsCode.message
      }
    } catch (error) {
      console.error('Error sending SMS code:', error)
      return {
        success: false,
        message: 'Ошибка при отправке SMS кода'
      }
    } finally {
      setIsLoading(false)
    }
  }

  const verifySmsCode = async (phone: string, code: string) => {
    try {
      setIsLoading(true)
      console.log('useAuth - Starting verifySmsCode mutation with:', { phone, code })
      
      const { data } = await verifySmsCodeMutation({
        variables: { phone, code }
      })

      console.log('useAuth - GraphQL response data:', data)
      const result = data.verifySmsCode
      console.log('useAuth - SMS verification result:', { 
        success: result.success,
        hasToken: !!result.token,
        hasUser: !!result.user,
        message: result.message 
      })
      
      if (result.success && result.token && result.user) {
        // Сохраняем токен и данные пользователя
        console.log('useAuth - Saving token:', result.token ? `${result.token.substring(0, 20)}...` : 'No token')
        setAuthToken(result.token)
        setUserData(result.user)
        
        // Обновляем состояние хука
        setUser(result.user)
        setIsAuthenticated(true)
        console.log('useAuth - State updated: user set, isAuthenticated=true')
        
        // Проверяем что токен действительно сохранился
        const savedToken = typeof window !== 'undefined' ? localStorage.getItem('authToken') : null
        console.log('useAuth - Token saved to localStorage:', savedToken ? `${savedToken.substring(0, 20)}...` : 'Not saved')
        
        // Принудительно обновляем Apollo Client
        refreshApolloClient()
        
        return {
          success: true,
          message: result.message,
          user: result.user
        }
      }

      return {
        success: false,
        message: result.message
      }
    } catch (error) {
      console.error('Error verifying SMS code:', error)
      console.error('Error details:', {
        message: error instanceof Error ? error.message : 'Unknown error',
        graphQLErrors: (error as { graphQLErrors?: unknown })?.graphQLErrors,
        networkError: (error as { networkError?: unknown })?.networkError
      })
      return {
        success: false,
        message: 'Ошибка при проверке SMS кода'
      }
    } finally {
      setIsLoading(false)
    }
  }

  const registerFulfillmentOrganization = async (phone: string, inn: string, type: 'FULFILLMENT' | 'LOGIST' | 'WHOLESALE') => {
    try {
      setIsLoading(true)
      
      // Проверяем токен перед запросом
      const currentToken = typeof window !== 'undefined' ? localStorage.getItem('authToken') : null
      console.log('useAuth - Token before registerFulfillment request:', currentToken ? `${currentToken.substring(0, 20)}...` : 'No token')
      
      const { data } = await registerFulfillmentMutation({
        variables: {
          input: { phone, inn, type }
        }
      })

      const result = data.registerFulfillmentOrganization
      
      if (result.success && result.user) {
        // Обновляем данные пользователя
        setUserData(result.user)
        
        return {
          success: true,
          message: result.message,
          user: result.user
        }
      }

      return {
        success: false,
        message: result.message
      }
    } catch (error) {
      console.error('Error registering fulfillment organization:', error)
      return {
        success: false,
        message: 'Ошибка при регистрации фулфилмент организации'
      }
    } finally {
      setIsLoading(false)
    }
  }

  const registerSellerOrganization = async (data: {
    phone: string
    wbApiKey?: string
    ozonApiKey?: string
    ozonClientId?: string
  }) => {
    try {
      setIsLoading(true)
      const { data: result } = await registerSellerMutation({
        variables: { input: data }
      })

      const registerResult = result.registerSellerOrganization
      
      if (registerResult.success && registerResult.user) {
        // Обновляем данные пользователя
        setUserData(registerResult.user)
        
        return {
          success: true,
          message: registerResult.message,
          user: registerResult.user
        }
      }

      return {
        success: false,
        message: registerResult.message
      }
    } catch (error) {
      console.error('Error registering seller organization:', error)
      return {
        success: false,
        message: 'Ошибка при регистрации селлер организации'
      }
    } finally {
      setIsLoading(false)
    }
  }

  const logout = () => {
    console.log('useAuth - Logging out')
    removeAuthToken()
    setUser(null)
    setIsAuthenticated(false)
    refreshApolloClient()
    
    // Перенаправляем на главную страницу
    if (typeof window !== 'undefined') {
      window.location.href = '/'
    }
  }

  return {
    // SMS методы  
    sendSmsCode,
    verifySmsCode,
    
    // Регистрация организаций
    registerFulfillmentOrganization,
    registerSellerOrganization,

    // Состояние
    user,
    isAuthenticated,
    isLoading,
    checkAuth,
    updateUser,
    logout
  }
} 