import { defineStore } from 'pinia'
import { Breadcrumb } from '@/components/nav/nav'
import { computed, MaybeRefOrGetter, ref, toRef, watch } from 'vue'
import { tryOnScopeDispose } from '@vueuse/core'
import { useShowStore } from '@/stores/shows'
import { RouteLocationNormalizedLoaded, useRoute } from 'vue-router'
import { merge } from 'lodash'
import { useId } from '@/util'

export function useBreadcrumbs(breadcrumbs: MaybeRefOrGetter<Breadcrumb[]>) {
  const store = useNavStore()
  const unwatch = watch(
    toRef(breadcrumbs),
    (_breadcrumbs) => {
      store.breadcrumbs = _breadcrumbs
    },
    { immediate: true },
  )
  tryOnScopeDispose(() => {
    unwatch()
    store.breadcrumbs = []
  })
}

const definedNavigationContext = ref(new Map<string, Record<string, unknown>>())

export function defineNavigationContext(context: MaybeRefOrGetter<Record<string, unknown>>) {
  const _context = toRef(context)
  const id = useId('nav-context-ref')
  const unwatch = watch(
    _context,
    (context) => {
      definedNavigationContext.value.set(id.value, context)
    },
    { immediate: true },
  )
  tryOnScopeDispose(() => {
    unwatch()
    definedNavigationContext.value.delete(id.value)
  })
}

export function useNavigationContext() {
  const store = useNavStore()
  return computed(() => store.navigationContext)
}

export const useNavStore = defineStore('nav', () => {
  const breadcrumbs = ref<Breadcrumb[]>([])
  const showStore = useShowStore()
  const route = useRoute()
  const navigationContext = computed<
    Record<string, unknown> & {
      route: RouteLocationNormalizedLoaded
    }
  >(() => {
    const mergedDefinedContext = merge({}, ...definedNavigationContext.value.values())
    return { route, show: showStore.selectedShow, ...mergedDefinedContext }
  })

  return {
    breadcrumbs,
    navigationContext,
  }
})