'use client'

import { useMutation } from '@apollo/client'
import { createContext, useContext, useState, useEffect, useCallback, useRef, ReactNode } 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 { useApolloRefresh } from '@/hooks/useApolloRefresh'
import { setAuthToken, setUserData, removeAuthToken, getAuthToken, apolloClient } from '@/lib/apollo-client'

// Types from useAuth.ts
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 AuthContextType {
  // 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
}

const AuthContext = createContext<AuthContextType | undefined>(undefined)

interface AuthProviderProps {
  children: ReactNode
}

export function AuthProvider({ children }: AuthProviderProps) {
  // Состояние аутентификации
  const [isLoading, setIsLoading] = useState(true) // ИЗМЕНЕНО: Начинаем с true для начальной загрузки
  const [user, setUser] = useState<User | null>(null)
  const [isAuthenticated, setIsAuthenticated] = useState(() => {
    // Проверяем наличие токена при инициализации
    return !!getAuthToken()
  })
  const [isCheckingAuth, setIsCheckingAuth] = useState(false) // Защита от повторных вызовов
  const [isInitialized, setIsInitialized] = useState(false) // Новый флаг для отслеживания инициализации
  const { refreshApolloClient } = useApolloRefresh()

  // GraphQL мутации
  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 updateUser = (updatedUser: Partial<User>) => {
    setUser((currentUser) => {
      if (!currentUser) return currentUser
      return { ...currentUser, ...updatedUser }
    })
  }

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

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

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

    setIsCheckingAuth(true)

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

      console.warn('AuthContext - GET_ME response:', { data, me: data?.me })
      if (data?.me) {
        console.warn('AuthContext - Setting user:', data.me)
        setUser(data.me)
        setIsAuthenticated(true)
        setUserData(data.me)
        
        // Форсируем обновление состояния
        console.warn('🔄 AuthContext - State updated, user is now:', data.me)
      } else {
        console.warn('AuthContext - No user data in response')
        setIsAuthenticated(false)
        setUser(null)
      }
    } catch (error: unknown) {
      console.warn('AuthContext - 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 initAuth = async () => {
      const token = getAuthToken()
      
      console.warn('🔐 AuthContext - Initialization started:', {
        hasToken: !!token,
        timestamp: new Date().toISOString()
      })

      if (token) {
        // Если есть токен, проверяем пользователя
        await checkAuth()
      } else {
        // Только устанавливаем состояние без токена
        setIsAuthenticated(false)
        setUser(null)
      }
      
      setIsLoading(false)
      setIsInitialized(true)
      console.warn('🔐 AuthContext - Initialization complete:', {
        isAuthenticated,
        hasUser: !!user,
        timestamp: new Date().toISOString()
      })
    }
    
    if (!isInitialized) {
      initAuth()
    }
  }, []) // Только при первом монтировании

  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('🔑 AuthContext - Starting SMS verification:', { phone, code })
      console.warn('🔑 AuthContext - BEFORE setState:', { 
        isAuthenticated: isAuthenticated, 
        hasUser: !!user,
        currentUser: user ? { id: user.id, hasOrganization: !!user.organization } : null,
      })

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

      console.warn('🔑 AuthContext - GraphQL response received:', data)
      const result = data.verifySmsCode
      console.warn('🔑 AuthContext - SMS verification result:', {
        success: result.success,
        hasToken: !!result.token,
        hasUser: !!result.user,
        userOrganization: result.user?.organization ? 'exists' : 'null',
        message: result.message,
      })

      if (result.success && result.token && result.user) {
        console.warn('🔑 AuthContext - SUCCESS: Saving token and updating state')
        
        // Сохраняем токен и данные пользователя
        console.warn('🔑 AuthContext - Step 1: Saving to localStorage/apollo')
        setAuthToken(result.token)
        setUserData(result.user)

        // Обновляем состояние контекста
        console.warn('🔑 AuthContext - Step 2: Updating React state')
        setUser(result.user)
        setIsAuthenticated(true)
        
        console.warn('🔑 AuthContext - AFTER setState:', { 
          isAuthenticated: true, 
          hasUser: !!result.user,
          userOrganization: result.user.organization,
          userId: result.user.id,
        })

        // Проверяем что токен действительно сохранился
        const savedToken = typeof window !== 'undefined' ? localStorage.getItem('authToken') : null
        console.warn('🔑 AuthContext - Step 3: Verification - Token saved to localStorage:', !!savedToken)

        // Принудительно обновляем Apollo Client
        console.warn('🔑 AuthContext - Step 4: Refreshing Apollo Client')
        await refreshApolloClient() // ДОБАВЛЕН await
        
        // Добавляем небольшую задержку для гарантии обновления React состояния
        console.warn('🔑 AuthContext - Step 5: Waiting for state propagation')
        await new Promise(resolve => setTimeout(resolve, 50))
        
        console.warn('🔑 AuthContext - SUCCESS COMPLETE: All steps finished, returning user data')
        console.warn('🔑 AuthContext - Final state check:', {
          willReturnUser: !!result.user,
          userHasOrganization: !!result.user.organization,
          timestamp: new Date().toISOString(),
        })

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

      console.warn('🔑 AuthContext - FAILURE: SMS verification failed or missing data')
      return {
        success: false,
        message: result.message,
      }
    } catch (error) {
      console.error('🔑 AuthContext - ERROR in verifySmsCode:', error)
      return {
        success: false,
        message: 'Ошибка при проверке SMS кода',
      }
    } finally {
      console.warn('🔑 AuthContext - Cleaning up: setIsLoading(false)')
      setIsLoading(false)
    }
  }

  const registerFulfillmentOrganization = async (
    phone: string,
    inn: string,
    type: 'FULFILLMENT' | 'LOGIST' | 'WHOLESALE',
    referralCode?: string | null,
    partnerCode?: string | null,
  ) => {
    console.warn('🎬 AuthContext - registerFulfillmentOrganization вызван с параметрами:', {
      phone, inn, type, referralCode, partnerCode,
    })
    
    // Rollback checkpoint
    const rollbackState = {
      previousUser: user,
      previousIsAuthenticated: isAuthenticated,
      previousToken: typeof window !== 'undefined' ? localStorage.getItem('authToken') : null,
    }
    
    try {
      setIsLoading(true)

      const { data } = await registerFulfillmentMutation({
        variables: {
          input: { phone, inn, type, referralCode, partnerCode },
        },
      })
      
      const result = data.registerFulfillmentOrganization

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

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

      return {
        success: false,
        message: result.message,
      }
    } catch (error) {
      console.error('❌ AuthContext - Error registering fulfillment organization:', error)
      
      // Rollback on error
      try {
        if (rollbackState.previousToken) {
          setAuthToken(rollbackState.previousToken)
        }
        
        if (rollbackState.previousUser) {
          setUser(rollbackState.previousUser)
          setUserData(rollbackState.previousUser)
        }
        
        setIsAuthenticated(rollbackState.previousIsAuthenticated)
        refreshApolloClient()
      } catch (rollbackError) {
        console.error('🚨 AuthContext - 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('🛍️ AuthContext - registerSellerOrganization вызван')
    
    // Rollback checkpoint
    const rollbackState = {
      previousUser: user,
      previousIsAuthenticated: isAuthenticated,
      previousToken: typeof window !== 'undefined' ? localStorage.getItem('authToken') : null,
    }
    
    try {
      setIsLoading(true)
      
      const { data: result } = await registerSellerMutation({
        variables: { input: data },
      })
      
      const registerResult = result.registerSellerOrganization

      if (registerResult.success && registerResult.user) {
        // Обновляем данные пользователя
        setUserData(registerResult.user)
        setUser(registerResult.user)

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

      return {
        success: false,
        message: registerResult.message,
      }
    } catch (error) {
      console.error('❌ AuthContext - Error registering seller organization:', error)
      
      // Rollback on error
      try {
        if (rollbackState.previousToken) {
          setAuthToken(rollbackState.previousToken)
        }
        
        if (rollbackState.previousUser) {
          setUser(rollbackState.previousUser)
          setUserData(rollbackState.previousUser)
        }
        
        setIsAuthenticated(rollbackState.previousIsAuthenticated)
        refreshApolloClient()
      } catch (rollbackError) {
        console.error('🚨 AuthContext - Critical error during seller rollback:', rollbackError)
      }
      
      return {
        success: false,
        message: 'Ошибка при регистрации селлер организации',
      }
    } finally {
      setIsLoading(false)
    }
  }

  // Универсальная функция регистрации организации
  const registerOrganization = async (input: OrganizationRegistrationInput) => {
    console.warn('🚀 AuthContext - registerOrganization (NEW) вызван:', input.type)

    // Rollback checkpoint
    const rollbackState = {
      previousUser: user,
      previousIsAuthenticated: isAuthenticated,
      previousToken: typeof window !== 'undefined' ? localStorage.getItem('authToken') : null,
    }

    try {
      setIsLoading(true)

      const { data } = await registerOrganizationMutation({
        variables: { input },
      })

      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()

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

      return {
        success: false,
        message: result.message,
      }
    } catch (error) {
      console.error('❌ AuthContext - Error in registerOrganization (NEW):', error)

      // Rollback on error
      try {
        if (rollbackState.previousToken) {
          setAuthToken(rollbackState.previousToken)
        }

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

        setIsAuthenticated(rollbackState.previousIsAuthenticated)
        refreshApolloClient()
      } catch (rollbackError) {
        console.error('🚨 AuthContext - Critical error during registerOrganization rollback:', rollbackError)
      }

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

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

    // Делаем redirect только на клиенте, асинхронно для избежания SSR проблем
    setTimeout(() => {
      if (typeof window !== 'undefined') {
        window.location.href = '/'
      }
    }, 0)
  }

  const value: AuthContextType = {
    // SMS методы
    sendSmsCode,
    verifySmsCode,

    // Регистрация организаций
    registerFulfillmentOrganization,
    registerSellerOrganization,
    registerOrganization,

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

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}

// Hook для использования AuthContext
export function useAuthContext() {
  const context = useContext(AuthContext)
  if (context === undefined) {
    throw new Error('useAuthContext must be used within an AuthProvider')
  }
  return context
}