'use client'

import { ReactNode, createContext, useEffect, useState } from 'react'

import { useCustomMutation, useCustomQuery } from '@/hooks/api'
import { request } from '@/utils'
import authConfig from '@/configs/auth'
import { AuthValuesType, ILoginParams, ILoginResponse, ILogoutResponse, IProfileResponse } from '@/types/context'
import { IUser } from '@/types/data'
import { StaticKey } from '@/@core/types/static-key.enum'
import { useParams, useRouter } from 'next/navigation'
import { getCookie, deleteCookie, setCookie } from 'cookies-next/client'
import { toast } from 'react-toastify'
import { useTranslations } from 'next-intl'

const defaultProvider: AuthValuesType = {
  loading: true,
  setLoading: () => Boolean,
  isPending: false,
  user: null,
  setUser: () => null
}

const AuthContext = createContext(defaultProvider)

type Props = {
  children: ReactNode
}

const AuthProvider = ({ children }: Props) => {
  const router = useRouter()
  const t = useTranslations('')
  const { lang } = useParams()

  // ** States
  const [user, setUser] = useState<IUser | null>(null)
  const [loading, setLoading] = useState<boolean>(true)

  const profileQuery = useCustomQuery<IProfileResponse, [string], IProfileResponse>(
    ['profile'],
    () =>
      request<IProfileResponse>({
        url: authConfig.meEndpoint,
        method: 'GET'
      }),
    {
      retry: false, // Avoid unnecessary retries
      enabled: !!getCookie(StaticKey.ACCESS_TOKEN) || !!getCookie(StaticKey.CURRENT_USER) // Only fetch if token exists
    }
  )

  // Handle profile fetching and authentication state
  useEffect(() => {
    if (profileQuery.isSuccess) {
      setUser(profileQuery?.data?.data?.user ?? null)
      setCookie(StaticKey.CURRENT_USER, JSON.stringify(profileQuery.data?.data))
    } else if (profileQuery.isError) {
      // deleteCookie(StaticKey.CURRENT_USER)
      // deleteCookie(StaticKey.ACCESS_TOKEN)
      // setUser(null)
      // router.replace(`/${lang}/login`)
    }
    setLoading(false) // Ensure loading is updated only once
  }, [profileQuery.isSuccess, profileQuery.isError])

  // Login mutation
  const loginMutation = useCustomMutation<ILoginParams, ILoginResponse>(
    ['login'],
    data =>
      request<ILoginResponse, ILoginParams>({
        url: authConfig.loginEndpoint,
        method: 'POST',
        data,
        withToken: false
      }),
    {
      onSuccess: async ({ data }) => {
        setCookie(StaticKey.ACCESS_TOKEN, data?.token)
        setCookie(StaticKey.CURRENT_USER, data?.user)
        setCookie('userRole', data?.user?.account_type as any)

        toast.success(t('MESSAGES.LOGIN_SUCCESS'))
        await profileQuery.refetch()
        window.location.href = `/${lang}/`
      },
      onError: async data => {
        if (data?.status !== 200) {
          toast.error(t('MESSAGES.LOGIN_ERROR'))
        }
      }
    }
  )

  // Login mutation
  const loginFirebaseMutation = useCustomMutation<{ identifier: string }, ILoginResponse>(
    ['login-firebase'],
    data =>
      request<ILoginResponse, { identifier: string }>({
        url: authConfig.loginFireBaseEndpoint,
        method: 'POST',
        data,
        withToken: false
      }),
    {
      // toastMessageType: 'promise',
      onSuccess: async ({ data }) => {
        setCookie(StaticKey.ACCESS_TOKEN, data?.token)
        setCookie(StaticKey.CURRENT_USER, data?.user)
        toast.success(t('MESSAGES.LOGIN_SUCCESS'))
        await profileQuery.refetch()
        window.location.href = `/${lang}/`
      },
      onError: async data => {
        if (data?.status !== 200) {
          toast.error(t('MESSAGES.FIREBASE_ERROR'))
        }
      }
    }
  )

  // Logout mutation
  const logoutMutation = useCustomMutation<ILogoutResponse>(
    ['logout'],
    () =>
      request<ILogoutResponse>({
        url: authConfig.logoutEndpoint,
        method: 'POST'
      }),
    {
      toastMessageType: 'promise',
      onSuccess: () => {
        deleteCookie(StaticKey.CURRENT_USER)
        deleteCookie(StaticKey.ACCESS_TOKEN)
        setUser(null)
        router.push(`/${lang}/login`)
      }
    }
  )
  const logoutAllMutation = useCustomMutation<ILogoutResponse>(
    ['logout-all'],
    () =>
      request<ILogoutResponse>({
        url: authConfig.logoutAllEndPoint,
        method: 'POST'
      }),
    {
      toastMessageType: 'promise',
      onSuccess: () => {
        deleteCookie(StaticKey.CURRENT_USER)
        deleteCookie(StaticKey.ACCESS_TOKEN)
        setUser(null)
        router.push(`/${lang}/login`)
      }
    }
  )

  // Check authentication on mount
  useEffect(() => {
    const accessToken = getCookie(StaticKey.ACCESS_TOKEN)
    if (!accessToken) {
      setLoading(false) // No token, no need to fetch profile
    }
  }, [])

  const values: AuthValuesType = {
    loading,
    setLoading,
    isPending: profileQuery.isFetching,
    user,
    setUser,
    logout: logoutMutation,
    logoutAll: logoutAllMutation,
    login: loginMutation,
    loginFireBase: loginFirebaseMutation
  }

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

export { AuthContext, AuthProvider }
