import { makeAutoObservable } from 'mobx';
import { Forms } from '../models/Form/Forms';
import PopupStore from '../models/Popup/PopupStore';
import Settings from './Settings';
import { TabsModel } from './tabs/TabsModel';
import View, { IView } from './View';
import { Feedback } from '../models/Feedback';
import { AppLayout } from '../models/AppLayout';
import { Shortcuts } from '../models/Shortcuts';
import hotkeys from 'hotkeys-js';

export const APP_NAME = 'Apphouse';

type IAppBase = IView;

/**
 * The main class of the library that will handle the internals of the app.
 * It handles the main state of the app and provides access to all the other classes.
 * Ideally you shouldn't have to deal with any of these classes directly but
 * they are available if you need to.
 */
export class AppBase {
  /**
   * The Feedback class handles all the feedback messages in the app.
   */
  feedback: Feedback;
  /**
   * The Forms class handles all the forms in the app.
   */
  forms: Forms;
  /**
   * The AppLayout class handles the layout of the app.
   * Things like height and width of the sidebar, the header, the footer, etc.
   */
  layout: AppLayout;
  /**
   * The PopupStore class handles all the popups in the app.
   * Popups are a way to show a modal window on top of the current view.
   */
  popups: PopupStore;
  /**
   * The Settings class handles all the settings in the app.
   */
  settings: Settings;
  /**
   * The Shortcuts class handles all the keyboard shortcuts in the app.
   */
  shortcuts: Shortcuts;
  /**
   * The Tabs class handles all the tabs in the app.
   * Tabs are a way to show multiple views at the same time.
   */
  tabs: TabsModel;
  /**
   * The View class handles all the views in the app.
   * A view is a way to show a page in the app.
   * A view is something similar to a route in a traditional web app.
   */
  view: View;

  constructor(props: IAppBase) {
    /**
     * Initialize all the base classes that
     * will handle the main state of the app
     */
    this.feedback = new Feedback();
    this.forms = new Forms();
    this.layout = new AppLayout(props.appLayout || {});
    this.popups = new PopupStore();
    this.settings = new Settings();
    this.view = new View({ appName: props.appName });
    this.shortcuts = new Shortcuts(this.view);
    this.tabs = new TabsModel();

    hotkeys('escape', () => {
      const { popups } = this;
      // for popups, let's check if the popup is enabling close on escape
      // Not sure if this will work, probably not
      if (popups.length > 0) {
        const popup = popups.peak();
        if (popup && popup.popup?.props.disableClosing !== true) {
          this.popups.pop();
        }
      }
      this.view.closeMostRecentOpenedView();
    });

    makeAutoObservable(this);
  }
}
