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 { useBackupServiceListDeletedTidbs } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import {
  Commonv1beta1ServicePlan,
  V1beta2DeletedTidb
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'

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

export function PremiumRecycleBinList({
  planType,
  regionIds,
  startTime,
  endTime,
  hasActiveFilters
}: { planType: 'Premium' | 'BYOC' | 'Essential_V2' } & RecycleBinFilterProps) {
  const {
    store: {
      lastVisitLocation: { orgId }
    }
  } = useStores()
  const { ref, inViewport } = useInViewport()

  // Pagination (cursor-based)
  const [nextPageToken, setNextPageToken] = useState<string | undefined>(undefined)
  const [hasNextPage, setHasNextPage] = useState(true)
  const [displayedTidbs, setDisplayedTidbs] = useState<V1beta2DeletedTidb[]>([])

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

  const servicePlansFilter =
    planType === 'Premium'
      ? [Commonv1beta1ServicePlan.Premium]
      : planType === 'BYOC'
        ? [Commonv1beta1ServicePlan.BYOC]
        : [Commonv1beta1ServicePlan.Essential_V2]

  const {
    data: deletedTidbs,
    isFetching,
    isFetched,
    isError
  } = useBackupServiceListDeletedTidbs(
    {
      orgId,
      projectId: '',
      pageSize: DEFAULT_PAGE_SIZE,
      pageToken: nextPageToken,
      servicePlans: servicePlansFilter,
      regionIds: regionIds.length > 0 ? regionIds : undefined,
      startTime,
      endTime
    },
    {
      query: {
        refetchOnWindowFocus: false,
        enabled: !!orgId && hasNextPage,
        onSuccess(data) {
          setDisplayedTidbs((prev) => {
            const existingIds = new Set(prev.map((t) => t.tidbId))
            const newItems = (data.items ?? []).filter((item) => !existingIds.has(item.tidbId))
            return prev.concat(newItems)
          })
          setHasNextPage(!!data.nextPageToken)
        }
      }
    }
  )

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

  const isInitialLoading = displayedTidbs.length === 0

  return (
    <>
      <HeroComponent ready={isHeroQueryReady({ isFetched, isError })} />
      {displayedTidbs.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>
          {displayedTidbs.map((tidb) => (
            <RecycleBinPremiumCard key={tidb.tidbId} tidb={tidb} />
          ))}
        </>
      )}

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

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

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