import { DataStore } from "/js/dataLayer/dataStore.js";
import { PatchStore } from "/js/dataLayer/patchStore.js";
import { Mutations } from "/js/dataLayer/mutations.js";
import { Requests } from "/js/dataLayer/requests.js";
import { Declarative } from "/js/dataLayer/declarative.js";
import { Derived } from "/js/dataLayer/derived.js";

export class DataLayer {
  constructor(
    api,
    pluginService,
    preferencesProvider,
    identityResolver,
    draftMediaStore,
  ) {
    this.api = api;
    this.pluginService = pluginService;
    this.identityResolver = identityResolver;
    this.draftMediaStore = draftMediaStore;
    this.isAuthenticated = api.isAuthenticated;
    this.dataStore = new DataStore();
    this.patchStore = new PatchStore(this.dataStore);
    this.preferencesProvider = preferencesProvider;
    this.requests = new Requests(
      this.api,
      this.dataStore,
      this.preferencesProvider,
      this.pluginService,
      this.draftMediaStore,
    );
    this.pluginService?.on("feedFiltersRefresh", async ({ feedURI }) => {
      const feedURIs = feedURI
        ? [feedURI]
        : Array.from(this.dataStore.$feeds.keys());
      await Promise.all(
        feedURIs.map((uri) => {
          const feed = this.dataStore.$feeds.get(uri);
          if (!feed) return;
          return this.pluginService.refreshFiltersForFeed(uri, feed, {
            reload: true,
          });
        }),
      );
    });
    this.mutations = new Mutations(
      this.api,
      this.dataStore,
      this.patchStore,
      this.preferencesProvider,
      this.identityResolver,
      this.draftMediaStore,
    );
    this.derived = new Derived(
      this.dataStore,
      this.patchStore,
      this.preferencesProvider,
      this.pluginService,
      this.isAuthenticated,
      this.draftMediaStore,
    );
    this.declarative = new Declarative(this.derived, this.requests);
    this.subscribers = [];
  }

  async initializePreferences() {
    return this.preferencesProvider.fetchPreferences();
  }

  hasCachedFeed(feedURI) {
    return this.dataStore.$feeds.get(feedURI) !== null;
  }

  hasCachedAuthorFeed(profileDid, feedType) {
    const feedURI = `${profileDid}-${feedType}`;
    return this.dataStore.$authorFeeds.get(feedURI) !== null;
  }
}
