import { ApolloClient } from '@apollo/client';
import { configure } from 'mobx';
import { enableStaticRendering } from 'mobx-react';
import Change from 'store/change';
import Checkout from 'store/checkout';
import Claims from 'store/claims';
import Fiber from 'store/fiber';
import Hradleid from 'store/hradleid';
import Profiles from 'store/profiles';
import UI from 'store/ui';

import Authentication from './authentication';
import Cart from './cart';
import MobileSignup from './mobileSignup';
import { signupStepsStore } from './signupSteps';

const isServer = typeof window === 'undefined';

enableStaticRendering(isServer);

/*
  Disable strict mode warnings after upgrading to 6.
  We might want to consider refactoring. see:
  https://mobx.js.org/configuration.html#enforceactions
*/
configure({
  enforceActions: 'never',
});

let store: any = null;

export default function initializeStore(
  state = {},
  query: any,
  apolloClient: ApolloClient<object> | undefined,
  cookies?: string | object | null,
) {
  if (!query) {
    return;
  }

  let requiresApolloClient = {};
  const { ssn } = query;

  const subscriptionId = Array.isArray(query.subscriptionId)
    ? query.subscriptionId[0]
    : query.subscriptionId;

  if (isServer) {
    const authentication = new Authentication(
      state,
      { ssn: ssn as string, subscriptionId: subscriptionId as string },
      cookies,
    );

    if (apolloClient) {
      const cart = new Cart(state, apolloClient, authentication, cookies);
      const mobileSignup = new MobileSignup(state, apolloClient, cart, cookies, authentication);
      signupStepsStore.setMobileSignup(mobileSignup);
      requiresApolloClient = {
        mobileSignup,
        cart,
      };
    }

    return {
      authentication,
      profiles: new Profiles(state, authentication),
      claims: new Claims(state, authentication),
      ui: new UI(state),
      checkout: new Checkout(state),
      change: new Change(state),
      fiber: new Fiber(state),
      hradleid: new Hradleid(state),
      signupSteps: signupStepsStore,
      ...requiresApolloClient,
    };
  }
  if (store === null) {
    const authentication = new Authentication(state, { ssn, subscriptionId }, '');
    if (apolloClient) {
      const cart = new Cart(state, apolloClient, authentication, cookies);
      const mobileSignup = new MobileSignup(state, apolloClient, cart, cookies, authentication);
      signupStepsStore.setMobileSignup(mobileSignup);
      requiresApolloClient = {
        mobileSignup,
        cart,
      };
    }
    store = {
      authentication,
      profiles: new Profiles(state, authentication),
      claims: new Claims(state, authentication),
      ui: new UI(state),
      checkout: new Checkout(state),
      change: new Change(state),
      fiber: new Fiber(state),
      signupSteps: signupStepsStore,
      hradleid: new Hradleid(state),
      ...requiresApolloClient,
    };
  }
  return store;
}
