import { useEffect, useRef, useState } from 'react'
import { getFeed, type FeedItem } from '~/lib/api-client'
import { SITE_NAME } from '~/lib/site-config'
import EmptyState from '~/components/EmptyState'
import PageLayout from '~/components/PageLayout'
import PostCard from '~/components/PostCard'
import Spinner from '~/components/Spinner'


export function meta() {
  return [{ title: `Recent Articles — ${SITE_NAME}` }]
}

export default function Recent() {
  const [items, setItems] = useState<FeedItem[]>([])
  // undefined = initial (not yet fetched); string = more pages exist; null = last page
  const [cursor, setCursor] = useState<string | null | undefined>(undefined)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const sentinelRef = useRef<HTMLDivElement>(null)

  // Initial load
  useEffect(() => {
    let cancelled = false
    setLoading(true)
    getFeed()
      .then((page) => {
        if (cancelled) return
        setItems(page.items)
        setCursor(page.cursor)
      })
      .catch((err) => {
        if (!cancelled) setError(err instanceof Error ? err.message : 'Failed to load')
      })
      .finally(() => { if (!cancelled) setLoading(false) })
    return () => { cancelled = true }
  }, [])

  // Infinite scroll — re-attach observer whenever cursor changes to a new page token
  useEffect(() => {
    if (cursor == null || !sentinelRef.current) return
    const sentinel = sentinelRef.current
    const observer = new IntersectionObserver((entries) => {
      if (!entries[0].isIntersecting) return
      observer.disconnect()
      setLoading(true)
      getFeed(cursor)
        .then((page) => {
          setItems((prev) => [...prev, ...page.items])
          setCursor(page.cursor)
        })
        .catch((err) => setError(err instanceof Error ? err.message : 'Failed to load more'))
        .finally(() => setLoading(false))
    })
    observer.observe(sentinel)
    return () => observer.disconnect()
  }, [cursor])

  return (
    <PageLayout>
        <div>
          <h1 className="font-display text-2xl font-semibold text-stone-900 dark:text-white">Recent Articles</h1>
          <p className="text-sm text-stone-500 dark:text-stone-400 mt-1">Discover what's being written on the Atmosphere</p>
        </div>

        {error && <p className="text-sm text-red-500">{error}</p>}

        {cursor === undefined && loading && (
          <div className="flex justify-center py-12">
            <Spinner />
          </div>
        )}

        {cursor !== undefined && items.length === 0 && !loading && (
          <EmptyState message="No articles yet." />
        )}

        <ul className="space-y-2.5">
          {items.map((item) => {
            const did = item.atUri.split('/')[2]
            const rkey = item.atUri.split('/').pop()!
            const pubRkey = item.site.startsWith('at://') ? item.site.split('/').pop() : undefined
            return (
              <PostCard
                key={item.sk}
                authorDid={did}
                rkey={rkey}
                pubRkey={pubRkey}
                title={item.title}
                publishedAt={item.publishedAt}
                resolvedHandle={item.resolvedHandle}
                publicationName={item.resolvedPubName}
                coverImageCid={item.coverImageRef}
                resolvedUrl={item.resolvedUrl}
                path={item.path}
                textContent={item.textContent}
                description={item.description}
              />
            )
          })}
        </ul>

        {/* Sentinel div — scrolling it into view triggers the next page fetch */}
        <div ref={sentinelRef} />

        {loading && cursor !== undefined && (
          <div className="flex justify-center py-4">
            <Spinner size="md" />
          </div>
        )}

        {cursor === null && items.length > 0 && (
          <p className="text-center text-sm text-stone-400 dark:text-stone-600 py-4">
            You've reached the end.
          </p>
        )}
    </PageLayout>
  )
}
