import { Alert, Center, Loader, Skeleton } from '@tidbcloud/uikit'
import { useInViewport } from '@tidbcloud/uikit/hooks'
import { IconAlertCircle } from '@tidbcloud/uikit/icons'
import { useEffect, useState } from 'react'

import { HeroComponent, isHeroQueryReady } from 'dbaas/components/Measurement'
import { useOrgProjectClusterIds } from 'dbaas/features/Common'
import { useBackupRestoreServiceListRecycledInstances } from 'dbaas/services/api-clients/legacy/serverless'
import { RecycledInstance } from 'dbaas/services/api-clients/legacy/serverless/interface'

import { RecycleBinEssentialCard } from './RecycleBinCard'
import { RecycleBinEmptyState } from './RecycleBinEmptyState'
import { DEFAULT_PAGE_SIZE, getRecycleBinEmptyStateMessage, RecycleBinFilterProps } from './recycleBinUtils'

export function EssentialRecycleBinList({
  regionIds,
  projectIds,
  startTime,
  endTime,
  hasActiveFilters
}: RecycleBinFilterProps) {
  const { orgId } = useOrgProjectClusterIds()
  const { ref, inViewport } = useInViewport()

  // Pagination (page-based)
  const [displayedClusters, setDisplayedClusters] = useState<RecycledInstance[]>([])
  const [hasMore, setHasMore] = useState(true)
  const [nextPageToken, setNextPageToken] = useState<string | undefined>(undefined)

  // Synchronous reset when filters change
  const filterKey = `${JSON.stringify(regionIds)}-${JSON.stringify(projectIds)}-${startTime}-${endTime}`
  const [prevFilterKey, setPrevFilterKey] = useState(filterKey)
  useEffect(() => {
    if (filterKey !== prevFilterKey) {
      setPrevFilterKey(filterKey)
      setNextPageToken(undefined)
      setDisplayedClusters([])
      setHasMore(true)
    }
  }, [filterKey])

  const {
    data: deletedTidbs,
    isFetching,
    isFetched,
    isError
  } = useBackupRestoreServiceListRecycledInstances(
    orgId,
    {
      page_size: DEFAULT_PAGE_SIZE,
      page_token: nextPageToken,
      region_ids: regionIds.length > 0 ? regionIds : undefined,
      project_ids: projectIds.length > 0 ? projectIds : undefined,
      start_time: startTime,
      end_time: endTime
    },
    {
      query: {
        refetchOnWindowFocus: false,
        enabled: !!orgId && hasMore,
        onSuccess(data) {
          setDisplayedClusters((prev) => {
            const existingIds = new Set(prev.map((c) => c.cluster_id))
            const newItems = (data.items ?? []).filter((item) => !existingIds.has(item.cluster_id))
            return prev.concat(newItems)
          })
          setHasMore(!!data.next_page_token)
        }
      }
    }
  )

  // Infinite scroll
  useEffect(() => {
    if (inViewport && hasMore && !isFetching) {
      setNextPageToken(deletedTidbs?.next_page_token)
    }
  }, [inViewport, hasMore, isFetching, deletedTidbs?.next_page_token])

  const isInitialLoading = displayedClusters.length === 0

  return (
    <>
      <HeroComponent ready={isHeroQueryReady({ isFetched, isError })} />
      {displayedClusters.length > 0 && (
        <>
          <Alert color="peacock" icon={<IconAlertCircle />}>
            After you delete an instance, auto-backups whose lifetimes do not exceed the retention period, as set in the
            Backup Settings, will be retained.
          </Alert>
          {displayedClusters.map((cluster) => (
            <RecycleBinEssentialCard key={cluster.cluster_id} cluster={cluster} />
          ))}
        </>
      )}

      {isInitialLoading && isFetching && (
        <>
          <Skeleton height={50} />
          <Skeleton height={50} />
          <Skeleton height={50} />
          <Skeleton height={50} />
          <Skeleton height={50} />
        </>
      )}

      {!isFetching && displayedClusters.length === 0 && (
        <RecycleBinEmptyState
          message={hasActiveFilters ? 'No results match your filters.' : getRecycleBinEmptyStateMessage('Essential')}
        />
      )}

      {!isInitialLoading && !isFetching && hasMore && <div ref={ref} />}
      {!isInitialLoading && isFetching && (
        <Center>
          <Loader size="md" />
        </Center>
      )}
    </>
  )
}
