import Feather from '@expo/vector-icons/Feather'
import { Image } from 'expo-image'
import { Link } from 'expo-router'
import { memo } from 'react'
import { Dimensions } from 'react-native'
import { useMMKVBoolean } from 'react-native-mmkv'
import ImageComponent from 'src/components/ImageComponent'
import type { Status } from 'src/lib/api-types'
import { ICON } from 'src/lib/icons'
import { appStorage, uiKeys } from 'src/state/storage'
import { useTheme, View } from 'tamagui'

const SCREEN_WIDTH = Dimensions.get('screen').width

type Props = {
  post: Status
  numColumns?: number
  aspectRatio?: number
  gap?: number
}

const SENSITIVE_FALLBACK_BLURHASH = 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay'

function resolveDisplayUri(media: Status['media_attachments'][number] | undefined) {
  if (!media) return null
  const preview = media.preview_url
  if (preview && !preview.endsWith('no-preview.png')) return preview
  // Federated images cached at media.url often 404 on the home server
  // (Mastodon-hosted account viewing a Pixelfed post); the upstream CDN
  // copy at remote_url remains reachable. See toImageUri / FeedPost wiring.
  if ((media.type === 'image' || media.type === 'unknown') && media.remote_url) {
    return media.remote_url
  }
  return media.url || null
}

function PostGridCellInner({ post, numColumns = 3, aspectRatio = 1.25, gap = 2 }: Props) {
  const theme = useTheme()
  const [forceSensitiveFlag] = useMMKVBoolean(uiKeys.forceSensitive, appStorage)
  const media = post?.media_attachments?.[0]
  if (!media) return null

  const width = SCREEN_WIDTH / numColumns - gap
  const height = width * aspectRatio

  const forceSensitive = forceSensitiveFlag === true
  const isSensitive = post.sensitive === true && !forceSensitive
  const isVideo = media.type === 'video' || post.pf_type === 'video'
  const isAlbum = post.pf_type === 'photo:album'

  const displayUri = resolveDisplayUri(media)
  const blurhash = media.blurhash || ''

  return (
    <Link href={`/post/${encodeURIComponent(post.id)}`} asChild>
      <View
        testID="post-grid-cell"
        flexShrink={1}
        width={width}
        height={height}
        backgroundColor="$background"
        overflow="hidden"
      >
        <Link.Trigger withAppleZoom>
          {isSensitive ? (
            <SensitiveLayer width={width} height={height} blurhash={blurhash} />
          ) : displayUri ? (
            <ImageComponent
              source={{ uri: displayUri }}
              placeholder={blurhash ? { blurhash } : undefined}
              recyclingKey={post.id}
              style={{
                width,
                height,
                backgroundColor: theme.background?.val,
              }}
              contentFit="cover"
              transition={200}
            />
          ) : (
            <View width={width} height={height} backgroundColor="$backgroundTertiary" />
          )}
        </Link.Trigger>
        {isSensitive ? (
          <Overlay kind="sensitive" />
        ) : isVideo ? (
          <Overlay kind="video" />
        ) : isAlbum ? (
          <Overlay kind="album" />
        ) : null}
      </View>
    </Link>
  )
}

function Overlay({ kind }: { kind: 'video' | 'album' | 'sensitive' }) {
  return (
    <View position="absolute" right={5} top={5} pointerEvents="none">
      {kind === 'video' ? (
        <Feather name="play" color="white" size={ICON.md} />
      ) : kind === 'album' ? (
        <Feather name="columns" color="white" size={ICON.md} />
      ) : (
        <Feather name="eye-off" color="white" size={ICON.md} />
      )}
    </View>
  )
}

function SensitiveLayer({
  width,
  height,
  blurhash,
}: {
  width: number
  height: number
  blurhash: string
}) {
  const bh = blurhash || SENSITIVE_FALLBACK_BLURHASH
  if (!blurhash) {
    return <View width={width} height={height} backgroundColor="black" />
  }
  return (
    <Image
      placeholder={{ blurhash: bh }}
      placeholderContentFit="cover"
      style={{ width, height }}
      contentFit="cover"
    />
  )
}

export const PostGridCell = memo(PostGridCellInner)
