import { markRaw, readonly, shallowRef, watch } from 'vue';
import { Date, cmp } from '@silane/datetime';
import type { WebStorage } from './webstorage';
import {
  generalTimetableScopeHistory as historyStorageKey,
} from './webstoragekeys';
import type { GeneralTimetableScope } from './general-timetable-scope';


export type GeneralTimetableScopeHistoryStorageType = {
  dateRange: [string, string],
  classroom: string,
}[];

type GeneralTimetableScopeValue = {
  classroom: string, dateRange: [Date, Date],
};

export function useGeneralTimetableScopeHistory(
  localStorage: WebStorage,
  generalTimetableScope: GeneralTimetableScope, maxHistoryCount: number,
) {
  function generalTimetableScopeValueEquals(
    a: GeneralTimetableScopeValue, b: GeneralTimetableScopeValue
  ) {
    return a.classroom === b.classroom && a.dateRange.every((_, idx) => cmp(
      a.dateRange[idx], b.dateRange[idx]
    ) === 0)
  }

  const storage = localStorage.get(historyStorageKey, []);

  const history = shallowRef<GeneralTimetableScopeValue[]>(storage.map(x => ({
    classroom: x.classroom,
    dateRange: x.dateRange.map(d => markRaw(Date.fromISOFormat(d))),
  })));

  watch([
    generalTimetableScope.classroom, generalTimetableScope.dateRange
  ], () => {
    const newValue = {
      classroom: generalTimetableScope.classroom.value,
      dateRange: generalTimetableScope.dateRange.value,
    };
    const sameValueIdx = history.value.findIndex(
      x => generalTimetableScopeValueEquals(x, newValue)
    );
    if(sameValueIdx === -1) {
      history.value = [newValue, ...history.value].toSpliced(
        -1, history.value.length > maxHistoryCount ? 1 : 0
      );
    } else {
      history.value = [newValue, ...history.value].toSpliced(sameValueIdx + 1, 1);
    }
  }, { immediate: true });

  watch(history, () => {
    localStorage.set(historyStorageKey, history.value.map(x => ({
      classroom: x.classroom, dateRange: x.dateRange.map(x => x.isoFormat()),
    })))
  });

  return { history: readonly(history) };
}

export type GeneralTimetableScopeHistory = ReturnType<
  typeof useGeneralTimetableScopeHistory
>;
