import React, { useEffect } from 'react';
import { AppBase } from '../app/AppBase';
import { ApphouseTheme } from '../styles/defaults/themes.interface';
import { observer } from 'mobx-react';
import { applyThemeColorsToHtmlBody } from '../utils/dom/applyThemeToHtmlBody';

import { AppFeedback } from './AppFeedback';
import { AppPopups } from './AppPopups';
import { AppViews } from './AppViews';
import { ApphouseStore } from './ApphouseStore';
import {
  ApphouseContentWrapperProps,
  IApphouseProvider,
  IApphouseThemeProvider,
  IStoreWithBase
} from './context.interface';
import { ApphouseContext } from './ApphouseContext';
import { useApphouse } from './useApphouse';
import { THEMES } from '../themes/presets';

/**
 * Apphouse Provider, an app wrapper that not only offers a
 * seamless store experience for apps but also facilitates advanced
 * functionalities such as efficient routing, effortless feedback handling,
 * streamlined form management, convenient shortcuts, and much more.
 */
export function ApphouseProvider<T>({ children, store }: IApphouseProvider<T>) {
  let _store = store;
  if (!store) {
    // NOTE: This will be a single page app without any routing
    _store = new ApphouseStore('default') as IStoreWithBase<T>;
  }
  const Context = ApphouseContext;
  return (
    <Context.Provider value={{ store: _store }}>{children}</Context.Provider>
  );
}

const ApphouseContentWrapper: React.FC<ApphouseContentWrapperProps> = observer(
  ({ app, children }) => {
    // A wrapper that adds the feedback component to the top of the page
    return (
      <>
        <AppFeedback app={app} />
        <AppPopups app={app} />
        {children}
      </>
    );
  }
);

/**
 * Apphouse Theme Provider
 * It decorates the app with the theme and applies the theme to the body
 */
export function ApphouseThemeProvider<T>({
  theme = THEMES.APPHOUSE_DARK,
  mode,
  children
}: IApphouseThemeProvider) {
  const store = useApphouse<T>();
  const {
    app: { settings }
  } = store;
  if (mode) {
    settings.setThemeId(mode);
  }

  if (theme) {
    settings.setCustomTheme(theme, 'custom');
  }

  useEffect(() => {
    applyThemeColorsToHtmlBody(
      theme?.styles.body.background,
      theme?.styles.body.color
    );
  });
  return (
    <ApphouseContentWrapper app={store.app as AppBase}>
      <AppViews store={store} />
      {children}
    </ApphouseContentWrapper>
  );
}

interface IApphouseApp<T> {
  store: IStoreWithBase<T>;
  theme?: ApphouseTheme;
}
/**
 * Private helper component to wrap the app with the provider
 */
function ApphouseAppWithProvider<T>({ store, theme }: IApphouseApp<T>) {
  return (
    <React.StrictMode>
      <ApphouseProvider store={store}>
        <ApphouseThemeProvider theme={theme} />
      </ApphouseProvider>
    </React.StrictMode>
  );
}

/**
 * Apphouse App, the ultimate app wrapper that serves
 * as an indispensable storefront for your app. Seamlessly
 * integrating with your app, it empowers you with a range of
 * powerful features, including efficient routing, seamless feedback
 * handling, intuitive form management, convenient shortcuts, and a
 * plethora of other cutting-edge functionalities.
 */
export const ApphouseApp: React.FC<{
  store: IStoreWithBase<any>;
  theme?: 'light' | 'dark' | ApphouseTheme;
}> = observer(({ store, theme }) => {
  let customTheme: ApphouseTheme = theme as ApphouseTheme;
  if (typeof theme === 'string') {
    customTheme =
      theme === 'dark' ? THEMES.APPHOUSE_DARK : THEMES.APPHOUSE_LIGHT;
  }
  return (
    <ApphouseAppWithProvider
      store={store}
      theme={customTheme}
    ></ApphouseAppWithProvider>
  );
});
