import { CSSProperties, ReactNode, useEffect, useState } from 'react'
import classNames from 'classnames'
import { CommonComponentProps } from '../../utils/types'
import './PasswordInput.scss'

export interface PasswordInputProps extends CommonComponentProps {
  className?: string
  style?: CSSProperties
  children?: ReactNode
  value?: string
  defaultValue?: string
  length?: number
  type?: 'border' | 'underline'
  gap?: number | string
  plainText?: boolean
  focused?: boolean
  defaultFocused?: boolean
  onFocused?: (focused: boolean) => void
  onClick?: () => void
  native?: boolean
  onChange?: (value: string) => void
}

export function PasswordInput(props: PasswordInputProps) {
  const {
    className,
    style,
    children,
    value,
    defaultValue,
    length = 6,
    type = 'border',
    gap,
    plainText,
    focused,
    defaultFocused,
    onFocused,
    onClick,
    native,
    onChange,
    ...restProps
  } = props

  const [innerValue, setInnerValue] = useState(value ?? defaultValue ?? '')
  const [innerFocused, setInnerFocused] = useState(
    focused ?? defaultFocused ?? false
  )

  // 受控
  useEffect(() => {
    if (value != null) {
      setInnerValue(value)
    }
  }, [value])

  const handleClick = () => {
    onClick?.()
  }

  // 受控
  useEffect(() => {
    if (focused != null) {
      setInnerFocused(focused)
    }
  }, [focused])

  const handleChange = (event: any) => {
    const val = (event.target.value ?? event.detail.value).slice(0, length)
    // 非受控
    if (value == null) {
      setInnerValue(val)
    }
    onChange?.(val)
  }

  const handleFocus = () => {
    // 非受控
    if (focused == null) {
      setInnerFocused(true)
    }
    onFocused?.(true)
  }

  const handleBlur = () => {
    // 非受控
    if (focused == null) {
      setInnerFocused(false)
    }
    onFocused?.(false)
  }

  const passwordInputClass = classNames(
    's-password-input',
    `s-password-input-${type}`,
    {
      's-password-input-gapless': gap === 0,
    },
    className
  )

  const passwordInputStyle = {
    ...style,
    gap,
  }

  return (
    <div
      {...restProps}
      className={passwordInputClass}
      onClick={handleClick}
      style={passwordInputStyle}
    >
      {Array(length)
        .fill(0)
        .map((_, i) => {
          return (
            <div
              key={i}
              className={classNames('s-password-input-item', {
                's-password-input-item-active':
                  innerFocused && i === innerValue.length,
              })}
            >
              {i < innerValue.length &&
                (plainText ? (
                  <div className="s-password-input-plaintext">
                    {innerValue[i]}
                  </div>
                ) : (
                  <div className="s-password-input-ciphertext"></div>
                ))}
              {innerFocused && i === innerValue.length && (
                <div className="s-password-input-cursor"></div>
              )}
            </div>
          )
        })}

      {native && (
        <input
          className="s-password-input-input"
          value={innerValue}
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
        />
      )}
    </div>
  )
}

export default PasswordInput
