import { useAccount } from '@lifi/wallet-management'
import { Box, List } from '@mui/material'
import { useVirtualizer } from '@tanstack/react-virtual'
import { type JSX, useCallback, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { PageContainer } from '../../components/PageContainer.js'
import { TransactionCardSkeleton } from '../../components/TransactionCard/TransactionCardSkeleton.js'
import { useHeader } from '../../hooks/useHeader.js'
import { useListHeight } from '../../hooks/useListHeight.js'
import { useTransactionList } from '../../hooks/useTransactionList.js'
import { useRouteExecutionStore } from '../../stores/routes/RouteExecutionStore.js'
import { RouteExecutionStatus } from '../../stores/routes/types.js'
import { ActiveTransactionItem } from './ActiveTransactionItem.js'
import { ActivitiesPageMenuButton } from './ActivitiesPageMenuButton.js'
import { TransactionHistoryEmpty } from './TransactionHistoryEmpty.js'
import { TransactionHistoryItem } from './TransactionHistoryItem.js'

const SKELETON_COUNT = 2

export const ActivitiesPage = (): JSX.Element => {
  // Parent ref and useVirtualizer should be in one file to avoid blank page (0 virtual items) issue
  const parentRef = useRef<HTMLDivElement | null>(null)
  const { items, isLoading } = useTransactionList()

  const { t } = useTranslation()
  const { accounts } = useAccount()
  const accountAddresses = useMemo(
    () => accounts.map((account) => account.address),
    [accounts]
  )
  const hasFailedItems = useRouteExecutionStore(
    useCallback(
      (state) =>
        Object.values(state.routes).some(
          (r) =>
            r?.status === RouteExecutionStatus.Failed &&
            accountAddresses.includes(r.route.fromAddress)
        ),
      [accountAddresses]
    )
  )

  useHeader(
    t('header.activities'),
    hasFailedItems ? <ActivitiesPageMenuButton /> : null
  )

  const { listHeight } = useListHeight({
    listParentRef: parentRef,
  })

  const hasStoreItems = items.length > 0
  const skeletonCount = isLoading && hasStoreItems ? SKELETON_COUNT : 0
  const totalCount = items.length + skeletonCount

  const getItemKey = useCallback(
    (index: number) => {
      if (index >= items.length) {
        return `skeleton-${index}`
      }
      const item = items[index]
      if (item.type === 'active') {
        return `active-${item.routeId}`
      }
      return `${item.type}-${item.txHash || item.routeExecution.route.id}`
    },
    [items]
  )

  const { getVirtualItems, getTotalSize, measureElement } = useVirtualizer({
    count: hasStoreItems ? totalCount : 0,
    overscan: 3,
    paddingEnd: 12,
    getScrollElement: () => parentRef.current,
    estimateSize: (index) => (items[index]?.type === 'active' ? 218 : 196),
    getItemKey,
  })

  const isEmpty = !items.length && !isLoading

  return (
    <PageContainer disableGutters>
      <Box
        className="long-list"
        ref={parentRef}
        style={{ height: listHeight }}
        sx={{ overflow: 'auto', paddingX: 3, paddingTop: 1.5 }}
      >
        {isEmpty ? (
          <TransactionHistoryEmpty />
        ) : isLoading && !hasStoreItems ? (
          <List
            disablePadding
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: 2,
              marginBottom: 2,
            }}
          >
            {Array.from({ length: SKELETON_COUNT }).map((_, index) => (
              <TransactionCardSkeleton key={index} />
            ))}
          </List>
        ) : (
          <List
            style={{ height: getTotalSize(), position: 'relative' }}
            disablePadding
          >
            {getVirtualItems().map((item) => {
              const listItem =
                item.index < items.length ? items[item.index] : null
              return (
                <li
                  key={item.key}
                  ref={measureElement}
                  data-index={item.index}
                  style={{
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    width: '100%',
                    paddingBottom: 16,
                    transform: `translateY(${item.start}px)`,
                    listStyle: 'none',
                  }}
                >
                  {!listItem ? (
                    <TransactionCardSkeleton />
                  ) : listItem.type === 'active' ? (
                    <ActiveTransactionItem routeId={listItem.routeId} />
                  ) : (
                    <TransactionHistoryItem
                      route={listItem.routeExecution.route}
                      type={listItem.type}
                      transactionHash={listItem.txHash}
                      startedAt={listItem.startedAt}
                    />
                  )}
                </li>
              )
            })}
          </List>
        )}
      </Box>
    </PageContainer>
  )
}
