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

import {
  SEND_SMS_CODE,
  VERIFY_SMS_CODE,
  REGISTER_FULFILLMENT_ORGANIZATION,
  REGISTER_SELLER_ORGANIZATION,
  REGISTER_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 OrganizationRegistrationInput {
  phone: string
  type: 'FULFILLMENT' | 'SELLER' | 'LOGIST' | 'WHOLESALE'
  
  // Для бизнес-организаций (FULFILLMENT, LOGIST, WHOLESALE)
  inn?: string
  kpp?: string
  name?: string
  fullName?: string
  address?: string
  addressFull?: string
  ogrn?: string
  ogrnDate?: string
  managerName?: string
  managerEmail?: string
  managerPhone?: string
  description?: string
  logoUrl?: string
  website?: string
  bankName?: string
  bik?: string
  correspondentAccount?: string
  currentAccount?: string
  taxSystem?: string
  
  // Для селлеров (SELLER)
  wbApiKey?: string
  ozonApiKey?: string
  ozonClientId?: string
  
  // Общие поля
  referralCode?: string | null
  partnerCode?: string | null
}

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',
    referralCode?: string | null,
    partnerCode?: string | null,
  ) => Promise<{
    success: boolean
    message: string
    user?: User
  }>
  registerSellerOrganization: (data: {
    phone: string
    wbApiKey?: string
    ozonApiKey?: string
    ozonClientId?: string
    referralCode?: string | null
    partnerCode?: string | null
  }) => Promise<{
    success: boolean
    message: string
    user?: User
  }>

  // 🚀 Новая универсальная регистрация организации
  registerOrganization: (input: OrganizationRegistrationInput) => 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 [registerOrganizationMutation] = useMutation(REGISTER_ORGANIZATION) // 🚀 Новая мутация

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

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

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

    setIsCheckingAuth(true)

    try {
      console.warn('useAuth - Making GET_ME query')
      const { data } = await apolloClient.query({
        query: GET_ME,
        errorPolicy: 'all',
        fetchPolicy: 'network-only', // Всегда делаем свежий запрос
      })

      console.warn('useAuth - GET_ME response:', { data, me: data?.me })
      if (data?.me) {
        console.warn('useAuth - Setting user:', data.me)
        setUser(data.me)
        setIsAuthenticated(true)
        setUserData(data.me)
        
        // Форсируем обновление состояния
        console.warn('🔄 useAuth - State updated, user is now:', data.me)
      } else {
        console.warn('useAuth - No user data in response')
        setIsAuthenticated(false)
        setUser(null)
      }
    } catch (error: unknown) {
      console.warn('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)
    }
  }, [])

  // Убираем автоматический checkAuth из useEffect - он будет вызываться только из AuthGuard
  useEffect(() => {
    const token = getAuthToken()

    // Только устанавливаем состояние без токена
    if (!token) {
      setIsAuthenticated(false)
      setUser(null)
    }
  }, []) // Только один раз при монтировании

  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.warn('useAuth - Starting verifySmsCode mutation with:', { phone, code })

      const { data } = await verifySmsCodeMutation({
        variables: { phone, code },
      })

      console.warn('useAuth - GraphQL response data:', data)
      const result = data.verifySmsCode
      console.warn('useAuth - SMS verification result:', {
        success: result.success,
        hasToken: !!result.token,
        hasUser: !!result.user,
        message: result.message,
      })

      if (result.success && result.token && result.user) {
        // Сохраняем токен и данные пользователя
        console.warn('useAuth - Saving token:', result.token ? `${result.token.substring(0, 20)}...` : 'No token')
        setAuthToken(result.token)
        setUserData(result.user)

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

        // Проверяем что токен действительно сохранился
        const savedToken = typeof window !== 'undefined' ? localStorage.getItem('authToken') : null
        console.warn(
          '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',
    referralCode?: string | null,
    partnerCode?: string | null,
  ) => {
    console.warn('🎬 useAuth - registerFulfillmentOrganization вызван с параметрами:', {
      phone, inn, type, referralCode, partnerCode,
    })
    
    // 🔒 ROLLBACK CHECKPOINT: Сохраняем текущее состояние для восстановления
    const rollbackState = {
      previousUser: user,
      previousIsAuthenticated: isAuthenticated,
      previousToken: typeof window !== 'undefined' ? localStorage.getItem('authToken') : null,
    }
    
    console.warn('💾 useAuth - Rollback checkpoint saved:', {
      hasUser: !!rollbackState.previousUser,
      wasAuthenticated: rollbackState.previousIsAuthenticated,
      hasToken: !!rollbackState.previousToken,
    })
    
    try {
      setIsLoading(true)

      // Проверяем токен перед запросом
      const currentToken = typeof window !== 'undefined' ? localStorage.getItem('authToken') : null
      console.warn(
        'useAuth - Token before registerFulfillment request:',
        currentToken ? `${currentToken.substring(0, 20)}...` : 'No token',
      )

      console.warn('🎬 useAuth - Отправка GraphQL мутации с input:', {
        phone, inn, type, referralCode, partnerCode,
      })
      
      const { data } = await registerFulfillmentMutation({
        variables: {
          input: { phone, inn, type, referralCode, partnerCode },
        },
      })
      
      console.warn('🎬 useAuth - Ответ GraphQL мутации:', data)

      const result = data.registerFulfillmentOrganization

      if (result.success && result.user) {
        // Обновляем данные пользователя
        setUserData(result.user)
        console.warn('✅ useAuth - registerFulfillmentOrganization успешно завершена')

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

      console.warn('⚠️ useAuth - registerFulfillmentOrganization не успешна:', result.message)
      return {
        success: false,
        message: result.message,
      }
    } catch (error) {
      console.error('❌ useAuth - Error registering fulfillment organization:', error)
      
      // 🔄 ROLLBACK EXECUTION: Восстанавливаем предыдущее состояние при ошибке
      try {
        console.warn('🔄 useAuth - Executing rollback after fulfillment registration error')
        
        if (rollbackState.previousToken && rollbackState.previousToken !== (typeof window !== 'undefined' ? localStorage.getItem('authToken') : null)) {
          if (typeof window !== 'undefined') {
            localStorage.setItem('authToken', rollbackState.previousToken)
          }
          setAuthToken(rollbackState.previousToken)
        }
        
        if (rollbackState.previousUser) {
          setUser(rollbackState.previousUser)
          setUserData(rollbackState.previousUser)
        }
        
        setIsAuthenticated(rollbackState.previousIsAuthenticated)
        refreshApolloClient()
        
        console.warn('✅ useAuth - Rollback completed successfully')
      } catch (rollbackError) {
        console.error('🚨 useAuth - Critical error during rollback:', rollbackError)
      }
      
      return {
        success: false,
        message: 'Ошибка при регистрации фулфилмент организации',
      }
    } finally {
      setIsLoading(false)
    }
  }

  const registerSellerOrganization = async (data: {
    phone: string
    wbApiKey?: string
    ozonApiKey?: string
    ozonClientId?: string
    referralCode?: string | null
    partnerCode?: string | null
  }) => {
    console.warn('🛍️ useAuth - registerSellerOrganization вызван с параметрами:', {
      phone: data.phone,
      hasWbApiKey: !!data.wbApiKey,
      hasOzonApiKey: !!data.ozonApiKey,
      referralCode: data.referralCode,
      partnerCode: data.partnerCode,
    })
    
    // 🔒 ROLLBACK CHECKPOINT: Сохраняем текущее состояние для восстановления
    const rollbackState = {
      previousUser: user,
      previousIsAuthenticated: isAuthenticated,
      previousToken: typeof window !== 'undefined' ? localStorage.getItem('authToken') : null,
    }
    
    console.warn('💾 useAuth - Rollback checkpoint saved for seller:', {
      hasUser: !!rollbackState.previousUser,
      wasAuthenticated: rollbackState.previousIsAuthenticated,
      hasToken: !!rollbackState.previousToken,
    })
    
    try {
      setIsLoading(true)
      
      console.warn('🛍️ useAuth - Отправка GraphQL мутации registerSellerOrganization')
      const { data: result } = await registerSellerMutation({
        variables: { input: data },
      })
      
      console.warn('🛍️ useAuth - Ответ GraphQL мутации:', result)
      const registerResult = result.registerSellerOrganization

      if (registerResult.success && registerResult.user) {
        // Обновляем данные пользователя
        setUserData(registerResult.user)
        console.warn('✅ useAuth - registerSellerOrganization успешно завершена')

        return {
          success: true,
          message: registerResult.message,
          user: registerResult.user,
        }
      }

      console.warn('⚠️ useAuth - registerSellerOrganization не успешна:', registerResult.message)
      return {
        success: false,
        message: registerResult.message,
      }
    } catch (error) {
      console.error('❌ useAuth - Error registering seller organization:', error)
      
      // 🔄 ROLLBACK EXECUTION: Восстанавливаем предыдущее состояние при ошибке
      try {
        console.warn('🔄 useAuth - Executing rollback after seller registration error')
        
        if (rollbackState.previousToken && rollbackState.previousToken !== (typeof window !== 'undefined' ? localStorage.getItem('authToken') : null)) {
          if (typeof window !== 'undefined') {
            localStorage.setItem('authToken', rollbackState.previousToken)
          }
          setAuthToken(rollbackState.previousToken)
        }
        
        if (rollbackState.previousUser) {
          setUser(rollbackState.previousUser)
          setUserData(rollbackState.previousUser)
        }
        
        setIsAuthenticated(rollbackState.previousIsAuthenticated)
        refreshApolloClient()
        
        console.warn('✅ useAuth - Rollback completed successfully for seller')
      } catch (rollbackError) {
        console.error('🚨 useAuth - Critical error during seller rollback:', rollbackError)
      }
      
      return {
        success: false,
        message: 'Ошибка при регистрации селлер организации',
      }
    } finally {
      setIsLoading(false)
    }
  }

  // 🚀 Новая универсальная функция регистрации организации
  const registerOrganization = async (input: OrganizationRegistrationInput) => {
    console.warn('🚀 useAuth - registerOrganization (NEW) вызван с параметрами:', {
      phone: input.phone,
      type: input.type,
      hasInn: !!input.inn,
      hasWbApiKey: !!input.wbApiKey,
      hasOzonApiKey: !!input.ozonApiKey,
      referralCode: input.referralCode,
      partnerCode: input.partnerCode,
    })

    // 🔒 ROLLBACK CHECKPOINT: Сохраняем текущее состояние для восстановления
    const rollbackState = {
      previousUser: user,
      previousIsAuthenticated: isAuthenticated,
      previousToken: typeof window !== 'undefined' ? localStorage.getItem('authToken') : null,
    }

    console.warn('💾 useAuth - Rollback checkpoint saved for universal registration:', {
      hasUser: !!rollbackState.previousUser,
      wasAuthenticated: rollbackState.previousIsAuthenticated,
      hasToken: !!rollbackState.previousToken,
    })

    try {
      setIsLoading(true)

      console.warn('🚀 useAuth - Отправка GraphQL мутации registerOrganization (NEW)')
      const { data } = await registerOrganizationMutation({
        variables: { input },
      })

      console.warn('🚀 useAuth - Ответ GraphQL мутации registerOrganization (NEW):', data)
      const result = data.registerOrganization

      if (result.success && result.user && result.token) {
        // Обновляем данные пользователя и токен
        setAuthToken(result.token)
        setUserData(result.user)
        setUser(result.user)
        setIsAuthenticated(true)

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

        console.warn('✅ useAuth - registerOrganization (NEW) успешно завершена:', {
          userId: result.user.id,
          organizationType: result.user.organization?.type,
          organizationName: result.user.organization?.name,
        })

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

      console.warn('⚠️ useAuth - registerOrganization (NEW) не успешна:', result.message)
      return {
        success: false,
        message: result.message,
      }
    } catch (error) {
      console.error('❌ useAuth - Error in registerOrganization (NEW):', error)

      // 🔄 ROLLBACK EXECUTION: Восстанавливаем предыдущее состояние при ошибке
      try {
        console.warn('🔄 useAuth - Executing rollback after registerOrganization (NEW) error')

        if (rollbackState.previousToken && rollbackState.previousToken !== (typeof window !== 'undefined' ? localStorage.getItem('authToken') : null)) {
          if (typeof window !== 'undefined') {
            localStorage.setItem('authToken', rollbackState.previousToken)
          }
          setAuthToken(rollbackState.previousToken)
        }

        if (rollbackState.previousUser) {
          setUser(rollbackState.previousUser)
          setUserData(rollbackState.previousUser)
        }

        setIsAuthenticated(rollbackState.previousIsAuthenticated)
        refreshApolloClient()

        console.warn('✅ useAuth - Rollback completed successfully for registerOrganization (NEW)')
      } catch (rollbackError) {
        console.error('🚨 useAuth - Critical error during registerOrganization rollback:', rollbackError)
      }

      return {
        success: false,
        message: 'Ошибка при регистрации организации',
      }
    } finally {
      setIsLoading(false)
    }
  }

  const logout = () => {
    console.warn('useAuth - Logging out')
    removeAuthToken()
    setUser(null)
    setIsAuthenticated(false)
    refreshApolloClient()

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

  return {
    // SMS методы
    sendSmsCode,
    verifySmsCode,

    // Регистрация организаций
    registerFulfillmentOrganization,
    registerSellerOrganization,
    registerOrganization, // 🚀 Новая универсальная функция

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