import { markRaw, readonly, shallowReadonly, shallowRef, watch } from 'vue';
import { cmp, Date } from '@silane/datetime';

import type { WebStorage } from './webstorage';
import { generalTimetableScope } from './webstoragekeys';


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

export function useGeneralTimetableScope(
  localStorage: WebStorage, sessionStorage: WebStorage,
) {
  const today = Date.today();
  const storage = sessionStorage.get(generalTimetableScope, localStorage.get(
    generalTimetableScope, {
      dateRange: [today.isoFormat(), today.isoFormat()] as const,
      classroom: '',
    }
  ));

  const dateRange = shallowRef<[Date, Date]>(
    storage.dateRange.map(x => markRaw(Date.fromISOFormat(x))) as [Date, Date]
  );
  const classroom = shallowRef(storage.classroom);

  watch([dateRange, classroom], () => {
    const storageData = {
      dateRange: dateRange.value.map(x => x.isoFormat()),
      classroom: classroom.value,
    };
    sessionStorage.set(generalTimetableScope, storageData);
    localStorage.set(generalTimetableScope, storageData);
  });

  function setDateRange(range: [Date, Date]) {
    if(cmp(range[0], range[1]) > 0) {
      throw new Error('Start date should be earlier than end date.');
    }
    dateRange.value = range.map(x => markRaw(x)) as [Date, Date];
  }

  function setClassroom(newClassroom: string) {
    classroom.value = newClassroom;
  }

  return {
    dateRange: shallowReadonly(dateRange), classroom: readonly(classroom),
    setDateRange, setClassroom,
  };
}

export type GeneralTimetableScope = ReturnType<typeof useGeneralTimetableScope>;
