/*
 * 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 '../services/authQueries';
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} />;
};
