import { createManagerActor } from '../utils/manager.utils';
import { initIdentity } from '../utils/identity.utils';
import { uploadDeckBackgroundAssets, uploadSlideAssets } from '../utils/sync.storage.utils';
import { deleteSlide, uploadDeckData, uploadSlideData } from '../utils/sync.data.utils';
import { updateDeckBackground, updateSlideChart, updateSlideImages } from '../utils/sync.attributes.utils';
export const uploadWorker = async ({ internetIdentity: { delegationChain, identityKey }, syncData, host }, syncWindow) => {
  if (!syncData) {
    return;
  }
  if (!delegationChain || !identityKey) {
    return;
  }
  const identity = initIdentity({ identityKey, delegationChain });
  const { updateDecks, updateSlides, deleteSlides: slidesToDelete } = syncData;
  const managerActor = await createManagerActor({ identity, host });
  await uploadDecks({ updateDecks, identity, managerActor, host, syncWindow });
  await uploadSlides({ updateSlides, identity, managerActor, host, syncWindow });
  await deleteSlides({ deleteSlides: slidesToDelete, identity, managerActor, host });
  // TODO: handle delete decks here?
  // TODO: upload slides assets and update DOM through postMessage
};
const uploadDecks = async ({ updateDecks, identity, managerActor, host, syncWindow }) => {
  if (!updateDecks || updateDecks.length <= 0) {
    return;
  }
  const promises = updateDecks.map(({ deck }) => uploadDeck({ deck, managerActor: managerActor, identity, host, syncWindow }));
  await Promise.all(promises);
  console.log('Deck IC synced');
};
const uploadDeck = async ({ deck, managerActor, identity, host, syncWindow }) => {
  if (!deck) {
    return;
  }
  // 1. We upload the asset to the IC (worker side), update DOM and IDB (window side for thread safe reason) and clean the asset from IDB
  const { src: imgSrc, storageFile } = await uploadDeckBackgroundAssets({ deck, host, identity, syncWindow });
  // 2. If we uploaded an asset, its URL has changed (no more local but available online)
  const updateDeck = updateDeckBackground({ deck, imgSrc, storageFile });
  // 3. We can update the data in the IC
  await uploadDeckData({ deck: updateDeck, managerActor, identity, host });
};
const uploadSlides = async ({ updateSlides, identity, managerActor, host, syncWindow }) => {
  if (!updateSlides || updateSlides.length <= 0) {
    return;
  }
  const promises = updateSlides.map(({ slide, deckId }) => uploadSlide({ slide, deckId, managerActor: managerActor, identity, host, syncWindow }));
  await Promise.all(promises);
};
const deleteSlides = async ({ deleteSlides, identity, managerActor, host }) => {
  if (!deleteSlides || deleteSlides.length <= 0) {
    return;
  }
  const promises = deleteSlides.map(({ deckId, slideId }) => deleteSlide({ slideId, deckId, identity, managerActor: managerActor, host }));
  await Promise.all(promises);
};
const uploadSlide = async ({ slide, deckId, managerActor, identity, host, syncWindow }) => {
  if (!slide) {
    return;
  }
  // 1. We upload the asset to the IC (worker side), update DOM and IDB (window side for thread safe reason) and clean the asset from IDB
  const { images, chart } = await uploadSlideAssets({ slide, deckId, host, identity, syncWindow });
  // 2. If we uploaded assets, there URL have changed (no more local but available online)
  const updateChartSlide = updateSlideChart({ slide, chart });
  const updateSlide = updateSlideImages({ slide: updateChartSlide, images });
  // 3. We can update the data in the IC
  await uploadSlideData({ slide: updateSlide, deckId, managerActor, identity, host });
};
