"use client"
import { useState, useEffect, useCallback } from "react"
import { useSearchParams, useRouter } from "next/navigation"

interface QueryParamConfig<T = string> {
  key: string
  defaultValue: T
  serialize?: (value: T) => string
  deserialize?: (value: string) => T
}

interface QueryStateReturn<T> {
  value: T
  setValue: (value: T) => void
  removeValue: () => void
}

export function useQueryState<T = string>(
  config: QueryParamConfig<T>
): QueryStateReturn<T> {
  const { key, defaultValue, serialize, deserialize } = config
  const searchParams = useSearchParams()
  const router = useRouter()

  // Initialize state from URL or default
  const [value, setValue] = useState<T>(() => {
    const paramValue = searchParams.get(key)
    if (paramValue !== null) {
      return deserialize ? deserialize(paramValue) : (paramValue as T)
    }
    return defaultValue
  })

  // Update state when URL changes
  useEffect(() => {
    const paramValue = searchParams.get(key)
    if (paramValue !== null) {
      const newValue = deserialize ? deserialize(paramValue) : (paramValue as T)
      setValue(newValue)
    } else {
      setValue(defaultValue)
    }
  }, [searchParams, key, defaultValue, deserialize])

  // Function to update both state and URL
  const updateValue = useCallback((newValue: T) => {
    setValue(newValue)

    const params = new URLSearchParams(searchParams.toString())
    const serializedValue = serialize ? serialize(newValue) : String(newValue)

    if (serializedValue && serializedValue !== String(defaultValue)) {
      params.set(key, serializedValue)
    } else {
      params.delete(key)
    }

    router.replace(`?${params.toString()}`, { scroll: false })
  }, [searchParams, router, key, defaultValue, serialize])

  // Function to remove the parameter (set to default)
  const removeValue = useCallback(() => {
    updateValue(defaultValue)
  }, [updateValue, defaultValue])

  return {
    value,
    setValue: updateValue,
    removeValue
  }
}

// Hook for multiple query parameters
export function useQueryStates<T extends Record<string, any>>(
  configs: { [K in keyof T]: QueryParamConfig<T[K]> }
): {
  [K in keyof T]: QueryStateReturn<T[K]>
} {
  const result = {} as { [K in keyof T]: QueryStateReturn<T[K]> }

  for (const key in configs) {
    result[key] = useQueryState(configs[key])
  }

  return result
}

// Example usage:
//
// Single parameter:
// const { value: tab, setValue: setTab } = useQueryState({
//   key: 'tab',
//   defaultValue: 'daily'
// })
//
// Multiple parameters:
// const queryStates = useQueryStates({
//   tab: { key: 'tab', defaultValue: 'daily' },
//   stylistId: { key: 'stylistId', defaultValue: '' },
//   date: {
//     key: 'date',
//     defaultValue: new Date(),
//     serialize: (date) => date.toISOString(),
//     deserialize: (str) => new Date(str)
//   }
// })
//
// const { value: tab, setValue: setTab } = queryStates.tab
// const { value: stylistId, setValue: setStylistId } = queryStates.stylistId