import { useCallback, useMemo } from 'react'

import trim from 'lodash/trim'
import find from 'lodash/find'
import map from 'lodash/map'

import { formIds } from 'config/form'
import { AUTH_SERVICE } from 'config/routes'

import { useForm } from 'features/FormStore'
import { useLexicsStore } from 'features/LexicsStore'
import { useAuthStore } from 'features/AuthStore'

import { SaveUserInfo } from 'requests'

import { readToken } from 'helpers/token'

import { useUserInfoForm } from './useUserInfoForm'
import { useValidateForm } from './useValidateForm'

export type Lang = {
  id: string,
  name: string,
}

export type Props = {
  loader?: boolean,
  onSubmit: (data: SaveUserInfo) => void,
}

export const useUserInfo = ({ loader, onSubmit }: Props) => {
  const { languageList } = useLexicsStore()
  const { userInfo } = useAuthStore()
  const {
    hasChanges,
    readFormError,
    readFormValue,
    updateFormValue,
  } = useForm()
  const token = readToken()
  const validateForm = useValidateForm()
  const { onPhoneBlur } = useUserInfoForm()
  const readTrimmedValue = useCallback(
    (fieldName: string) => trim(readFormValue(fieldName)) || null,
    [readFormValue],
  )
  const readNumberValue = useCallback(
    (fieldName: string) => {
      const value = readTrimmedValue(fieldName)
      return value ? Number(value) : null
    },
    [readTrimmedValue],
  )
  const handleSubmit = useCallback(() => {
    if (validateForm()) {
      const firstname = readTrimmedValue(formIds.firstname)
      const lastname = readTrimmedValue(formIds.lastname)
      const language_id = find(
        languageList,
        (language) => language.iso_639_1 === readTrimmedValue(formIds.language),
      )?.id ?? null
      const phone = readTrimmedValue(formIds.phone)
      const postalCode = readNumberValue(formIds.postalCode)
      const region = readTrimmedValue(formIds.region)
      const address_line1 = readTrimmedValue(formIds.address1)
      const address_line2 = readTrimmedValue(formIds.address2)
      const city = readTrimmedValue(formIds.city)
      const cityId = readNumberValue(formIds.cityId)
      const countryId = readNumberValue(formIds.countryId)
      onSubmit({
        address_line1,
        address_line2,
        city: cityId ? null : city,
        cityId,
        countryId,
        firstname,
        isUnsubscribed: userInfo?.is_unsubscribed!,
        language_id,
        lastname,
        phone,
        postalCode,
        region,
      })
    }
  }, [
    onSubmit,
    readTrimmedValue,
    languageList,
    readNumberValue,
    userInfo,
    validateForm,
  ])

  const lang = readFormValue(formIds.language)

  const langOptions = useMemo(() => map(languageList, (language) => ({
    id: language.iso_639_1,
    name: language.name_national || language.name_en,
  })), [languageList])

  const selectedlangOption = useMemo(
    () => find(langOptions, { id: lang })?.name ?? lang,
    [lang, langOptions],
  )

  const onLangSelect = (selectedLang: Lang | null) => {
    if (selectedLang) {
      updateFormValue(formIds.language)(selectedLang.id)
    }
  }

  const resetPassword = useCallback(() => {
    window.location.href = `${AUTH_SERVICE}/change_password?token=${token}`
  }, [token])

  return {
    handleSubmit,
    hasChanges,
    lang: selectedlangOption,
    langOptions,
    loader,
    onLangSelect,
    onPhoneBlur,
    readFormError,
    readFormValue,
    resetPassword,
    updateFormValue,
  }
}
