'use client'
import 'react-international-phone/style.css'

import { useEffect, useMemo } from 'react'
import { TextField } from 'react-aria-components'
import { useFormContext, useWatch } from 'react-hook-form'
import {
  buildCountryData,
  CountrySelector,
  defaultCountries,
  DialCodePreview,
  parseCountry,
  type ParsedCountry,
  usePhoneInput,
} from 'react-international-phone'

import Body from '../../Body'
import { ErrorMessage } from '../ErrorMessage'
import { MaterialIcon } from '../../Icons/MaterialIcon'
import { Input } from '../../Input'
import { Label } from '../../Label'

import styles from './phone.module.css'

import type { PhoneProps } from './phone'

export default function Phone({
  ariaLabel = 'Phone number input',
  className = '',
  countryLabel = 'Country code',
  countrySelectorName = 'phoneNumberCC',
  countriesWithTranslatedName,
  defaultCountryCode,
  disabled = false,
  errorMessage,
  label,
  name = 'phoneNumber',
  placeholder,
  registerOptions = {
    required: true,
  },
}: PhoneProps) {
  const countries = useMemo(() => {
    return defaultCountries.map((dc) => {
      const parsedCountry = parseCountry(dc)
      const country = countriesWithTranslatedName?.find(
        (country) => country.code === parsedCountry.iso2.toUpperCase()
      )
      const translatedCountryName = country?.displayName ?? country?.name
      if (translatedCountryName) {
        parsedCountry.name = translatedCountryName
      }
      return buildCountryData(parsedCountry)
    })
  }, [countriesWithTranslatedName])

  const { formState, getFieldState, register, setValue } = useFormContext()
  const fieldState = getFieldState(name)
  const ccFieldState = getFieldState(countrySelectorName)
  const [phoneNumber, phoneNumberCC]: [string, string] = useWatch({
    name: [name, countrySelectorName],
  })

  const { country, setCountry } = usePhoneInput({
    countries,
    defaultCountry: phoneNumberCC ? phoneNumberCC : defaultCountryCode,
  })

  function handleSelectCountry(value: ParsedCountry) {
    setCountry(value.iso2)
    setValue(countrySelectorName, value.iso2, {
      shouldDirty: true,
      shouldTouch: true,
      shouldValidate: true,
    })
    if (registerOptions.onBlur) {
      registerOptions.onBlur(value)
    }
  }
  useEffect(() => {
    if (!ccFieldState.isTouched) {
      setCountry(phoneNumberCC)
    }
  }, [phoneNumberCC, setCountry, ccFieldState])
  return (
    <div className={`${styles.phone} ${className}`}>
      <CountrySelector
        countries={countries}
        disabled={disabled}
        dropdownArrowClassName={styles.arrow}
        flagClassName={styles.flag}
        onSelect={handleSelectCountry}
        preferredCountries={['de', 'dk', 'fi', 'no', 'se', 'gb']}
        selectedCountry={country.iso2}
        renderButtonWrapper={(props) => (
          <button
            {...props.rootProps}
            className={styles.select}
            tabIndex={0}
            type="button"
            data-testid="country-selector"
          >
            <Label
              required={!!registerOptions.required}
              size="small"
              disabled={disabled}
            >
              {countryLabel}
            </Label>
            <span className={styles.selectContainer}>
              {props.children}
              <Body asChild fontOnly>
                <DialCodePreview
                  className={styles.dialCode}
                  dialCode={country.dialCode}
                  prefix="+"
                  disabled={disabled}
                />
              </Body>
              <MaterialIcon
                icon="keyboard_arrow_down"
                className={styles.chevron}
                color="Icon/Default"
                size={18}
              />
            </span>
          </button>
        )}
      />
      <TextField
        aria-label={ariaLabel}
        isDisabled={disabled || registerOptions.disabled}
        isInvalid={fieldState.invalid}
        isRequired={!!registerOptions?.required}
        name={name}
        type="tel"
        value={phoneNumber}
      >
        <Input
          {...register(name, registerOptions)}
          autoComplete="tel-national"
          label={label}
          placeholder={placeholder}
          disabled={disabled}
          type="tel"
        />
        <ErrorMessage
          errors={formState.errors}
          name={name}
          messageLabel={errorMessage}
        />
      </TextField>
    </div>
  )
}
