import React, {memo, useCallback} from 'react'
import {
  StyleProp,
  StyleSheet,
  TouchableOpacity,
  View,
  ViewStyle,
} from 'react-native'
import {
  AppBskyFeedDefs,
  AppBskyFeedPost,
  RichText as RichTextAPI,
} from '@atproto/api'
import {Text} from '../text/Text'
import {PostDropdownBtn} from '../forms/PostDropdownBtn'
import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons'
import {s} from 'lib/styles'
import {pluralize} from 'lib/strings/helpers'
import {useTheme} from 'lib/ThemeContext'
import {RepostButton} from './RepostButton'
import {Haptics} from 'lib/haptics'
import {HITSLOP_10, HITSLOP_20} from 'lib/constants'
import {useModalControls} from '#/state/modals'
import {
  usePostLikeMutation,
  usePostUnlikeMutation,
  usePostRepostMutation,
  usePostUnrepostMutation,
} from '#/state/queries/post'
import {useComposerControls} from '#/state/shell/composer'
import {Shadow} from '#/state/cache/types'
import {useRequireAuth} from '#/state/session'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'

let PostCtrls = ({
  big,
  post,
  record,
  richText,
  showAppealLabelItem,
  style,
  onPressReply,
}: {
  big?: boolean
  post: Shadow<AppBskyFeedDefs.PostView>
  record: AppBskyFeedPost.Record
  richText: RichTextAPI
  showAppealLabelItem?: boolean
  style?: StyleProp<ViewStyle>
  onPressReply: () => void
}): React.ReactNode => {
  const theme = useTheme()
  const {_} = useLingui()
  const {openComposer} = useComposerControls()
  const {closeModal} = useModalControls()
  const postLikeMutation = usePostLikeMutation()
  const postUnlikeMutation = usePostUnlikeMutation()
  const postRepostMutation = usePostRepostMutation()
  const postUnrepostMutation = usePostUnrepostMutation()
  const requireAuth = useRequireAuth()

  const defaultCtrlColor = React.useMemo(
    () => ({
      color: theme.palette.default.postCtrl,
    }),
    [theme],
  ) as StyleProp<ViewStyle>

  const onPressToggleLike = React.useCallback(async () => {
    if (!post.viewer?.like) {
      Haptics.default()
      postLikeMutation.mutate({
        uri: post.uri,
        cid: post.cid,
      })
    } else {
      postUnlikeMutation.mutate({
        postUri: post.uri,
        likeUri: post.viewer.like,
      })
    }
  }, [
    post.viewer?.like,
    post.uri,
    post.cid,
    postLikeMutation,
    postUnlikeMutation,
  ])

  const onRepost = useCallback(() => {
    closeModal()
    if (!post.viewer?.repost) {
      Haptics.default()
      postRepostMutation.mutate({
        uri: post.uri,
        cid: post.cid,
      })
    } else {
      postUnrepostMutation.mutate({
        postUri: post.uri,
        repostUri: post.viewer.repost,
      })
    }
  }, [
    post.uri,
    post.cid,
    post.viewer?.repost,
    closeModal,
    postRepostMutation,
    postUnrepostMutation,
  ])

  const onQuote = useCallback(() => {
    closeModal()
    openComposer({
      quote: {
        uri: post.uri,
        cid: post.cid,
        text: record.text,
        author: post.author,
        indexedAt: post.indexedAt,
      },
    })
    Haptics.default()
  }, [
    post.uri,
    post.cid,
    post.author,
    post.indexedAt,
    record.text,
    openComposer,
    closeModal,
  ])

  return (
    <View style={[styles.ctrls, style]}>
      <TouchableOpacity
        testID="replyBtn"
        style={[
          styles.ctrl,
          !big && styles.ctrlPad,
          {paddingLeft: 0},
          post.viewer?.replyDisabled ? {opacity: 0.5} : undefined,
        ]}
        onPress={() => {
          if (!post.viewer?.replyDisabled) {
            requireAuth(() => onPressReply())
          }
        }}
        accessibilityRole="button"
        accessibilityLabel={`Reply (${post.replyCount} ${
          post.replyCount === 1 ? 'reply' : 'replies'
        })`}
        accessibilityHint=""
        hitSlop={big ? HITSLOP_20 : HITSLOP_10}>
        <CommentBottomArrow
          style={[defaultCtrlColor, big ? s.mt2 : styles.mt1]}
          strokeWidth={3}
          size={big ? 20 : 15}
        />
        {typeof post.replyCount !== 'undefined' && post.replyCount > 0 ? (
          <Text style={[defaultCtrlColor, s.ml5, s.f15]}>
            {post.replyCount}
          </Text>
        ) : undefined}
      </TouchableOpacity>
      <View style={[styles.ctrl, !big && styles.ctrlPad]}>
        <RepostButton
          big={big}
          isReposted={!!post.viewer?.repost}
          repostCount={post.repostCount}
          onRepost={onRepost}
          onQuote={onQuote}
        />
      </View>
      <TouchableOpacity
        testID="likeBtn"
        style={[styles.ctrl, !big && styles.ctrlPad]}
        onPress={() => {
          requireAuth(() => onPressToggleLike())
        }}
        accessibilityRole="button"
        accessibilityLabel={`${
          post.viewer?.like ? _(msg`Unlike`) : _(msg`Like`)
        } (${post.likeCount} ${pluralize(post.likeCount || 0, 'like')})`}
        accessibilityHint=""
        hitSlop={big ? HITSLOP_20 : HITSLOP_10}>
        {post.viewer?.like ? (
          <HeartIconSolid style={s.likeColor} size={big ? 22 : 16} />
        ) : (
          <HeartIcon
            style={[defaultCtrlColor, big ? styles.mt1 : undefined]}
            strokeWidth={3}
            size={big ? 20 : 16}
          />
        )}
        {typeof post.likeCount !== 'undefined' && post.likeCount > 0 ? (
          <Text
            testID="likeCount"
            style={
              post.viewer?.like
                ? [s.bold, s.likeColor, s.f15, s.ml5]
                : [defaultCtrlColor, s.f15, s.ml5]
            }>
            {post.likeCount}
          </Text>
        ) : undefined}
      </TouchableOpacity>
      {big ? undefined : (
        <PostDropdownBtn
          testID="postDropdownBtn"
          postAuthor={post.author}
          postCid={post.cid}
          postUri={post.uri}
          record={record}
          richText={richText}
          showAppealLabelItem={showAppealLabelItem}
          style={styles.ctrlPad}
        />
      )}
      {/* used for adding pad to the right side */}
      <View />
    </View>
  )
}
PostCtrls = memo(PostCtrls)
export {PostCtrls}

const styles = StyleSheet.create({
  ctrls: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  ctrl: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
  },
  ctrlPad: {
    paddingTop: 5,
    paddingBottom: 5,
    paddingLeft: 5,
    paddingRight: 5,
  },
  mt1: {
    marginTop: 1,
  },
})
