import {useCallback, useState} from 'react'
import {Keyboard, Pressable, View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'

import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {
  useCameraPermission,
  usePhotoLibraryPermission,
  useVideoLibraryPermission,
} from '#/lib/hooks/usePermissions'
import {openCamera, openUnifiedPicker} from '#/lib/media/picker'
import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile'
import {MAX_GALLERY_IMAGES} from '#/view/com/composer/state/composer'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, native, useTheme, web} from '#/alf'
import {Button} from '#/components/Button'
import {useSheetWrapper} from '#/components/Dialog/sheet-wrapper'
import {Camera_Stroke2_Corner0_Rounded as CameraIcon} from '#/components/icons/Camera'
import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image'
import {SubtleHover} from '#/components/SubtleHover'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_NATIVE} from '#/env'

export function ComposerPrompt() {
  const t = useTheme()
  const ax = useAnalytics()
  const {_} = useLingui()
  const {openComposer} = useOpenComposer()
  const profile = useCurrentAccountProfile()
  const [hover, setHover] = useState(false)
  const {requestCameraAccessIfNeeded} = useCameraPermission()
  const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission()
  const {requestVideoAccessIfNeeded} = useVideoLibraryPermission()
  const sheetWrapper = useSheetWrapper()

  const onPress = useCallback(() => {
    ax.metric('composerPrompt:press', {})
    openComposer({logContext: 'Fab'})
  }, [ax, openComposer])

  const onPressImage = useCallback(async () => {
    ax.metric('composerPrompt:gallery:press', {})

    // On web, open the composer with the gallery picker auto-opening
    if (!IS_NATIVE) {
      openComposer({openGallery: true, logContext: 'Fab'})
      return
    }

    try {
      const [photoAccess, videoAccess] = await Promise.all([
        requestPhotoAccessIfNeeded(),
        requestVideoAccessIfNeeded(),
      ])

      if (!photoAccess && !videoAccess) {
        return
      }

      if (Keyboard.isVisible()) {
        Keyboard.dismiss()
      }

      const selectionCountRemaining = MAX_GALLERY_IMAGES
      const {assets, canceled} = await sheetWrapper(
        openUnifiedPicker({selectionCountRemaining}),
      )

      if (canceled) {
        return
      }

      if (assets.length > 0) {
        const imageUris = assets
          .filter(asset => asset.mimeType?.startsWith('image/'))
          .slice(0, MAX_GALLERY_IMAGES)
          .map(asset => ({
            uri: asset.uri,
            width: asset.width,
            height: asset.height,
          }))

        if (imageUris.length > 0) {
          openComposer({imageUris, logContext: 'Fab'})
        }
      }
    } catch (err: any) {
      if (!String(err).toLowerCase().includes('cancel')) {
        ax.logger.error('Error opening image picker', {error: err})
      }
    }
  }, [
    ax,
    openComposer,
    requestPhotoAccessIfNeeded,
    requestVideoAccessIfNeeded,
    sheetWrapper,
  ])

  const onPressCamera = useCallback(async () => {
    ax.metric('composerPrompt:camera:press', {})

    try {
      if (!(await requestCameraAccessIfNeeded())) {
        return
      }

      if (IS_NATIVE && Keyboard.isVisible()) {
        Keyboard.dismiss()
      }

      const image = await openCamera({
        mediaTypes: 'images',
      })

      const imageUris = [
        {
          uri: image.path,
          width: image.width,
          height: image.height,
        },
      ]

      openComposer({
        imageUris: IS_NATIVE ? imageUris : undefined,
        logContext: 'Fab',
      })
    } catch (err: any) {
      if (!String(err).toLowerCase().includes('cancel')) {
        ax.logger.error('Error opening camera', {error: err})
      }
    }
  }, [ax, openComposer, requestCameraAccessIfNeeded])

  if (!profile) {
    return null
  }

  return (
    <Pressable
      onPress={onPress}
      android_ripple={null}
      accessibilityRole="button"
      accessibilityLabel={_(msg`Compose new post`)}
      accessibilityHint={_(msg`Opens the post composer`)}
      onPointerEnter={() => setHover(true)}
      onPointerLeave={() => setHover(false)}
      style={({pressed}) => [
        a.relative,
        a.flex_row,
        a.align_start,
        {
          paddingLeft: 18,
          paddingRight: 15,
        },
        a.py_md,
        native({
          paddingTop: 10,
          paddingBottom: 10,
        }),
        web({
          cursor: 'pointer',
          outline: 'none',
        }),
        pressed && web({outline: 'none'}),
      ]}>
      <SubtleHover hover={hover} />
      <UserAvatar
        avatar={profile.avatar}
        size={42}
        type={profile.associated?.labeler ? 'labeler' : 'user'}
      />
      <View
        style={[
          a.flex_1,
          a.ml_md,
          a.flex_row,
          a.align_center,
          a.justify_between,
          {
            height: 40,
          },
        ]}>
        <Text
          style={[
            t.atoms.text_contrast_medium,
            a.text_md,
            {includeFontPadding: false},
          ]}>
          <Trans>Anything but skeet</Trans>
        </Text>
        <View style={[a.flex_row, a.gap_md]}>
          {IS_NATIVE && (
            <Button
              onPress={e => {
                e.stopPropagation()
                onPressCamera()
              }}
              label={_(msg`Open camera`)}
              accessibilityHint={_(msg`Opens device camera`)}
              variant="ghost"
              shape="round">
              {({hovered, pressed, focused}) => (
                <CameraIcon
                  size="lg"
                  style={{
                    color:
                      hovered || pressed || focused
                        ? t.palette.primary_500
                        : t.palette.contrast_300,
                  }}
                />
              )}
            </Button>
          )}
          <Button
            onPress={e => {
              e.stopPropagation()
              onPressImage()
            }}
            label={_(msg`Add image`)}
            accessibilityHint={_(msg`Opens image picker`)}
            variant="ghost"
            shape="round">
            {({hovered, pressed, focused}) => (
              <ImageIcon
                size="lg"
                style={{
                  color:
                    hovered || pressed || focused
                      ? t.palette.primary_500
                      : t.palette.contrast_300,
                }}
              />
            )}
          </Button>
        </View>
      </View>
    </Pressable>
  )
}
