import { useRef } from 'react'
import type { Article } from '@/types/nostr'
import { ArticleCard } from './ArticleCard'
import { ErrorState, EmptyState, Skeleton } from './ui'
import { t } from '@/lib/i18n'
import { useArrowNavigation } from '@/hooks/useArrowNavigation'

interface ArticlesListProps {
  articles: Article[]
  allArticles: Article[]
  loading: boolean
  error: string | null
  onUnlock: (article: Article) => void
  unlockedArticles: Set<string>
}

function ArticleCardSkeleton(): React.ReactElement {
  return (
    <div className="border border-neon-cyan/30 rounded-lg p-6 bg-cyber-dark space-y-4">
      <div className="space-y-2">
        <Skeleton variant="rectangular" height={24} className="w-3/4" />
        <Skeleton variant="rectangular" height={16} className="w-1/2" />
      </div>
      <Skeleton variant="rectangular" height={100} className="w-full" />
      <div className="flex items-center justify-between">
        <Skeleton variant="circular" width={32} height={32} />
        <Skeleton variant="rectangular" height={36} className="w-32" />
      </div>
    </div>
  )
}

function LoadingState(): React.ReactElement {
  return (
    <div className="space-y-6">
      {Array.from({ length: 3 }, (_, index) => (
        <ArticleCardSkeleton key={`article-skeleton-${index}`} />
      ))}
    </div>
  )
}

function ArticlesEmptyState({ hasAny }: { hasAny: boolean }): React.ReactElement {
  return (
    <EmptyState
      title={hasAny ? t('common.empty.articles.filtered') : t('common.empty.articles')}
    />
  )
}

function ArticlesErrorState({ error }: { error: string }): React.ReactElement {
  const errorObj = new Error(error)
  return (
    <ErrorState
      message={error}
      error={errorObj}
      onRetry={() => {
        window.location.reload()
      }}
      onCheckConnection={() => {
        if (navigator.onLine) {
          window.location.reload()
        } else {
          // eslint-disable-next-line no-alert
          alert(t('errors.network.offline'))
        }
      }}
    />
  )
}

function ArticlesContent({
  articles,
  allArticles,
  onUnlock,
  unlockedArticles,
  containerRef,
}: {
  articles: Article[]
  allArticles: Article[]
  onUnlock: (article: Article) => void
  unlockedArticles: Set<string>
  containerRef: React.RefObject<HTMLDivElement | null>
}): React.ReactElement {
  return (
    <section id="articles-section" aria-label={t('navigation.articlesSection')} tabIndex={-1}>
      <div className="mb-4 text-sm text-cyber-accent/70">
        Showing {articles.length} of {allArticles.length} article{allArticles.length !== 1 ? 's' : ''}
      </div>
      <div ref={containerRef} className="space-y-6" role="list">
        {articles.map((article) => (
          <div key={article.id} role="listitem">
            <ArticleCard
              article={{ ...article, paid: unlockedArticles.has(article.id) || article.paid }}
              onUnlock={onUnlock}
              allArticles={allArticles}
              unlockedArticles={unlockedArticles}
            />
          </div>
        ))}
      </div>
    </section>
  )
}

export function ArticlesList({
  articles,
  allArticles,
  loading,
  error,
  onUnlock,
  unlockedArticles,
}: ArticlesListProps): React.ReactElement {
  const containerRef = useRef<HTMLDivElement>(null)
  useArrowNavigation({ itemCount: articles.length, containerRef, enabled: !loading && articles.length > 0 })

  if (loading) {
    return <LoadingState />
  }
  if (error) {
    return <ArticlesErrorState error={error} />
  }
  if (articles.length === 0) {
    return <ArticlesEmptyState hasAny={allArticles.length > 0} />
  }

  return (
    <ArticlesContent
      articles={articles}
      allArticles={allArticles}
      onUnlock={onUnlock}
      unlockedArticles={unlockedArticles}
      containerRef={containerRef}
    />
  )
}
