import { FlashList } from '@shopify/flash-list'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import type { ErrorBoundaryProps } from 'expo-router'
import { Pressable, RefreshControl } from 'react-native'
import { EmptyState } from 'src/components/common/EmptyState'
import { ErrorState } from 'src/components/common/ErrorState'
import { LoadingView } from 'src/components/common/LoadingView'
import {
  ScreenScrollContainer,
  useAccentRefreshControlProps,
} from 'src/components/layout'
import { BodyText, Card, FootnoteText, SubheadText } from 'src/components/ui'
import { useNewsroomMarkReadMutation } from 'src/hooks/mutations/useNewsroomMarkReadMutation'
import { useRequireHalflight } from 'src/hooks/useRequirePixelfed'
import type { NewsroomItem } from 'src/lib/api-types'
import { haptic } from 'src/lib/haptics'
import { newsroomQueries } from 'src/lib/queries/newsroom'
import { AccountStore } from 'src/state/accountStore'
import { openBrowserAsync } from 'src/utils'
import { Separator, YStack } from 'tamagui'

export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
  return <ErrorState message={error.message} onRetry={retry} />
}

export default function Page() {
  // Newsroom is Halflight-only — vanilla Pixelfed lacks the CSRF carve-out
  // for the mark-as-read POST, and Mastodon doesn't expose the endpoint at
  // all. Redirect non-Halflight sessions away as a belt-and-braces fallback
  // for deep links / back-nav that bypass the gated entry row.
  useRequireHalflight()
  const instance = AccountStore.activeAccount()?.instance ?? 'this server'

  const queryClient = useQueryClient()
  const refreshProps = useAccentRefreshControlProps()
  const { data, error, isPending, isRefetching, refetch } = useQuery(
    newsroomQueries.timeline()
  )
  const markRead = useNewsroomMarkReadMutation()

  if (isPending) return <LoadingView />
  if (error) return <ErrorState onRetry={refetch} />

  const items = data ?? []

  const handlePress = (item: NewsroomItem) => {
    haptic.selection()
    markRead.mutate(item.id)
    if (item.url) openBrowserAsync(item.url)
  }

  return (
    <ScreenScrollContainer variant="flashlist">
      {(scrollProps) => (
        <FlashList
          data={items}
          keyExtractor={(item) => String(item.id)}
          refreshControl={
            <RefreshControl
              refreshing={isRefetching}
              onRefresh={() => {
                queryClient
                  .invalidateQueries({
                    queryKey: newsroomQueries.timeline().queryKey,
                  })
                  .then(() => haptic.light())
              }}
              progressViewOffset={scrollProps.topInset}
              {...refreshProps}
            />
          }
          ItemSeparatorComponent={() => <YStack h="$2" />}
          ListHeaderComponent={<YStack h="$3" />}
          ListEmptyComponent={
            <EmptyState
              icon="inbox"
              title="No updates"
              subtitle={`You're all caught up on announcements from ${instance}.`}
            />
          }
          contentInsetAdjustmentBehavior={scrollProps.contentInsetAdjustmentBehavior}
          contentInset={scrollProps.contentInset}
          scrollIndicatorInsets={scrollProps.scrollIndicatorInsets}
          contentContainerStyle={{
            ...scrollProps.contentContainerStyle,
            paddingHorizontal: 20,
            flexGrow: 1,
          }}
          renderItem={({ item }) => (
            <Pressable
              onPress={() => handlePress(item)}
              style={({ pressed }) => ({ opacity: pressed ? 0.7 : 1 })}
              accessibilityRole="button"
              accessibilityLabel={item.title}
              accessibilityHint={
                item.url ? 'Opens announcement in browser' : 'Marks announcement as read'
              }
            >
              <Card>
                <YStack gap="$2">
                  <SubheadText emphasis="strong">{item.title}</SubheadText>
                  {item.summary ? <BodyText>{item.summary}</BodyText> : null}
                  <Separator borderColor="$borderColor" />
                  <FootnoteText tone="tertiary">{item.published_at}</FootnoteText>
                </YStack>
              </Card>
            </Pressable>
          )}
        />
      )}
    </ScreenScrollContainer>
  )
}
