import { get, writable } from 'svelte/store';
import { getAccountData, setAccountData } from './api';
import { parseDisabledPackImages, withImageEnabled } from './pack-preferences-model';
import type { DisabledPackImages } from './pack-preferences-model';

const EVENT_TYPE = 'dev.malice.pack_preferences';

export const disabledPackImages = writable<DisabledPackImages>({});

let loadGeneration = 0;
let accountGeneration = 0;
let pendingSaves = 0;
let persistedPreferences: DisabledPackImages = {};
let saveQueue: Promise<void> = Promise.resolve();

export async function loadPackPreferences(): Promise<void> {
  if (pendingSaves > 0) return;
  const generation = ++loadGeneration;
  const epoch = accountGeneration;
  try {
    const preferences = parseDisabledPackImages(await getAccountData(EVENT_TYPE));
    if (generation !== loadGeneration || epoch !== accountGeneration || pendingSaves > 0) return;
    persistedPreferences = preferences;
    disabledPackImages.set(preferences);
  } catch {}
}

export function setPackImageEnabled(packId: string, shortcode: string, enabled: boolean): Promise<void> {
  const previous = get(disabledPackImages);
  const next = withImageEnabled(previous, packId, shortcode, enabled);
  if (next === previous) return Promise.resolve();

  const epoch = accountGeneration;
  loadGeneration += 1;
  pendingSaves += 1;
  disabledPackImages.set(next);

  const save = saveQueue.then(async () => {
    if (epoch !== accountGeneration) return;
    await setAccountData(EVENT_TYPE, { disabled: next });
    if (epoch === accountGeneration) persistedPreferences = next;
  });
  saveQueue = save.catch(() => undefined);
  return save.catch((error: unknown) => {
    if (epoch === accountGeneration && get(disabledPackImages) === next) {
      loadGeneration += 1;
      disabledPackImages.set(persistedPreferences);
    }
    throw error;
  }).finally(() => {
    if (epoch === accountGeneration) pendingSaves -= 1;
  });
}

export function resetPackPreferences(): void {
  accountGeneration += 1;
  loadGeneration += 1;
  pendingSaves = 0;
  persistedPreferences = {};
  disabledPackImages.set({});
}
