import { useCoreServices } from '@learnitive/context';
import React, { useEffect } from 'react';
import { interactiveDocSaveStatus } from './interactive-content/save-status';

type SaveStatusSource = {
  hasPendingOrFailedSave: () => boolean;
  subscribeToSaveStatus: (listener: () => void) => () => void;
};

type UnsavedChangesTarget = {
  setUnsavedChanges: (hasUnsavedChanges: boolean) => void;
};

export function connectSaveProtection(
  saveStatus: SaveStatusSource | readonly SaveStatusSource[],
  navigation: UnsavedChangesTarget,
): () => void {
  const sources = Array.isArray(saveStatus) ? saveStatus : [saveStatus];
  const syncProtection = () => {
    navigation.setUnsavedChanges(
      sources.some((source) => source.hasPendingOrFailedSave()),
    );
  };

  syncProtection();
  const unsubscribes = sources.map((source) =>
    source.subscribeToSaveStatus(syncProtection),
  );

  return () => {
    for (const unsubscribe of unsubscribes) {
      unsubscribe();
    }
    navigation.setUnsavedChanges(false);
  };
}

export function SaveProtection() {
  const { navigation, editorEngine, latexSource } = useCoreServices();

  useEffect(
    () => connectSaveProtection([editorEngine, latexSource, interactiveDocSaveStatus], navigation),
    [navigation, editorEngine, latexSource],
  );

  return null;
}
