"use client"

import { forwardRef } from "react"
import { Checkbox as AriaCheckbox } from "react-aria-components"
import {
  type RegisterOptions,
  useController,
  useFormContext,
} from "react-hook-form"

import styles from "./checkbox.module.css"
import { MaterialIcon } from "../../Icons/MaterialIcon"
import { ErrorMessage } from "../ErrorMessage"

interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {
  name: string
  registerOptions?: RegisterOptions
  hideError?: boolean
  topAlign?: boolean
  errorCodeMessages?: Record<string, string>
}

const CheckboxComponent = forwardRef<
  HTMLInputElement,
  React.PropsWithChildren<CheckboxProps>
>(function Checkbox(
  {
    className = "",
    name,
    children,
    registerOptions,
    hideError,
    topAlign = false,
    errorCodeMessages,
  },
  ref
) {
  const { control } = useFormContext()
  const { field, fieldState, formState } = useController({
    control,
    name,
    rules: registerOptions,
  })

  return (
    <AriaCheckbox
      className={`${styles.container} ${className}`}
      isSelected={field.value}
      onChange={field.onChange}
      data-testid={name}
      name={name}
      isDisabled={registerOptions?.disabled}
      excludeFromTabOrder
    >
      {({ isSelected }) => (
        <>
          <span
            className={`${styles.checkboxContainer} ${topAlign ? styles.topAlign : ""}`}
          >
            <span
              className={styles.checkbox}
              tabIndex={registerOptions?.disabled ? undefined : 0}
              ref={ref}
            >
              {isSelected && (
                <MaterialIcon icon="check" color="Icon/Inverted" />
              )}
            </span>
            {children}
          </span>
          {fieldState.error && !hideError ? (
            <ErrorMessage
              errors={formState.errors}
              name={name}
              messageLabel={
                (fieldState.error.message &&
                  errorCodeMessages?.[fieldState.error.message]) ||
                fieldState.error.message
              }
            />
          ) : null}
        </>
      )}
    </AriaCheckbox>
  )
})

const Checkbox = CheckboxComponent as React.ForwardRefExoticComponent<
  React.PropsWithChildren<CheckboxProps> & React.RefAttributes<HTMLInputElement>
>

export default Checkbox
