import { useCallback, useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { api } from '@/lib/api'
import type { PagedResult } from '@/lib/types'
import type { SortOrder } from '@/components/DataTable'

export function useCatalogList<T>(url: string, extraParams: Record<string, string | number | boolean | undefined> = {}) {
  const [page, setPage] = useState(1)
  const [search, setSearch] = useState('')
  const [sortKey, setSortKey] = useState<string | null>(null)
  const [sortOrder, setSortOrder] = useState<SortOrder>('asc')

  const setSort = useCallback((key: string, order: SortOrder) => {
    setSortKey(key)
    setSortOrder(order)
    setPage(1)
  }, [])

  const query = useQuery({
    queryKey: [url, page, search, sortKey, sortOrder, extraParams],
    queryFn: async () => {
      const params = new URLSearchParams({
        page: String(page),
        pageSize: '50',
        ...(search ? { search } : {}),
        ...(sortKey ? { sort: sortKey, order: sortOrder } : {}),
        ...Object.fromEntries(
          Object.entries(extraParams).filter(([, v]) => v !== undefined && v !== '').map(([k, v]) => [k, String(v)])
        ),
      })
      const res = await api.get<PagedResult<T>>(`${url}?${params}`)
      return res.data
    },
    placeholderData: (prev) => prev,
  })

  return { page, setPage, search, setSearch, sortKey, sortOrder, setSort, ...query }
}

export function useCatalogMutations(url: string, listUrl: string) {
  const qc = useQueryClient()
  const create = useMutation({
    mutationFn: async (input: unknown) => (await api.post(url, input)).data,
    onSuccess: () => qc.invalidateQueries({ queryKey: [listUrl] }),
  })
  const update = useMutation({
    mutationFn: async ({ id, input }: { id: string; input: unknown }) => (await api.put(`${url}/${id}`, input)).data,
    onSuccess: () => qc.invalidateQueries({ queryKey: [listUrl] }),
  })
  const remove = useMutation({
    mutationFn: async (id: string) => (await api.delete(`${url}/${id}`)).data,
    onSuccess: () => qc.invalidateQueries({ queryKey: [listUrl] }),
  })
  return { create, update, remove }
}
