import * as React from 'react';
import clsx from 'clsx';

import MuiIconButton from '@mui/material/IconButton';
import MuiInputAdornment from '@mui/material/InputAdornment';
import MuiOutlinedInput from '@mui/material/OutlinedInput';
import type { OutlinedInputProps as MuiOutlinedInputProps } from '@mui/material/OutlinedInput';
import { styled } from '@mui/material/styles';

import { ASSETS_URL } from '../../../consts/common';
import { Button } from '../../button';
import type { ButtonProps } from '../../button';
import { CustomIcon } from '../../custom-icon';
import type { Theme } from '../../@styles/theme-provider';

type StyledInputProps = Pick<InputProps, 'active' | 'disabled' | 'readOnly'>;

const StyledInput = styled(MuiOutlinedInput, {
  shouldForwardProp: prop => prop !== 'active'
})<StyledInputProps>(
  ({ active, disabled, readOnly, theme }: StyledInputProps & { theme: Theme }) => ({
    '& > .MuiInputAdornment-root': {
      '.endAdornmentButton': {
        marginRight: theme.spacing(1),
        textTransform: 'inherit',
        '& .MuiButton-startIcon': {
          marginRight: theme.spacing(0.5)
        },
        ...(disabled && {
          color: theme.palette.primary[100]
        })
      },
      '.togglePasswordVisibility': {
        color: disabled ? theme.palette.primary[100] : theme.palette.primary[400],
        padding: 0,
        '&:hover': {
          background: 'none',
          color: theme.palette.primary[500]
        }
      },
      ...(disabled && {
        pointerEvents: 'none'
      })
    },
    ...(active && {
      '& fieldset, &:hover fieldset': {
        borderColor: `${theme.palette.secondary[500]} !important`
      }
    }),
    ...(readOnly && {
      backgroundColor: theme.palette.secondary[100],
      color: theme.palette.primary[400],
      '& fieldset, &.Mui-focused fieldset': {
        borderColor: `${theme.palette.primary[200]} !important`
      },
      '&:hover fieldset, &.Mui-focused:hover fieldset': {
        boxShadow: theme.shadows[8]
      }
    })
  })
);

export type InputProps = MuiOutlinedInputProps & {
  /**
   * Whether to display input in active state.
   * @default false
   */
  active?: boolean;
  /**
   * Props passed to the Button component rendered using endAdornment.
   */
  endAdornmentButtonProps?: ButtonProps;
  /**
   * If `true`, the eye icon will be displayed.
   * @default false
   */
  toggleShowPassword?: boolean;
};

export const Input = React.forwardRef(function (props: InputProps, ref) {
  const {
    active = false,
    disabled,
    endAdornmentButtonProps,
    toggleShowPassword = false,
    type: _type,
    ...otherProps
  } = props;

  const [showPassword, setShowPassword] = React.useState(false);
  const type = React.useMemo(
    () => (toggleShowPassword ? (showPassword ? 'text' : 'password') : _type),
    [_type, showPassword, toggleShowPassword]
  );

  const handleClickShowPassword = () => {
    setShowPassword(!showPassword);
  };

  const handleMouseDownPassword = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.preventDefault();
  };

  return (
    <StyledInput
      ref={ref}
      active={active}
      disabled={disabled}
      endAdornment={
        <>
          {endAdornmentButtonProps && (
            <MuiInputAdornment position="end">
              <Button
                clickArea={false}
                size="small"
                {...endAdornmentButtonProps}
                className={clsx('endAdornmentButton', endAdornmentButtonProps.className)}
                data-testid="endAdornmentButton"
              />
            </MuiInputAdornment>
          )}
          {toggleShowPassword && (
            <MuiInputAdornment position="end">
              <MuiIconButton
                aria-label="Toggle password visibility"
                className="togglePasswordVisibility"
                data-testid="togglePasswordVisibilityIconButton"
                size="small"
                onClick={!disabled ? handleClickShowPassword : undefined}
                onMouseDown={handleMouseDownPassword}
              >
                {showPassword ? (
                  <CustomIcon color="inherit" src={`${ASSETS_URL}/icons2/icon_hide.svg`} />
                ) : (
                  <CustomIcon color="inherit" src={`${ASSETS_URL}/icons/icon_View.svg`} />
                )}
              </MuiIconButton>
            </MuiInputAdornment>
          )}
        </>
      }
      type={type}
      {...otherProps}
    />
  );
});
