import type { FormEvent, MouseEvent } from 'react'

import {
  useRef,
  useState,
  useEffect,
} from 'react'

import isObject from 'lodash/isObject'

import { redirectToUrl } from 'helpers'

import { useLocalStore } from 'hooks'

import type { Settings } from 'features/AuthStore/helpers'
import { loginCheck } from 'features/AuthServiceApp/requests/auth'
import { resendConfirmation } from 'features/AuthServiceApp/requests/resendConfirmation'
import { getApiUrl } from 'features/AuthServiceApp/config/routes'
import { useAuthFields } from 'features/AuthServiceApp/hooks/useAuthFields'

import { addAccessTokenToUrl } from 'helpers/languageUrlParam'

import { AuthProviders } from '../../config/authProviders'
import { getAuthUrl } from '../../helpers/getAuthUrl'
import { useParamsUrl } from '../../hooks/useParamsUrl'

const url = getApiUrl('/authorize')

export const useLoginForm = () => {
  const urlParams = useParamsUrl()
  const {
    client_id,
    lang,
    redirect_uri,
    response_mode,
    response_type,
    scope,
  } = urlParams

  const [authError, setAuthError] = useState('')
  const [resendConfirm, setResendConfirm] = useState(false)
  const [isFetching, setIsFetching] = useState(false)
  const [isRecoveryPopupOpen, setIsRecoveryPopupOpen] = useState(false)
  const [isModalOpen, setIsModalOpen] = useState(false)

  const formRef = useRef<HTMLFormElement>(null)
  const {
    email,
    error: formError,
    onEmailBlur,
    onEmailChange,
    onPasswordBlur,
    onPasswordChange,
    password,
  } = useAuthFields('login')

  const [, setUrlParams] = useLocalStore<Partial<Settings>>({
    defaultValue: {},
    key: 'urlParams',
    validator: isObject,
  })

  const isSubmitDisabled = (
    !email
    || !password
    || Boolean(formError)
    || Boolean(authError)
    || isFetching
  )

  const handleModalOpen = () => {
    setIsRecoveryPopupOpen(true)
  }

  const submitForm = () => formRef.current?.submit()

  const handleError = (error: string) => {
    setAuthError(error)
    setIsFetching(false)

    if (error === 'error_user_not_confirm') {
      setResendConfirm(true)
    }
  }

  const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    setIsFetching(true)
    try {
      await loginCheck({
        email,
        password,
        urlParams: {
          client_id,
          lang,
          redirect_uri,
          response_mode,
          response_type,
          scope,
        },
      })
      submitForm()
    } catch (err) {
      handleError(String(err))
    }
  }

  const handleResendConfirm = async () => {
    setIsFetching(true)
    try {
      await resendConfirmation({
        email,
        urlParams,
      })
      setAuthError('')
      setIsFetching(false)
      setIsModalOpen(true)
    } catch (err) {
      handleError(String(err))
      setIsFetching(false)
    }
  }

  const handleModalClose = () => {
    setIsModalOpen(false)
  }

  const handleAuthButtonClick = (authProvider: AuthProviders) => (
    e: MouseEvent<HTMLButtonElement>,
  ) => {
    e.preventDefault()

    const authUrl = getAuthUrl(authProvider, urlParams)

    setUrlParams(urlParams)
    redirectToUrl(authUrl)
  }

  useEffect(() => {
    setAuthError('')
  }, [email, password])

  return {
    authError,
    client_id,
    email,
    formError,
    formRef,
    handleAuthButtonClick,
    handleModalClose,
    handleModalOpen,
    handleResendConfirm,
    handleSubmit,
    isFetching,
    isModalOpen,
    isRecoveryPopupOpen,
    isSubmitDisabled,
    lang,
    onEmailBlur,
    onEmailChange,
    onPasswordBlur,
    onPasswordChange,
    password,
    redirect_uri,
    resendConfirm,
    response_mode,
    response_type,
    scope,
    setIsRecoveryPopupOpen,
    url: addAccessTokenToUrl(url),
  }
}
