"use client"

import { useState } from "react"
import { Text, TextField } from "react-aria-components"
import { Controller, useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"

import {
  CheckIcon,
  CloseIcon,
  EyeHideIcon,
  EyeShowIcon,
  InfoCircleIcon,
} from "@/components/Icons"
import AriaInputWithLabel from "@/components/TempDesignSystem/Form/Input/AriaInputWithLabel"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import { passwordValidators } from "@/utils/passwordValidator"

import Button from "../../Button"
import { IconProps, type NewPasswordProps } from "./newPassword"

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

import { PasswordValidatorKey } from "@/types/components/form/newPassword"

export default function NewPassword({
  name = "newPassword",
  "aria-label": ariaLabel,
  disabled = false,
  placeholder = "",
  registerOptions = {},
  label,
  visibilityToggleable = true,
}: NewPasswordProps) {
  const { control } = useFormContext()
  const intl = useIntl()
  const [isPasswordVisible, setIsPasswordVisible] = useState(false)

  return (
    <Controller
      disabled={disabled}
      control={control}
      name={name}
      rules={registerOptions}
      render={({ field, fieldState, formState }) => {
        const errors = Object.values(formState.errors[name]?.types ?? []).flat()

        return (
          <TextField
            aria-label={ariaLabel}
            isDisabled={field.disabled}
            isInvalid={fieldState.invalid}
            isRequired={!!registerOptions.required}
            name={field.name}
            onBlur={field.onBlur}
            onChange={field.onChange}
            validationBehavior="aria"
            value={field.value}
            type={
              visibilityToggleable && isPasswordVisible ? "text" : "password"
            }
          >
            <div className={styles.inputWrapper}>
              <AriaInputWithLabel
                {...field}
                aria-labelledby={field.name}
                id={field.name}
                label={intl.formatMessage({ id: "New password" })}
                placeholder={placeholder}
                type={
                  visibilityToggleable && isPasswordVisible
                    ? "text"
                    : "password"
                }
              />
              {visibilityToggleable ? (
                <Button
                  className={styles.eyeIcon}
                  type="button"
                  variant="icon"
                  size="small"
                  intent="tertiary"
                  onClick={() => setIsPasswordVisible((value) => !value)}
                >
                  {isPasswordVisible ? <EyeHideIcon /> : <EyeShowIcon />}
                </Button>
              ) : null}
            </div>

            <PasswordValidation value={field.value} errors={errors} />

            {!field.value && fieldState.error ? (
              <Caption className={styles.error} fontOnly>
                <InfoCircleIcon color="red" />
                {fieldState.error.message}
              </Caption>
            ) : null}
          </TextField>
        )
      }}
    />
  )
}

function Icon({ errorMessage, errors }: IconProps) {
  return errors.includes(errorMessage) ? (
    <CloseIcon color="red" height={20} width={20} />
  ) : (
    <CheckIcon color="green" height={20} width={20} />
  )
}

function PasswordValidation({
  value,
  errors,
}: {
  value: string
  errors: string[]
}) {
  const intl = useIntl()

  if (!value) return null

  function getErrorMessage(key: PasswordValidatorKey) {
    switch (key) {
      case "length":
        return `10 ${intl.formatMessage({ id: "to" })} 40 ${intl.formatMessage({ id: "characters" })}`
      case "hasUppercase":
        return `1 ${intl.formatMessage({ id: "uppercase letter" })}`
      case "hasLowercase":
        return `1 ${intl.formatMessage({ id: "lowercase letter" })}`
      case "hasNumber":
        return `1 ${intl.formatMessage({ id: "number" })}`
      case "hasSpecialChar":
        return `1 ${intl.formatMessage({ id: "special character" })}`
    }
  }

  return (
    <div className={styles.errors}>
      {Object.entries(passwordValidators).map(([key, { message }]) => (
        <Caption asChild color="black" key={key}>
          <Text className={styles.helpText} slot="description">
            <Icon errorMessage={message} errors={errors} />
            {getErrorMessage(key as PasswordValidatorKey)}
          </Text>
        </Caption>
      ))}
    </div>
  )
}
