import {
  NDKFilter,
  NDKKind,
  NDKSubscriptionCacheUsage
} from '@nostr-dev-kit/ndk'
import { ModCard } from 'components/ModCard'
import { ModFilter } from 'components/ModsFilter'
import { PaginationWithPageNumbers } from 'components/Pagination'
import { MAX_MODS_PER_PAGE, T_TAG_VALUE } from 'constants.ts'
import {
  useAppSelector,
  useFilteredMods,
  useMuteLists,
  useNDKContext,
  useNSFWList
} from 'hooks'
import { useEffect, useRef, useState } from 'react'
import { useParams } from 'react-router-dom'
import {
  FilterOptions,
  ModDetails,
  ModeratedFilter,
  NSFWFilter,
  SortBy
} from 'types'
import { extractModData, isModDataComplete, scrollIntoView } from 'utils'

export const GamePage = () => {
  const scrollTargetRef = useRef<HTMLDivElement>(null)
  const params = useParams()
  const { name: gameName } = params
  const { ndk } = useNDKContext()
  const muteLists = useMuteLists()
  const nsfwList = useNSFWList()

  const [filterOptions, setFilterOptions] = useState<FilterOptions>({
    sort: SortBy.Latest,
    nsfw: NSFWFilter.Hide_NSFW,
    source: window.location.host,
    moderated: ModeratedFilter.Moderated
  })
  const [mods, setMods] = useState<ModDetails[]>([])

  const [currentPage, setCurrentPage] = useState(1)

  const userState = useAppSelector((state) => state.user)

  const filteredMods = useFilteredMods(
    mods,
    userState,
    filterOptions,
    nsfwList,
    muteLists
  )

  // Pagination logic
  const totalGames = filteredMods.length
  const totalPages = Math.ceil(totalGames / MAX_MODS_PER_PAGE)
  const startIndex = (currentPage - 1) * MAX_MODS_PER_PAGE
  const endIndex = startIndex + MAX_MODS_PER_PAGE
  const currentMods = filteredMods.slice(startIndex, endIndex)

  const handlePageChange = (page: number) => {
    if (page >= 1 && page <= totalPages) {
      scrollIntoView(scrollTargetRef.current)
      setCurrentPage(page)
    }
  }

  useEffect(() => {
    const filter: NDKFilter = {
      kinds: [NDKKind.Classified],
      '#t': [T_TAG_VALUE]
    }

    const subscription = ndk.subscribe(filter, {
      cacheUsage: NDKSubscriptionCacheUsage.PARALLEL,
      closeOnEose: true
    })

    subscription.on('event', (ndkEvent) => {
      if (isModDataComplete(ndkEvent)) {
        const mod = extractModData(ndkEvent)
        if (mod.game === gameName)
          setMods((prev) => {
            if (prev.find((e) => e.aTag === mod.aTag)) return [...prev]

            return [...prev, mod]
          })
      }
    })

    subscription.start()

    // Cleanup function to stop subscription
    return () => {
      subscription.stop()
    }
  }, [gameName, ndk])

  if (!gameName) return null

  return (
    <>
      <div className='InnerBodyMain'>
        <div className='ContainerMain'>
          <div
            className='IBMSecMainGroup IBMSecMainGroupAlt'
            ref={scrollTargetRef}
          >
            <div className='IBMSecMain'>
              <div className='SearchMainWrapper'>
                <div className='IBMSMTitleMain'>
                  <h2 className='IBMSMTitleMainHeading'>
                    Game:&nbsp;
                    <span className='IBMSMTitleMainHeadingSpan'>
                      {gameName}
                    </span>
                  </h2>
                </div>
              </div>
            </div>
            <ModFilter
              filterOptions={filterOptions}
              setFilterOptions={setFilterOptions}
            />
            <div className='IBMSecMain IBMSMListWrapper'>
              <div className='IBMSMList'>
                {currentMods.map((mod) => (
                  <ModCard key={mod.id} {...mod} />
                ))}
              </div>
            </div>
            <PaginationWithPageNumbers
              currentPage={currentPage}
              totalPages={totalPages}
              handlePageChange={handlePageChange}
            />
          </div>
        </div>
      </div>
    </>
  )
}
