'use client'

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

import { PktInputWrapper } from '../inputwrapper/InputWrapper'
import { TPktInputSize } from 'shared-types/size'

export interface IPktTextarea extends TextareaHTMLAttributes<HTMLTextAreaElement> {
  id: string
  ariaDescribedby?: string
  ariaLabelledby?: string
  counter?: boolean
  counterMaxLength?: number
  disabled?: boolean
  errorMessage?: string | ReactNode | ReactNode[]
  hasError?: boolean
  helptext?: string | ReactNode | ReactNode[]
  helptextDropdown?: string | ReactNode | ReactNode[]
  helptextDropdownButton?: string
  inline?: boolean
  fullwidth?: boolean
  label: string
  name?: string
  optionalTag?: boolean
  optionalText?: string
  requiredTag?: boolean
  requiredText?: string
  tagText?: string | null
  placeholder?: string
  rows?: number
  useWrapper?: boolean
  value?: string
  autocomplete?: string
  minLength?: number
  maxLength?: number
  readOnly?: boolean
  required?: boolean
  skipForwardTestid?: boolean
  inputSize?: TPktInputSize
  onChange?: ChangeEventHandler<HTMLTextAreaElement>
}

export const PktTextarea = forwardRef(
  (
    {
      id,
      ariaDescribedby,
      ariaLabelledby,
      counter,
      counterMaxLength,
      className,
      disabled,
      errorMessage,
      hasError,
      helptext,
      helptextDropdown,
      helptextDropdownButton,
      inline,
      fullwidth = false,
      label,
      name,
      optionalTag = false,
      optionalText,
      requiredTag = false,
      requiredText,
      tagText = null,
      placeholder,
      rows,
      useWrapper = true,
      onChange,
      value,
      autoComplete = 'off',
      minLength,
      maxLength,
      readOnly,
      skipForwardTestid = false,
      inputSize = 'medium',
      ...props
    }: IPktTextarea,
    ref: ForwardedRef<HTMLTextAreaElement>,
  ) => {
    const classNames = [className, 'pkt-textinput', 'pkt-textarea'].join(' ')

    const inputId = `${id}-input` // id til input element og sendes inn til htmlFor/forId 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 [counterCurrent, setCounterCurrent] = useState(0)

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

    const initRef = (domInput: HTMLTextAreaElement) => {
      setCounterCurrent(domInput?.value?.length || 0)
      if (typeof ref === 'function') {
        ref(domInput)
      }
    }

    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}
      >
        <textarea
          ref={initRef}
          className={`pkt-input pkt-input--${inputSize} ${fullwidth ? 'pkt-input--fullwidth' : ''} ${
            counterMaxLength && counterCurrent > counterMaxLength ? 'pkt-input--counter-error' : ''
          }`}
          name={`${name || id}`}
          id={inputId}
          placeholder={placeholder}
          disabled={disabled}
          rows={rows}
          aria-labelledby={labelledBy}
          aria-invalid={hasError}
          aria-errormessage={`${id}-error`}
          {...props}
          onChange={handleChange}
          value={value}
          autoComplete={autoComplete}
          minLength={minLength}
          maxLength={maxLength}
          readOnly={readOnly}
          data-skip-forward-testid={skipForwardTestid ? 'true' : undefined}
        />
      </PktInputWrapper>
    )
  },
)

PktTextarea.displayName = 'PktTextarea'
