/*
 * 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, Warning } from '@mui/icons-material';
import {
  IconButtonProps,
  List,
  ListItem,
  ListItemIcon,
  Stack,
  TextField,
  TextFieldProps,
  Typography,
} from '@mui/material';
import { styled } from '@mui/material/styles';
import { ChangeEvent, ReactElement, useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { StrengthValueCode } from '../utils/auth';
import { InfoButton, ToggleVisibilityButton } from './Button';
import RulesDialog from './RulesDialog';
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' | 'invalid' | 'registration_failed';
export type PasswordStatus = StrengthValueCode | 'registration_failed';

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

export const UsernameInput = ({
  infoButtonProps,
  onChange: _onChange,
  success,
  status = 'default',
  tooltipTitle,
  ...props
}: InputProps<NameStatus>) => {
  const { t } = useTranslation();
  const [isSelected, setIsSelected] = useState(false);
  const [input, setInput] = useState(props.defaultValue);
  const [startAdornment, setStartAdornment] = useState<ReactElement | undefined>();
  const [isDialogOpened, setIsDialogOpened] = useState<boolean>(false);

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

  useEffect(() => {
    /* Handle startAdornment */
    let Icon = StyledPersonIconLight;
    let visibility = 'visible';
    if (props.error) {
      Icon = StyledRoundSaltireIconError;
    } else if (success) {
      Icon = StyledCheckedIconSuccess;
    } else if (!isSelected && !input) {
      visibility = 'hidden'; // keep icon's space so text does not move
    }
    setStartAdornment(<Icon sx={{ visibility }} />);
  }, [props.error, success, isSelected, input]);

  /*
  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 (
    <>
      <RulesDialog
        openDialog={isDialogOpened}
        title={t('username_rules_dialog_title')}
        closeDialog={() => setIsDialogOpened(false)}
      >
        <UsernameRules />
      </RulesDialog>
      <TextField
        color={inputColor(props.error, success)}
        label={t('username_input_label')}
        variant="standard"
        helperText={status !== 'default' ? helperText : ''}
        onChange={onChange}
        onFocus={() => setIsSelected(true)}
        onBlur={() => setIsSelected(false)}
        {...props}
        InputLabelProps={{
          shrink: !!(isSelected || input),
          ...props.InputLabelProps,
        }}
        InputProps={{
          startAdornment,
          endAdornment: (
            <InfoButton tooltipTitle={tooltipTitle} {...infoButtonProps} onClick={() => setIsDialogOpened(true)} />
          ),
          ...props.InputProps,
        }}
      />
    </>
  );
};

export const PasswordInput = ({
  infoButtonProps,
  onChange: _onChange,
  success,
  tooltipTitle,
  status = 'default',
  ...props
}: InputProps<PasswordStatus>) => {
  const { t } = useTranslation();
  const [showPassword, setShowPassword] = useState(false);
  const [isSelected, setIsSelected] = useState(false);
  const [input, setInput] = useState(props.defaultValue);
  const [startAdornment, setStartAdornment] = useState<ReactElement | undefined>();
  const [isDialogOpened, setIsDialogOpened] = useState<boolean>(false);

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

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

  useEffect(() => {
    /* Handle startAdornment */
    let Icon = StyledLockIcon;
    let visibility = 'visible';
    if (props.error) {
      Icon = StyledRoundSaltireIconError;
    } else if (success) {
      Icon = StyledCheckedIconSuccess;
    } else if (!isSelected && !input) {
      visibility = 'hidden'; // keep icon's space so text does not move
    }
    setStartAdornment(<Icon sx={{ visibility }} />);
  }, [props.error, success, isSelected, input]);

  /*
  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 (
    <>
      <RulesDialog
        openDialog={isDialogOpened}
        title={t('password_rules_dialog_title')}
        closeDialog={() => setIsDialogOpened(false)}
      >
        <PasswordRules />
      </RulesDialog>
      <TextField
        color={inputColor(props.error, success)}
        label={t('password_input_label')}
        type={showPassword ? 'text' : 'password'}
        variant="standard"
        autoComplete="current-password"
        helperText={status !== 'default' ? helperText : ''}
        onChange={onChange}
        onFocus={() => setIsSelected(true)}
        onBlur={() => setIsSelected(false)}
        {...props}
        InputLabelProps={{ shrink: !!(isSelected || input), ...props.InputLabelProps }}
        InputProps={{
          startAdornment,
          endAdornment: (
            <Stack direction="row" spacing="14px" alignItems="center">
              <InfoButton tooltipTitle={tooltipTitle} {...infoButtonProps} onClick={() => setIsDialogOpened(true)} />
              <ToggleVisibilityButton visible={showPassword} onClick={toggleShowPassword} />
            </Stack>
          ),
          ...props.InputProps,
        }}
      />
    </>
  );
};

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)}
    />
  );
};

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)}
    />
  );
};

function inputColor(
  error?: boolean,
  success?: boolean
): 'success' | 'error' | 'primary' | 'secondary' | 'info' | 'warning' | undefined {
  return error ? 'error' : success ? 'success' : 'primary';
}

const PasswordRules = () => {
  const { t } = useTranslation();

  return (
    <List>
      <ListItem>
        <ListItemIcon>
          <GppMaybe />
        </ListItemIcon>
        <Typography variant="body1">{t('password_rule_one')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <GppMaybe />
        </ListItemIcon>
        <Typography variant="body1">{t('password_rule_two')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <GppMaybe />
        </ListItemIcon>
        <Typography variant="body1">{t('password_rule_three')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <GppMaybe />
        </ListItemIcon>
        <Typography variant="body1">{t('password_rule_four')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <GppMaybe />
        </ListItemIcon>
        <Typography variant="body1">{t('password_rule_five')}</Typography>
      </ListItem>
    </List>
  );
};

const UsernameRules = () => {
  const { t } = useTranslation();

  return (
    <List>
      <ListItem>
        <ListItemIcon>
          <Warning />
        </ListItemIcon>
        <Typography variant="body1">{t('username_rule_one')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <Warning />
        </ListItemIcon>
        <Typography variant="body1">{t('username_rule_two')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <Warning />
        </ListItemIcon>
        <Typography variant="body1">{t('username_rule_three')}</Typography>
      </ListItem>
      <ListItem>
        <ListItemIcon>
          <Warning />
        </ListItemIcon>
        <Typography variant="body1">{t('username_rule_four')}</Typography>
      </ListItem>
    </List>
  );
};
