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

import { isValidPhoneNumber, parsePhoneNumber } from "libphonenumber-js"
import { TextField } from "react-aria-components"
import { useController, useFormContext, useWatch } from "react-hook-form"
import {
  CountrySelector,
  DialCodePreview,
  ParsedCountry,
  usePhoneInput,
} from "react-international-phone"
import { useIntl } from "react-intl"

import { ChevronDownIcon } from "@/components/Icons"
import ErrorMessage from "@/components/TempDesignSystem/Form/ErrorMessage"
import AriaInputWithLabel from "@/components/TempDesignSystem/Form/Input/AriaInputWithLabel"
import Label from "@/components/TempDesignSystem/Form/Label"
import Body from "@/components/TempDesignSystem/Text/Body"

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

import type { ChangeEvent } from "react"

import type { PhoneProps } from "./phone"

export default function Phone({
  ariaLabel = "Phone number input",
  className = "",
  disabled = false,
  label,
  name = "phoneNumber",
  placeholder = "",
  readOnly = false,
  registerOptions = {
    required: true,
  },
}: PhoneProps) {
  const intl = useIntl()
  const { control, setValue, trigger } = useFormContext()
  const phone = useWatch({ name })

  const { field, fieldState, formState } = useController({
    control,
    disabled,
    name,
    rules: registerOptions,
  })

  const { country, handlePhoneValueChange, inputValue, setCountry } =
    usePhoneInput({
      defaultCountry: isValidPhoneNumber(formState.defaultValues?.phoneNumber)
        ? parsePhoneNumber(
            formState.defaultValues?.phoneNumber
          ).country?.toLowerCase()
        : "se",
      disableDialCodeAndPrefix: true,
      forceDialCode: true,
      value: phone,
      onChange: (value) => {
        // If not checked trigger(name) forces validation on mount
        // which shows error message before user even can see the form
        if (value.inputValue) {
          setValue(name, value.phone)
          trigger(name)
        } else {
          setValue(name, "")
        }
      },
    })

  function handleSelectCountry(value: ParsedCountry) {
    setCountry(value.iso2)
  }

  function handleChange(evt: ChangeEvent<HTMLInputElement>) {
    handlePhoneValueChange(evt)
  }

  return (
    <div className={`${styles.phone} ${className}`}>
      <CountrySelector
        disabled={readOnly}
        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">
              {intl.formatMessage({ id: "Country code" })}
            </Label>
            <span className={styles.selectContainer}>
              {props.children}
              <Body asChild fontOnly>
                <DialCodePreview
                  className={styles.dialCode}
                  dialCode={country.dialCode}
                  prefix="+"
                />
              </Body>
              <ChevronDownIcon
                className={styles.chevron}
                color="grey80"
                height={18}
                width={18}
              />
            </span>
          </button>
        )}
      />
      <TextField
        aria-label={ariaLabel}
        defaultValue={field.value}
        isDisabled={disabled ?? field.disabled}
        isInvalid={fieldState.invalid}
        isRequired={!!registerOptions?.required}
        isReadOnly={readOnly}
        name={field.name}
        type="tel"
      >
        <AriaInputWithLabel
          {...field}
          id={field.name}
          label={label}
          onChange={handleChange}
          placeholder={placeholder}
          readOnly={readOnly}
          required={!!registerOptions.required}
          type="tel"
          value={inputValue}
        />
        <ErrorMessage errors={formState.errors} name={field.name} />
      </TextField>
    </div>
  )
}
