import { QueryClient } from '@tanstack/react-query';
import { makeAutoObservable } from 'mobx';

import { ApiClient } from '@/lib/apiClient';
import { EventLogger } from '@/utils/event-logger';

export type BaseRootStore<
  S extends Record<PropertyKey, BaseSubstore> = Record<PropertyKey, any>,
> = {
  apiClient: ApiClient;
  queryClient: QueryClient;
  logger: EventLogger;
  isLocalStorageAvailable: boolean;
} & S;

export interface BaseSubstore<R extends BaseRootStore = BaseRootStore> {
  readonly root: R;
  readonly apiClient: ApiClient;
  readonly queryClient?: QueryClient;
  readonly logger?: EventLogger;
  readonly isLocalStorageAvailable?: boolean;
  initialize?: (isClient?: boolean) => void;
}

type AutoObservableConfig<
  T extends object,
  K extends PropertyKey = never,
> = Parameters<typeof makeAutoObservable<T, K>>;

/**
 * Sets up a store so that it has access to the root store and is auto-observable
 */
export function makeAutoObservableSubstore<
  T extends BaseSubstore = BaseSubstore,
  K extends PropertyKey = never,
>(
  target: T,
  overrides?: AutoObservableConfig<T, K>[1],
  options?: AutoObservableConfig<T, K>[2]
) {
  return makeAutoObservable(
    target,
    {
      root: false,
      apiClient: false,
      queryClient: false,
      logger: false,
      isLocalStorageAvailable: false,
      ...overrides,
    },
    options
  );
}
