<script lang="ts" context="module">
  const contextKey = {ctx: "itemMultiListContext"};
  
  interface ItemMultiListContextData {
    lists: Readable<Record<string, Item[]>>,
    reloadItemLists(): void,
  };

  const fallback: ItemMultiListContextData = {
    lists: readable({}),
    reloadItemLists() {},
  }

  export function getItemMultiListContext() {
    return getContext(contextKey) as ItemMultiListContextData || fallback
  }
</script>

<script lang="ts">
  import { readable, writable, type Readable } from "svelte/store";
  import { getContext, setContext } from "svelte";
  import type Item from "$lib/models/item";
  import type { ItemFilter } from "$lib/models/item";
  import { getScopeContext } from "./ScopeContext.svelte";
  import deepEqual from "$lib/utils/object";
  import { sl3 } from "$lib/clients/sl3";
  import { getStores } from "$app/stores";

  const {scope} = getScopeContext();
  const {page} = getStores();

  export let lists: Record<string, Item[]>
  export let filters: Record<string, ItemFilter>
  export let global: boolean = false;

  let loaded: Record<string, ItemFilter> = {...filters};
  let loading: Record<string, boolean> = {};
  const listsWritable = writable<Record<string, Item[]>>({...lists});

  function reloadItemLists() {
    loaded = {};
  }

  async function runLoad(key: string, filter: ItemFilter) {
    loading = {...loading, [key]: true};
    
    try {
      const items = await sl3(fetch, $page.stuff.idToken).listItems(global ? "ALL" : $scope.id, filter)
      listsWritable.update(l => ({...l, [key.replace("Filter", "Items")]: items}));
    } catch(_err) {
      // TODO: Use err
    }

    loading = {...loading, [key]: false};
    loaded = {...loaded, [key]: filter};
  }

  setContext<ItemMultiListContextData>(contextKey, {
    lists: {subscribe: listsWritable.subscribe},
    reloadItemLists,
  });

  $: for (const key in filters) {
    if (loading[key]) {
      continue;
    }

    if (loaded[key] == null || !deepEqual(filters[key], loaded[key])) {
      runLoad(key, {...filters[key]})
    }
  }
</script>

<slot></slot>