/*
 * 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 { Alert, AlertColor, AlertProps, AlertTitle, Snackbar, SnackbarProps } from '@mui/material';
import { createContext, useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { SetState, WithChildren } from '../utils/utils';
type AlertSnackbarProps = AlertProps & {
  severity: AlertColor;
  open?: boolean;
  snackBarProps?: Partial<SnackbarProps>;
};

export type AlertContent = {
  messageI18nKey: AlertMessageKeys;
  messageI18nContext?: object;
  severity: AlertColor;
  alertOpen: boolean;
};

export function AlertSnackbar({ severity, open, snackBarProps, children, ...alertProps }: AlertSnackbarProps) {
  const { t } = useTranslation();

  return (
    <Snackbar
      open={open}
      {...snackBarProps}
      anchorOrigin={{
        vertical: 'top',
        horizontal: 'center',
        ...snackBarProps?.anchorOrigin,
      }}
    >
      <Alert severity={severity} {...alertProps}>
        <AlertTitle>{t('severity', { context: `${severity}` })}</AlertTitle>
        {children}
      </Alert>
    </Snackbar>
  );
}

type IAlertSnackbarContext = {
  alertContent: AlertContent;
  setAlertContent: SetState<AlertContent>;
};

const defaultAlertSnackbarContext: IAlertSnackbarContext = {
  alertContent: {
    messageI18nKey: '',
    messageI18nContext: {},
    severity: 'info',
    alertOpen: false,
  },
  setAlertContent: () => {},
};

type AlertMessageKeys =
  | 'missed_incoming_call'
  | 'unknown_error_alert'
  | 'username_input_helper_text_empty'
  | 'password_input_helper_text_empty'
  | 'login_invalid_password'
  | 'registration_success'
  | '';

export const AlertSnackbarContext = createContext<IAlertSnackbarContext>(defaultAlertSnackbarContext);

const AlertSnackbarProvider = ({ children }: WithChildren) => {
  const { t } = useTranslation();
  const [alertContent, setAlertContent] = useState<AlertContent>(defaultAlertSnackbarContext.alertContent);
  const closeAlert = () => {
    setAlertContent((prev) => {
      return {
        ...prev,
        alertOpen: false,
      };
    });
  };

  //This is to explicitly let i18n know that these keys should be extracted
  const getAlertMessageText = useCallback(
    (messageI18nKey: AlertMessageKeys, messageI18nContext?: object): string => {
      switch (messageI18nKey) {
        case 'missed_incoming_call':
          return t('missed_incoming_call', { ...messageI18nContext });
        case 'unknown_error_alert':
          return t('unknown_error_alert');
        case 'username_input_helper_text_empty':
          return t('username_input_helper_text_empty');
        case 'password_input_helper_text_empty':
          return t('password_input_helper_text_empty');
        case 'login_invalid_password':
          return t('login_invalid_password');
        case 'registration_success':
          return t('registration_success');
        default:
          return t('unknown_error_alert');
      }
    },
    [t]
  );

  const value = {
    alertContent,
    setAlertContent,
  };

  return (
    <>
      <AlertSnackbar severity={alertContent.severity} open={alertContent.alertOpen} onClose={closeAlert}>
        {getAlertMessageText(alertContent.messageI18nKey, alertContent.messageI18nContext)}
      </AlertSnackbar>
      <AlertSnackbarContext.Provider value={value}>{children}</AlertSnackbarContext.Provider>
    </>
  );
};

export default AlertSnackbarProvider;
