/*
 * Copyright (C) 2022 Savoir-faire Linux Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <https://www.gnu.org/licenses/>.
 */
import GppMaybe from '@mui/icons-material/GppMaybe';
import Warning from '@mui/icons-material/Warning';
import { IconButtonProps, Stack, TextField, TextFieldProps } from '@mui/material';
import { styled } from '@mui/material/styles';
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { StrengthValueCode } from '../utils/auth';
import { InfoButton, ToggleVisibilityButton } from './Button';
import { DialogContentList, InfosDialog, useDialogHandler } from './Dialog';
import { CheckedIcon, LockIcon, PenIcon, PersonIcon, RoundSaltireIcon } from './SvgIcon';

const iconsHeight = '16px';
const StyledCheckedIconSuccess = styled(CheckedIcon)(({ theme }) => ({
  height: iconsHeight,
  color: theme.palette.success.main,
}));
const StyledRoundSaltireIconError = styled(RoundSaltireIcon)(({ theme }) => ({
  height: iconsHeight,
  color: theme.palette.error.main,
}));
const StyledPenIconLight = styled(PenIcon)({ height: iconsHeight, color: '#03B9E9' });
const StyledPenIconDark = styled(PenIcon)(({ theme }) => ({ height: iconsHeight, color: theme.palette.primary.dark }));
const StyledPersonIconLight = styled(PersonIcon)({ height: iconsHeight, color: '#03B9E9' });
const StyledLockIcon = styled(LockIcon)({ height: iconsHeight, color: '#03B9E9' });

export type NameStatus = 'default' | 'success' | 'taken' | 'valid' | 'invalid' | 'registration_failed';
export type PasswordStatus = StrengthValueCode | 'registration_failed';

export type InputProps<StatusType extends NameStatus | PasswordStatus> = TextFieldProps & {
  status?: StatusType;
  infoButtonProps?: IconButtonProps;
  tooltipTitle: string;
};

export const UsernameInput = ({
  infoButtonProps,
  status = 'default',
  tooltipTitle,
  ...props
}: InputProps<NameStatus>) => {
  const { t } = useTranslation();
  const [isSelected, setIsSelected] = useState(false);
  const dialogHandler = useDialogHandler();

  const usernameError = status === 'taken' || status === 'invalid' || status === 'registration_failed';
  const usernameSuccess = status === 'success';

  let StartAdornmentIcon = StyledPersonIconLight;
  let visibility = 'visible';
  if (usernameError) {
    StartAdornmentIcon = StyledRoundSaltireIconError;
  } else if (usernameSuccess) {
    StartAdornmentIcon = StyledCheckedIconSuccess;
  } else if (!isSelected && !props.value) {
    visibility = 'hidden'; // keep icon's space so text does not move
  }

  /*
  t('username_input_helper_text_success')
  t('username_input_helper_text_taken')
  t('username_input_helper_text_invalid')
  t('username_input_helper_text_registration_failed')
 */
  const helperText = t('username_input_helper_text', { context: `${status}` });

  return (
    <>
      <InfosDialog {...dialogHandler.props} title={t('username_rules_dialog_title')} content={<UsernameRules />} />
      <TextField
        required
        error={usernameError}
        label={t('username_input_label')}
        variant="standard"
        helperText={status !== 'default' ? helperText : ''}
        onFocus={() => setIsSelected(true)}
        onBlur={() => setIsSelected(false)}
        {...props}
        InputLabelProps={{
          shrink: !!(isSelected || props.value),
          ...props.InputLabelProps,
        }}
        InputProps={{
          startAdornment: <StartAdornmentIcon sx={{ visibility }} />,
          endAdornment: (
            <InfoButton
              tabIndex={-1}
              tooltipTitle={tooltipTitle}
              {...infoButtonProps}
              onClick={dialogHandler.openDialog}
            />
          ),
          ...props.InputProps,
        }}
      />
    </>
  );
};

export const PasswordInput = ({
  infoButtonProps,
  status = 'default',
  tooltipTitle,
  ...props
}: InputProps<PasswordStatus>) => {
  const { t } = useTranslation();
  const [showPassword, setShowPassword] = useState(false);
  const [isSelected, setIsSelected] = useState(false);
  const dialogHandler = useDialogHandler();

  const passwordError = status !== 'strong' && status !== 'default';
  const passwordSuccess = status === 'strong';

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

  let StartAdornmentIcon = StyledLockIcon;
  let StartAdornmentIconVisibility = 'visible';
  if (passwordError) {
    StartAdornmentIcon = StyledRoundSaltireIconError;
  } else if (passwordSuccess) {
    StartAdornmentIcon = StyledCheckedIconSuccess;
  } else if (!isSelected && !props.value) {
    StartAdornmentIconVisibility = 'hidden'; // keep icon's space so text does not move
  }

  /*
  t('password_input_helper_text_too_weak')
  t('password_input_helper_text_weak')
  t('password_input_helper_text_medium')
  t('password_input_helper_text_strong')
  t('password_input_helper_text_registration_failed')
   */
  const helperText = t('password_input_helper_text', { context: `${status}` });

  return (
    <>
      <InfosDialog {...dialogHandler.props} title={t('password_rules_dialog_title')} content={<PasswordRules />} />
      <TextField
        required
        error={passwordError}
        label={t('password_input_label')}
        type={showPassword ? 'text' : 'password'}
        variant="standard"
        autoComplete="current-password"
        helperText={status !== 'default' ? helperText : ''}
        onFocus={() => setIsSelected(true)}
        onBlur={() => setIsSelected(false)}
        {...props}
        InputLabelProps={{ shrink: !!(isSelected || props.value), ...props.InputLabelProps }}
        InputProps={{
          startAdornment: <StartAdornmentIcon sx={{ visibility: StartAdornmentIconVisibility }} />,
          endAdornment: (
            <Stack direction="row" spacing="14px" alignItems="center">
              <InfoButton tooltipTitle={tooltipTitle} {...infoButtonProps} onClick={dialogHandler.openDialog} />
              <ToggleVisibilityButton visible={showPassword} onClick={toggleShowPassword} />
            </Stack>
          ),
          ...props.InputProps,
        }}
      />
    </>
  );
};

