import { useMemo, useState } from 'react'

import { useQuery } from '@tanstack/react-query'
import { getCoreRowModel, useReactTable } from '@tanstack/react-table'

import { listApis } from '@/api'
import { hasPermission } from '@/lib'
import { type Api, type SearchApiParams } from '@/schemas'

import { ActionDialogs } from './components/action-dialogs.tsx'
import { ApiTable } from './components/api-table.tsx'
import { createColumns } from './components/columns.tsx'
import { CrudProvider } from './components/crud-provider.tsx'
import { QUERY_KEY } from './constants.ts'

export default function CrudPage() {
  const [pagination, setPagination] = useState({
    pageIndex: 0,
    pageSize: 10,
  })

  const [searchParams, setSearchParams] = useState<SearchApiParams>({})

  const { data, isFetching, refetch } = useQuery({
    queryKey: [QUERY_KEY, pagination.pageIndex, pagination.pageSize, searchParams],
    queryFn: () =>
      listApis({
        page: pagination.pageIndex + 1,
        page_size: pagination.pageSize,
        ...searchParams,
      }),
    placeholderData: (prev) => prev,
    enabled: hasPermission('api:list'),
  })

  const tableData = useMemo<Api[]>(() => data?.list ?? [], [data])

  const columns = useMemo(() => createColumns(), [])

  const table = useReactTable<Api>({
    data: tableData,
    columns,
    getCoreRowModel: getCoreRowModel(),
    manualPagination: true,
    rowCount: data?.total,
    state: { pagination },
    onPaginationChange: setPagination,
    meta: {
      isFetching,
      refetch,
    },
  })

  const handleSearch = (params: SearchApiParams) => {
    const isSameParams = JSON.stringify(params) === JSON.stringify(searchParams)

    setSearchParams(params)
    setPagination((prev) => ({ ...prev, pageIndex: 0 }))

    if (isSameParams && pagination.pageIndex === 0) {
      void refetch()
    }
  }

  return (
    <CrudProvider>
      <ActionDialogs />

      <ApiTable table={table} onSearch={handleSearch} />
    </CrudProvider>
  )
}
