import { useCallback, useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/router'

export function parseDetailTabQuery<T extends string>(
  value: string | string[] | undefined,
  validTabs: readonly T[],
  defaultTab: T,
): T {
  const raw = typeof value === 'string' ? value : Array.isArray(value) ? value[0] : undefined
  if (raw && validTabs.includes(raw as T)) {
    return raw as T
  }
  return defaultTab
}

export function useDetailTabQuery<T extends string>(
  validTabs: readonly T[],
  defaultTab: T,
  resetKey?: string,
) {
  const router = useRouter()
  const [activeTab, setActiveTabState] = useState<T>(defaultTab)
  const tabSet = useMemo(() => new Set(validTabs), [validTabs])

  useEffect(() => {
    if (!router.isReady) {
      return
    }
    setActiveTabState(parseDetailTabQuery(router.query.tab, validTabs, defaultTab))
  }, [defaultTab, resetKey, router.isReady, router.query.tab, validTabs])

  useEffect(() => {
    if (!tabSet.has(activeTab)) {
      setActiveTabState(defaultTab)
    }
  }, [activeTab, defaultTab, tabSet])

  const setActiveTab = useCallback(
    (tab: T) => {
      if (!tabSet.has(tab)) {
        return
      }

      setActiveTabState(tab)

      if (!router.isReady) {
        return
      }

      const query = { ...router.query }
      if (tab === defaultTab) {
        delete query.tab
      } else {
        query.tab = tab
      }

      void router.replace({ pathname: router.pathname, query }, undefined, { shallow: true })
    },
    [defaultTab, router, tabSet],
  )

  return { activeTab, setActiveTab, isReady: router.isReady }
}
