'use client'

import {
  ChangeEvent,
  ChangeEventHandler,
  ForwardedRef,
  forwardRef,
  InputHTMLAttributes,
  ReactNode,
  useEffect,
  useState,
} from 'react'

import { PktIcon } from '../icon/Icon'
import { PktInputWrapper } from '../inputwrapper/InputWrapper'

export interface IPktTextinput extends InputHTMLAttributes<HTMLInputElement> {
  id: string
  ariaDescribedby?: string
  ariaLabelledby?: string
  autocomplete?: string
  counter?: boolean
  counterMaxLength?: number
  disabled?: boolean
  errorMessage?: string | ReactNode | ReactNode[]
  hasError?: boolean
  helptext?: string | ReactNode | ReactNode[]
  helptextDropdown?: string | ReactNode | ReactNode[]
  helptextDropdownButton?: string
  iconNameRight?: string
  inline?: boolean
  fullwidth?: boolean
  label: string
  name?: string
  optionalTag?: boolean
  optionalText?: string
  requiredTag?: boolean
  requiredText?: string
  tagText?: string | null
  placeholder?: string
  prefix?: string
  suffix?: string
  type?: string
  useWrapper?: boolean
  value?: string
  omitSearchIcon?: boolean
  min?: number | string
  max?: number | string
  minLength?: number
  maxLength?: number
  step?: string
  size?: number
  readonly?: boolean
  required?: boolean
  dataTestid?: string
  onChange?: ChangeEventHandler<HTMLInputElement>
  skipForwardTestid?: boolean
  inputSize?: 'small' | 'medium' | 'xsmall'
}

export const PktTextinput = forwardRef(
  (
    {
      id,
      ariaDescribedby,
      ariaLabelledby,
      autocomplete = 'off',
      counter,
      counterMaxLength,
      className,
      disabled = false,
      errorMessage,
      hasError = false,
      helptext,
      helptextDropdown,
      helptextDropdownButton,
      iconNameRight,
      inline = false,
      fullwidth = false,
      label,
      name,
      optionalTag = false,
      optionalText,
      requiredTag = false,
      requiredText,
      tagText = null,
      placeholder,
      prefix,
      suffix,
      type = 'text',
      useWrapper = true,
      omitSearchIcon = false,
      value,
      minLength,
      maxLength,
      min,
      max,
      step,
      size,
      readonly: readOnly,
      required,
      dataTestid,
      onChange,
      skipForwardTestid = false,
      inputSize = 'medium',
      ...props
    }: IPktTextinput,
    ref: ForwardedRef<HTMLInputElement>,
  ) => {
    const classNames = [className, 'pkt-textinput'].join(' ')

    const shouldShowSearchIcon = type === 'search' && !iconNameRight && !omitSearchIcon
    const isoValue = type === 'date' && value ? value.slice(0, 10) : value

    const [counterCurrent, setCounterCurrent] = useState(value?.length || 0)

    const inputId = `${id}` // id til input element og sendes inn til htmlFor i InputWrapper
    const labelId = `${inputId}-label` // id til label elementet og sendes inn til aria-labelledby i input (genereres i InputWrapper)
    const labelledBy = ariaLabelledby || labelId

    const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
      if (counter) {
        setCounterCurrent(event.currentTarget?.value?.length || 0)
      }
      if (onChange) {
        onChange(event)
      }
    }

    useEffect(() => {
      if (value !== undefined) {
        setCounterCurrent(value?.length || 0)
      }
    }, [value])

    return (
      <PktInputWrapper
        ariaDescribedby={ariaDescribedby}
        className={classNames}
        disabled={disabled}
        errorMessage={errorMessage}
        forId={inputId}
        hasError={hasError}
        helptext={helptext}
        helptextDropdown={helptextDropdown}
        helptextDropdownButton={helptextDropdownButton}
        inline={inline}
        label={label}
        optionalTag={optionalTag}
        optionalText={optionalText}
        requiredTag={requiredTag}
        requiredText={requiredText}
        tagText={tagText}
        useWrapper={useWrapper}
        counter={counter}
        counterCurrent={counterCurrent}
        counterMaxLength={counterMaxLength}
        size={inputSize}
      >
        <div
          className={`pkt-input__container pkt-input__container--${inputSize}`}
          data-testid={dataTestid}
          data-skip-forward-testid={skipForwardTestid ? 'true' : undefined}
        >
          {prefix && <div className="pkt-input-prefix">{prefix}</div>}
          <input
            {...props}
            ref={ref}
            className={`pkt-input pkt-input--${inputSize} ${fullwidth ? 'pkt-input--fullwidth' : ''} ${
              counterMaxLength && counterCurrent > counterMaxLength ? 'pkt-input--counter-error' : ''
            }`}
            type={type}
            name={`${name || id}`}
            value={isoValue}
            id={inputId}
            placeholder={placeholder}
            autoComplete={autocomplete}
            disabled={disabled}
            aria-invalid={hasError}
            aria-errormessage={`${id}-error`}
            aria-labelledby={labelledBy}
            min={min}
            max={max}
            onChange={handleChange}
            step={step}
            minLength={minLength}
            maxLength={maxLength}
            size={size}
            readOnly={readOnly}
            required={required}
          />
          {suffix && (
            <p className="pkt-input-suffix">
              {suffix}
              {iconNameRight && <PktIcon className="pkt-input-suffix-icon" name={iconNameRight} />}
              {shouldShowSearchIcon && <PktIcon className="pkt-input-suffix-icon" name="magnifying-glass-big" />}
            </p>
          )}

          {!suffix && iconNameRight && <PktIcon className="pkt-input-icon" name={iconNameRight} />}
          {!suffix && shouldShowSearchIcon && <PktIcon className="pkt-input-icon" name="magnifying-glass-big" />}
        </div>
      </PktInputWrapper>
    )
  },
)

PktTextinput.displayName = 'PktTextinput'
