import { create } from "zustand"

export enum StickyElementNameEnum {
  SITEWIDE_ALERT = "SITEWIDE_ALERT",
  BOOKING_WIDGET = "BOOKING_WIDGET",
  HOTEL_TAB_NAVIGATION = "HOTEL_TAB_NAVIGATION",
  HOTEL_STATIC_MAP = "HOTEL_STATIC_MAP",
}

export interface StickyElement {
  height: number
  ref: React.RefObject<HTMLElement>
  group: string
  priority: number
  name: StickyElementNameEnum
}

interface StickyStore {
  stickyElements: StickyElement[]
  registerSticky: (
    ref: React.RefObject<HTMLElement>,
    name: StickyElementNameEnum,
    group: string
  ) => void
  unregisterSticky: (ref: React.RefObject<HTMLElement>) => void
  updateHeights: () => void
  getAllElements: () => Array<StickyElement>
}

// Map to define priorities based on StickyElementNameEnum
const priorityMap: Record<StickyElementNameEnum, number> = {
  [StickyElementNameEnum.SITEWIDE_ALERT]: 1,
  [StickyElementNameEnum.BOOKING_WIDGET]: 2,

  [StickyElementNameEnum.HOTEL_TAB_NAVIGATION]: 3,
  [StickyElementNameEnum.HOTEL_STATIC_MAP]: 3,
}

const useStickyPositionStore = create<StickyStore>((set, get) => ({
  stickyElements: [],
  registerSticky: (ref, name, group) => {
    const priority = priorityMap[name] || 0

    set((state) => {
      const newStickyElement: StickyElement = {
        height: ref.current?.offsetHeight || 0,
        ref,
        group,
        priority,
        name,
      }

      const updatedStickyElements = [
        ...state.stickyElements,
        newStickyElement,
      ].sort((a, b) => a.priority - b.priority)

      return {
        stickyElements: updatedStickyElements,
      }
    })
  },
  unregisterSticky: (ref) => {
    set((state) => ({
      stickyElements: state.stickyElements.filter((el) => el.ref !== ref),
    }))
  },
  updateHeights: () => {
    set((state) => ({
      stickyElements: state.stickyElements.map((el) => ({
        ...el,
        height: el.ref.current?.offsetHeight || el.height,
      })),
    }))
  },
  getAllElements: () => get().stickyElements,
}))

export default useStickyPositionStore