//this component is not used anywhere
export const NickNameInput = ({ onChange: _onChange, ...props }: TextFieldProps) => {
  const [isSelected, setIsSelected] = useState(false);
  const [input, setInput] = useState(props.defaultValue);
  const [startAdornmentVisibility, setStartAdornmentVisibility] = useState<'visible' | 'hidden'>('hidden');

  const onChange = useCallback(
    (event: ChangeEvent<HTMLInputElement>) => {
      setInput(event.target.value);
      _onChange?.(event);
    },
    [_onChange]
  );

  useEffect(() => {
    setStartAdornmentVisibility(isSelected || input ? 'visible' : 'hidden');
  }, [isSelected, input]);

  return (
    <TextField
      {...props}
      label="Nickname, surname..."
      variant="standard"
      InputLabelProps={{ shrink: !!(isSelected || input) }}
      onChange={onChange}
      InputProps={{
        startAdornment: <StyledPenIconLight sx={{ visibility: startAdornmentVisibility }} />,
      }}
      onFocus={() => setIsSelected(true)}
      onBlur={() => setIsSelected(false)}
    />
  );
};

//this component is not used anywhere
export const RegularInput = ({ onChange: _onChange, ...props }: TextFieldProps) => {
  const [isSelected, setIsSelected] = useState(false);
  const [input, setInput] = useState(props.defaultValue);
  const [startAdornmentVisibility, setStartAdornmentVisibility] = useState<'visible' | 'hidden'>('hidden');
  const [endAdornmentVisibility, setEndAdornmentVisibility] = useState<'visible' | 'hidden'>('visible');

  const onChange = useCallback(
    (event: ChangeEvent<HTMLInputElement>) => {
      setInput(event.target.value);
      _onChange?.(event);
    },
    [_onChange]
  );

  useEffect(() => {
    setStartAdornmentVisibility(isSelected || input ? 'visible' : 'hidden');
    setEndAdornmentVisibility(isSelected || input ? 'hidden' : 'visible');
  }, [isSelected, input]);

  return (
    <TextField
      {...props}
      variant="standard"
      InputLabelProps={{ shrink: !!(isSelected || input) }}
      onChange={onChange}
      InputProps={{
        startAdornment: <StyledPenIconLight sx={{ visibility: startAdornmentVisibility }} />,
        endAdornment: <StyledPenIconDark sx={{ visibility: endAdornmentVisibility }} />,
      }}
      onFocus={() => setIsSelected(true)}
      onBlur={() => setIsSelected(false)}
    />
  );
};

//this was used for altering the color of input fields, but somehow it didn't work at all. Only the `error` prop of the input is taking effect
// function inputColor(
//   error?: boolean,
//   success?: boolean
// ): 'success' | 'error' | 'primary' | 'secondary' | 'info' | 'warning' | undefined {
//   return error ? 'error' : success ? 'success' : 'primary';
// }

const PasswordRules = () => {
  const { t } = useTranslation();
  const items = useMemo(
    () => [
      {
        Icon: GppMaybe,
        value: t('password_rule_1'),
      },
      {
        Icon: GppMaybe,
        value: t('password_rule_2'),
      },
      {
        Icon: GppMaybe,
        value: t('password_rule_3'),
      },
      {
        Icon: GppMaybe,
        value: t('password_rule_4'),
      },
      {
        Icon: GppMaybe,
        value: t('password_rule_5'),
      },
    ],
    [t]
  );
  return <DialogContentList items={items} />;
};

const UsernameRules = () => {
  const { t } = useTranslation();
  const items = useMemo(
    () => [
      {
        Icon: Warning,
        value: t('username_rule_1'),
      },
      {
        Icon: Warning,
        value: t('username_rule_2'),
      },
      {
        Icon: Warning,
        value: t('username_rule_3'),
      },
      {
        Icon: Warning,
        value: t('username_rule_4'),
      },
    ],
    [t]
  );
  return <DialogContentList items={items} />;
};
