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

import forEach from 'lodash/forEach'
import trim from 'lodash/trim'

import { formIds } from 'config/form'

import type { UserInfo } from 'requests/saveUserInfo'
import { getUserInfo } from 'requests/getUserInfo'
import { saveUserInfo } from 'requests/saveUserInfo'

import type { SelectedCountry } from './useCountries'
import { useUserInfoForm } from './useUserInfoForm'
import { useValidateForm } from './useValidateForm'

export const useUserInfo = () => {
  const validateForm = useValidateForm()
  const saveButton = useRef<HTMLButtonElement>(null)

  const {
    cities,
    countries,
    getCities,
    onCitySelect,
    onCountrySelect,
    onPhoneBlur,
    onRegionOrCityChange,
    readFormError,
    readFormValue,
    resetCities,
    resetSelectedCity,
    selectedCity,
    updateFormError,
    updateFormValue,
  } = useUserInfoForm()

  const readTrimmedValue = useCallback(
    (fieldName: string) => trim(readFormValue(fieldName)),
    [readFormValue],
  )

  const handleSubmit = useCallback(() => {
    if (validateForm()) {
      const firstname = readTrimmedValue(formIds.firstname)
      const lastname = readTrimmedValue(formIds.lastname)
      const phone = readTrimmedValue(formIds.phone)
      const password = readTrimmedValue(formIds.password)
      const postalCode = Number(readTrimmedValue(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 countryId = Number(readTrimmedValue(formIds.countryId))

      saveUserInfo({
        address_line1,
        address_line2,
        city,
        cityId: selectedCity?.id || null,
        countryId,
        firstname,
        lastname,
        password,
        phone,
        postalCode,
        region,
      }).then(() => saveButton?.current?.blur())
    }
  }, [
    readTrimmedValue,
    validateForm,
    selectedCity,
  ])

  useEffect(() => {
    getUserInfo().then((res: UserInfo) => {
      forEach(res, (value: string | number | SelectedCountry, key: string) => {
        if (value && typeof value === 'object') {
          onCountrySelect(value, false)
        } else if (value) {
          updateFormValue(key)(String(value))
        }
      })
    })
  }, [updateFormValue, onCountrySelect])

  return {
    cities,
    countries,
    getCities,
    handleSubmit,
    onCitySelect,
    onCountrySelect,
    onPhoneBlur,
    onRegionOrCityChange,
    readFormError,
    readFormValue,
    resetCities,
    resetSelectedCity,
    saveButton,
    selectedCity,
    updateFormError,
    updateFormValue,
  }
}
