import {useRef} from 'react'
import {type StyleProp, View, type ViewStyle} from 'react-native'
import {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
import {type AppBskyEmbedImages} from '@atproto/api'

import {atoms as a, useBreakpoints} from '#/alf'
import {type Dimensions} from '#/components/Lightbox/types'
import {PostEmbedViewContext} from '#/components/Post/Embed/types'
import {GalleryItem} from './ImageLayoutGridItem'

interface ImageLayoutGridProps {
  images: AppBskyEmbedImages.ViewImage[]
  onPress?: (
    index: number,
    containerRefs: AnimatedRef<any>[],
    fetchedDims: (Dimensions | null)[],
  ) => void
  onLongPress?: (index: number) => void
  onPressIn?: (index: number) => void
  style?: StyleProp<ViewStyle>
  viewContext?: PostEmbedViewContext
  isWithinQuote?: boolean
}

export function ImageLayoutGrid({
  style,
  isWithinQuote: isWithinQuoteProp,
  ...props
}: ImageLayoutGridProps) {
  const {gtMobile} = useBreakpoints()
  const isWithinQuote =
    isWithinQuoteProp ??
    props.viewContext === PostEmbedViewContext.FeedEmbedRecordWithMedia
  const gap = isWithinQuote ? (gtMobile ? a.gap_xs : a.gap_2xs) : a.gap_xs

  return (
    <View style={style}>
      <View style={[gap, a.rounded_md, a.overflow_hidden]}>
        <ImageLayoutGridInner
          {...props}
          gap={gap}
          isWithinQuote={isWithinQuote}
        />
      </View>
    </View>
  )
}

interface ImageLayoutGridInnerProps {
  images: AppBskyEmbedImages.ViewImage[]
  onPress?: (
    index: number,
    containerRefs: AnimatedRef<any>[],
    fetchedDims: (Dimensions | null)[],
  ) => void
  onLongPress?: (index: number) => void
  onPressIn?: (index: number) => void
  viewContext?: PostEmbedViewContext
  isWithinQuote?: boolean
  gap: {gap: number}
}

function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) {
  const gap = props.gap
  const count = props.images.length

  const containerRef1 = useAnimatedRef()
  const containerRef2 = useAnimatedRef()
  const containerRef3 = useAnimatedRef()
  const containerRef4 = useAnimatedRef()
  const thumbDimsRef = useRef<(Dimensions | null)[]>([])

  switch (count) {
    case 2: {
      const containerRefs = [containerRef1, containerRef2]
      return (
        <View style={[a.flex_1, a.flex_row, gap]}>
          <View style={[a.flex_1, a.aspect_square]}>
            <GalleryItem
              {...props}
              index={0}
              insetBorderStyle={noCorners(['topRight', 'bottomRight'])}
              containerRefs={containerRefs}
              thumbDimsRef={thumbDimsRef}
            />
          </View>
          <View style={[a.flex_1, a.aspect_square]}>
            <GalleryItem
              {...props}
              index={1}
              insetBorderStyle={noCorners(['topLeft', 'bottomLeft'])}
              containerRefs={containerRefs}
              thumbDimsRef={thumbDimsRef}
            />
          </View>
        </View>
      )
    }

    case 3: {
      const containerRefs = [containerRef1, containerRef2, containerRef3]
      return (
        <View style={[a.flex_1, a.flex_row, gap]}>
          <View style={[a.flex_1, a.aspect_square]}>
            <GalleryItem
              {...props}
              index={0}
              insetBorderStyle={noCorners(['topRight', 'bottomRight'])}
              containerRefs={containerRefs}
              thumbDimsRef={thumbDimsRef}
            />
          </View>
          <View style={[a.flex_1, a.aspect_square, gap]}>
            <View style={[a.flex_1]}>
              <GalleryItem
                {...props}
                index={1}
                insetBorderStyle={noCorners([
                  'topLeft',
                  'bottomLeft',
                  'bottomRight',
                ])}
                containerRefs={containerRefs}
                thumbDimsRef={thumbDimsRef}
              />
            </View>
            <View style={[a.flex_1]}>
              <GalleryItem
                {...props}
                index={2}
                insetBorderStyle={noCorners([
                  'topLeft',
                  'bottomLeft',
                  'topRight',
                ])}
                containerRefs={containerRefs}
                thumbDimsRef={thumbDimsRef}
              />
            </View>
          </View>
        </View>
      )
    }

    case 4: {
      const containerRefs = [
        containerRef1,
        containerRef2,
        containerRef3,
        containerRef4,
      ]
      return (
        <>
          <View style={[a.flex_row, gap]}>
            <View style={[a.flex_1, {aspectRatio: 1.5}]}>
              <GalleryItem
                {...props}
                index={0}
                insetBorderStyle={noCorners([
                  'bottomLeft',
                  'topRight',
                  'bottomRight',
                ])}
                containerRefs={containerRefs}
                thumbDimsRef={thumbDimsRef}
              />
            </View>
            <View style={[a.flex_1, {aspectRatio: 1.5}]}>
              <GalleryItem
                {...props}
                index={1}
                insetBorderStyle={noCorners([
                  'topLeft',
                  'bottomLeft',
                  'bottomRight',
                ])}
                containerRefs={containerRefs}
                thumbDimsRef={thumbDimsRef}
              />
            </View>
          </View>
          <View style={[a.flex_row, gap]}>
            <View style={[a.flex_1, {aspectRatio: 1.5}]}>
              <GalleryItem
                {...props}
                index={2}
                insetBorderStyle={noCorners([
                  'topLeft',
                  'topRight',
                  'bottomRight',
                ])}
                containerRefs={containerRefs}
                thumbDimsRef={thumbDimsRef}
              />
            </View>
            <View style={[a.flex_1, {aspectRatio: 1.5}]}>
              <GalleryItem
                {...props}
                index={3}
                insetBorderStyle={noCorners([
                  'topLeft',
                  'bottomLeft',
                  'topRight',
                ])}
                containerRefs={containerRefs}
                thumbDimsRef={thumbDimsRef}
              />
            </View>
          </View>
        </>
      )
    }

    default:
      return null
  }
}

function noCorners(
  corners: ('topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight')[],
) {
  const styles: StyleProp<ViewStyle>[] = []
  if (corners.includes('topLeft')) {
    styles.push({borderTopLeftRadius: 0})
  }
  if (corners.includes('topRight')) {
    styles.push({borderTopRightRadius: 0})
  }
  if (corners.includes('bottomLeft')) {
    styles.push({borderBottomLeftRadius: 0})
  }
  if (corners.includes('bottomRight')) {
    styles.push({borderBottomRightRadius: 0})
  }
  return styles
}
