import { create, useStore } from "zustand";
import { produce } from "immer";
import { useCallback, useMemo } from "react";
import { last } from "@applicaster/zapp-react-native-utils/utils";

type Dimensions = {
  width: Option<number>;
  height: Option<number>;
};

type DimensionsState = {
  dimensions: Record<string, Dimensions>;
  setCachedDimensions: (id: string, dimensions: Dimensions) => void;
  ids: string[];
};

const dimensionsStore = create<DimensionsState>((set) => ({
  dimensions: {},
  ids: [],
  setCachedDimensions: (id, dimensions) =>
    set(
      produce((draft) => {
        draft.dimensions[id] = dimensions;
        draft.ids.push(id);
      })
    ),
}));

const initialDimensions = () => ({
  width: undefined,
  height: undefined,
});

export const useCachedDimensions = (id: string) => {
  const { dimensions, setCachedDimensions, ids } = useStore(
    dimensionsStore
  ) as DimensionsState;

  const getCachedDimensions = useCallback(() => {
    return dimensions[id] || initialDimensions();
  }, [dimensions?.[id], id]);

  const handleSetCachedDimensions = useCallback((newDimensions) => {
    setCachedDimensions(id, newDimensions);
  }, []);

  const getLastCachedDimensions = useCallback(() => {
    const previousId = last(ids);

    if (!previousId) {
      return undefined;
    }

    return dimensions[previousId];
  }, [dimensions, ids]);

  return useMemo(
    () => ({
      getCachedDimensions,
      setCachedDimensions: handleSetCachedDimensions,
      getLastCachedDimensions,
    }),
    [getCachedDimensions, handleSetCachedDimensions, getLastCachedDimensions]
  );
};
