import { ApiClient } from '@/lib/apiClient';
import { RootStore, Substore, Substores } from '@/state/rootStore';
import { eventLogger } from '@/utils/event-logger';

export default function makeMockRootStore(
  apiClient: ApiClient,
  logger = eventLogger,
  overrideStores?: Partial<Record<keyof Substores, Substore>>
) {
  const createMockSubstore = (name: string, fields?: Record<string, any>) =>
    new Proxy(
      {
        apiClient,
        logger,
        get root() {
          return rootStore;
        },
        ...fields,
      },
      {
        get(target, prop) {
          if (prop in target) {
            return target[prop as keyof typeof target];
          }
          throw new Error(
            `Mock Store (${name}): ${String(prop)} is not implemented`
          );
        },
      }
    ) as Substore;

  const stores = {
    clips: createMockSubstore('clips'),
    contest: createMockSubstore('contest'),
    discover: createMockSubstore('discover'),
    edit: createMockSubstore('edit'),
    featureSession: createMockSubstore('featureSession'),
    genForm: createMockSubstore('genForm'),
    library: createMockSubstore('library'),
    menus: createMockSubstore('menus'),
    notifications: createMockSubstore('notifications'),
    persona: createMockSubstore('persona'),
    queue: createMockSubstore('queue'),
    playbar: createMockSubstore('playbar'),
    playlist: createMockSubstore('playlist'),
    project: createMockSubstore('project'),
    promo: createMockSubstore('promo'),
    session: createMockSubstore('session'),
    social: createMockSubstore('social'),
    tag: createMockSubstore('tag'),
    trash: createMockSubstore('trash'),
    ...overrideStores,
  };

  const rootStore = {
    apiClient,
    logger,
    ...stores,
  } as RootStore;

  return rootStore;
}

export const createMockEventLogger = (apiClient: ApiClient) => {
  let identified = false;

  return new Proxy(
    {
      noop() {},
      initialized: true,
      get identified() {
        return identified;
      },
      set identified(value: boolean) {
        identified = value;
      },
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      track: (eventName: string, properties?: Record<string, unknown>) => {},
      identify() {},
      reset() {
        identified = false;
      },
      apiClient,
      extendSessionLock: true,
      createSessionLock: true,
      init: () => Promise.resolve(),
      segmentTrack: () => {},
      logWebPageEvent: () => {},
      logAudioActionWithContext: () => {},
      logAudioActionEvent: () => {},
      logButtonClickEvent: () => {},
      logNavigationEvent: () => {},
      logUIEvent: () => {},
      trackPageView: () => {},
      trackButtonClick: () => {},
      trackError: () => {},
      logAudioCreationEvent: () => {},
    },
    {
      get(target, prop) {
        if (prop in target) {
          return target[prop as keyof typeof target];
        }
        console.log(`mockEventLogger.${prop.toString()}`);
        return target.noop;
      },
    }
  );
};
