import { onMounted, ref, type Ref } from "vue";


export function useSimpleLocalDataStorage<T>(
  subKey: string, 
  requireValueAtLoad = false,
  defaultValue: T|null = null,
) {
  const key = `SimpleLocalDataStorage.${subKey}`;

  async function get() : Promise<T | null> {
    try {
      const res = await uni.getStorage({ key });
      if (res.data) 
        return JSON.parse(res.data) as T;
    } catch (e) {
      console.error(e);
    }
    return defaultValue ?? null;
  }
  async function set(newValue: T|null) {
    if (newValue === null)
      await uni.removeStorage({ key });
    else
      await uni.setStorage({ key, data: JSON.stringify(newValue) });
    value.value = newValue;
  }

  async function update(fn: (oldValue: T|null) => T|null) {
    const oldValue = await get();
    const newValue = fn(oldValue);
    await set(newValue);
    return newValue;
  }
  const value = ref<T|null>(defaultValue) as Ref<T|null>;

  onMounted(async () => {
    if (requireValueAtLoad)
      value.value = await get() as T;
  })

  return {
    get, 
    set,
    update,
    value,
  }
}
export function useSimpleLocalArrayDataStorage<T>(
  subKey: string, 
  requireValueAtLoad = false,
  defaultValue: T[]|null = null,
) {

  const {
    value,
    get, 
    set,
    update,
  } = useSimpleLocalDataStorage<T[]>(subKey, requireValueAtLoad, defaultValue);

  async function arrayRemove(index: number) {
    return await update((a) => {
      if (a instanceof Array)
        return a.filter((_, i) => i !== index);
      return a;
    });
  }
  async function arrayPush(newItem: T) {
    return await update((a) => {
      if (a instanceof Array) {
        a.push(newItem);
        return a;
      }
      return a;
    }); 
  }
  async function arrayUpdate(index: number, updateItem: (old: T) => T) {
    return await update((a) => {
      if (a instanceof Array) {
        a[index] = updateItem(a[index]);
        return a;
      }
      return a;
    }); 
  }

  return {
    get, 
    set,
    update,
    arrayRemove,
    arrayPush,
    arrayUpdate,
    value,
  }
}