import { makeAutoObservable } from 'mobx';

const DEFAULT_TYPE = 'floating';
const DEFAULT_POSITION = 'top';
const DEFAULT_VARIANT = 'regular';

const DEFAULT_AUTO_HIDE_DURATION = 6000;

export type FeedbackPositionOptions =
  | 'bottom-end'
  | 'bottom-start'
  | 'bottom'
  | 'left-end'
  | 'left-start'
  | 'left'
  | 'right-end'
  | 'right-start'
  | 'right'
  | 'top-end'
  | 'top-start'
  | 'top'
  | undefined;

export type FeedbackTypeOptions =
  | 'full-width'
  | 'hanging'
  | 'floating'
  | undefined;

export type FeedbackVariantType =
  | 'regular'
  | 'error'
  | 'info'
  | 'success'
  | 'warning'
  | undefined;

type dismissButtonLabel = string | undefined;
type autoHideDuration = number | null | undefined; // default is 6000

export interface FeedbackType {
  autoHideDuration?: autoHideDuration;
  dismissButtonLabel?: dismissButtonLabel;
  message?: string;
  onClose?: () => void;
  position?: FeedbackPositionOptions;
  showLoader?: boolean;
  error?: string;
  type?: FeedbackTypeOptions;
  variant?: FeedbackVariantType;
}

/**
 * The Feedback class is a model for the feedback component
 * This model allows you to show a feedback
 * from anywhere in the app simply calling feedback.setMessage()
 * Example usage:
 *  feedback.setFeedback({
      message: "Error saving data...",
      variant: "error",
    });
 */
export class Feedback {
  autoHideDuration?: autoHideDuration;
  dismissButtonLabel?: dismissButtonLabel;
  message?: string;
  onClose: () => void;
  open: boolean;
  error?: string;
  position?: FeedbackPositionOptions;
  showLoader?: boolean;
  type?: FeedbackTypeOptions;
  variant?: FeedbackVariantType;

  constructor(feedback?: FeedbackType) {
    this.open = false;
    this.onClose = this.defaultOnClose;
    if (feedback) {
      this.setFeedback(feedback);
      this.showFeedback();
    }

    makeAutoObservable(this);
  }

  setFeedback(feedback: FeedbackType) {
    this.dismissButtonLabel = feedback.dismissButtonLabel;
    this.autoHideDuration = feedback.autoHideDuration;
    this.message = feedback.message;
    this.onClose = feedback.onClose || this.defaultOnClose;
    this.open = true;
    this.error = feedback.error;
    this.position = feedback.position || DEFAULT_POSITION;
    this.showLoader = feedback.showLoader || false;
    this.type = feedback.type || DEFAULT_TYPE;
    this.variant = feedback.variant;
    setTimeout(() => {
      this.setOpen(false);
    }, this.autoHideDuration || DEFAULT_AUTO_HIDE_DURATION);
  }

  setOpen = (value: boolean) => {
    this.open = value;
  };

  resetToDefault() {
    this.autoHideDuration = null;
    this.dismissButtonLabel = undefined;
    this.message = undefined;
    this.onClose = this.defaultOnClose;
    this.error = undefined;
    this.open = this.open = false;
    this.position = DEFAULT_POSITION;
    this.showLoader = false;
    this.type = DEFAULT_TYPE;
    this.variant = DEFAULT_VARIANT;
  }

  showFeedback() {
    this.open = true;
  }

  hideFeedback() {
    this.open = false;
  }

  dismiss() {
    this.resetToDefault();
  }

  defaultOnClose() {
    this.hideFeedback();
  }
}
