import {
  UserType,
  FileType,
  LinkType,
  PollType,
  RoomType,
  StickerType,
  MessageType,
  ChannelType,
  RoomKindEnum,
  AttachmentType,
  LinkPreviewType,
  MessagePackType,
  MessageKindEnum,
  AttachmentKindEnum,
  MessageMetadataType,
} from "@openchat/types"
import {
  useMembersBy,
  useAccountId,
  useChannelsBy,
  useRoomMetadata,
  useUserProfiles,
  useCurrentRoomUISettings,
  CurrentRoomUISettingsModel,
  useMessagePack,
} from "@openchat/ui"
import {
  View,
  Image,
  Keyboard,
  TextInput,
  Pressable,
  TouchableOpacity,
  useWindowDimensions,
  NativeSyntheticEvent,
  TextInputKeyPressEventData,
} from "react-native"
import Animated, {
  Easing,
  withTiming,
  ReduceMotion,
  useSharedValue,
  useAnimatedStyle,
} from "react-native-reanimated"
import { SvgXml } from "react-native-svg"
import { useStyles } from "./message-input.style"
import TrackPlayer from "react-native-track-player"
import { AppColors } from "../../../app/app.colors"
import { UserProfileUtils } from "@openchat/models"
import React, { useEffect, useRef, useState } from "react"
import { launchImageLibrary } from "react-native-image-picker"
import { Icon } from "../../../ui-components/icon/icon.component"
import { useModal } from "../../../ui-components/modal/modal.hook"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { AppController, AppStore } from "../../../app/app.globals"
import { EmojiBox } from "../../emoji/emoji-box/emoji-box.component"
import { CryptoUtils, DateUtils, RandomUtils } from "@openchat/core"
import { SVGIcons } from "../../../ui-components/svg-icons/svg-icons"
import { ViewIf } from "../../../ui-components/view-if/view-if.component"
import { Tooltip } from "../../../ui-components/tooltip/tooltip.provider"
import { StyledText } from "../../../ui-components/styled-text/styled-text"
import { MessageTextAreaUtils } from "../message-textarea/message-textarea.utils"
import { EmotionCategoryType } from "../../emoji/emoji-type/emotion-category.types"
import { MessageInputQuote } from "../message-input-quote/message-input-quote.component"
import { MessageInputPopup } from "../message-input-popup/message-input-popup.component"
import { MessageInputAudio } from "../message-input-audio/message-input-audio.component"
import { MessageInputMention } from "../message-input-mention/message-input-mention.component"
import { MessageInputEditable } from "../message-input-editable/message-input-editable.component"
import { MessageInputDecorator } from "../message-input-decorator/message-input-decorator.component"
import { MessageInputPreviewContainer } from "../message-input-preview-container/message-input-preview-container.component"

export function MessageInput({
  room,
  scrollToMessage,
  newMessagePacks,
  updateMessagePacks,
}: {
  room: RoomType
  scrollToMessage: (messageId: string) => void
  newMessagePacks: (messagePack: MessagePackType) => void
  updateMessagePacks: (messagePack: MessagePackType) => void
}) {
  // ---------------------------------------------------------------------------
  // variables
  // ---------------------------------------------------------------------------

  const styles = useStyles()
  const modal = useModal()
  const accountId = useAccountId()
  const insets = useSafeAreaInsets()
  const dimensions = useWindowDimensions()
  const currentRoomUISettings = useCurrentRoomUISettings(room.id)
  const quoteMessage = currentRoomUISettings.quotedMessage
  const editMessage = currentRoomUISettings.editMessage
  const screenHeight = dimensions.height

  const { channel, communityId } = useRoomMetadata(room.id)

  const members = useMembersBy({ communityId: communityId })
  const userProfiles = useUserProfiles({
    in: members.map((member) => member.identityId),
  })
  const channels = useChannelsBy({ communityId: communityId })
  const [filteredUsers, setFilteredUsers] = useState<UserType[]>([])
  const [filteredChannels, setFilteredChannels] = useState<ChannelType[]>([])
  const [newInputHeight, setNewInputHeight] = useState(0)
  const [isShowEmojiBox, setIsShowEmojiBox] = useState(false)
  const [maxShowEmoji, setMaxShowEmoji] = useState(false)
  const [expanded, setExpanded] = useState(false)
  const [attachmentKind, setAttachmentKind] = useState<AttachmentKindEnum>()
  const [textMessage, setTextMessage] = useState<string>("")
  const [editTextMessage, setEditTextMessage] = useState<string>("")

  const [editMessageInput, setEditMessageInput] = useState<MessageType | null>()
  const [files, setFiles] = useState<FileType[]>([])
  const [messageLinks, setMessageLinks] = useState<LinkPreviewType[]>([])
  const [linkIgnoreList, setLinkIgnoreList] = useState([""])
  const [emotionCategory, setEmotionCategory] =
    useState<EmotionCategoryType>("emoji")
  const [currentType, setCurrentType] = useState<
    "emoji" | "keyboard" | "sticker" | "gif"
  >("keyboard")
  const [deviceState, setDeviceState] = useState({
    camera: false,
    microphone: false,
  })
  const [deviceActiveState, setDeviceActiveState] = useState({
    cameraActive: false,
    microphoneActive: false,
  })
  const [selection, setSelection] = useState({
    start: 0,
    end: 0,
  })
  const [showTools, setShowTools] = useState(false)
  const [selectedToolbarIcon, setSelectedToolbarIcon] = useState<
    "bold" | "italic" | "strikethrough" | "code" | "bulletList" | "orderedList"
  >("bold")
  const [toggleMarkdownList, setToggleMarkdownList] = useState("")
  const [slowModeTime, setSlowModeTime] = useState(0)

  const inputRef = useRef<TextInput | null>(null)
  const inputWrapperRef = useRef<View>(null)
  const slowModeInterval = useRef<NodeJS.Timeout>()

  // ---------------------------------------------------------------------------
  // animations
  // ---------------------------------------------------------------------------

  const inputHeight = useSharedValue(newInputHeight)

  const animatedInputStyles = useAnimatedStyle(() => ({
    height: maxShowEmoji ? inputHeight.value : "auto",
  }))
  const animatedEmojiStyles = useAnimatedStyle(() =>
    maxShowEmoji
      ? { height: "auto" }
      : isShowEmojiBox
        ? {
            height: 320,
          }
        : {},
  )

  // ---------------------------------------------------------------------------
  // effects
  // ---------------------------------------------------------------------------

  useEffect(() => {
    if (channel && channel.slowMode) {
      const lastMessageSendTime = room.lastMessageSendTime
      const slowMode = channel ? channel.slowMode : 0

      slowModeInterval.current = setInterval(() => {
        const timeLeft =
          slowMode - Math.floor((Date.now() - lastMessageSendTime) / 1000)

        if (timeLeft < 0) {
          clearInterval(slowModeInterval.current)
          setSlowModeTime(timeLeft)
        } else {
          setSlowModeTime(timeLeft)
        }
      }, 1000)
    }
    return () => {
      clearInterval(slowModeInterval.current)
    }
  }, [room.lastMessageSendTime])

  useEffect(() => {
    loadDraft()
  }, [room.id])

  useEffect(() => {
    setEditMessageInput(editMessage)

    if (editMessage) setEditTextMessage(editMessage.text)
  }, [editMessage])

  useEffect(() => {
    if (!files.length) return

    onMessageTyping(textMessage)
  }, [files.length])

  // ---------------------------------------------------------------------------
  // functions
  // ---------------------------------------------------------------------------

  function goDown() {
    inputHeight.value = withTiming(newInputHeight, {
      duration: 0,
      easing: Easing.inOut(Easing.quad),
      reduceMotion: ReduceMotion.System,
    })

    setMaxShowEmoji(false)
    setExpanded(false)
  }

  function goUp() {
    if (!inputWrapperRef.current) return

    inputWrapperRef.current.measure((x, y, width, height, pageX, pageY) => {
      setNewInputHeight(height)
    })

    setTimeout(() => setMaxShowEmoji(true), 0)

    inputHeight.value = withTiming(
      screenHeight - insets.top - insets.bottom - 20,
      {
        duration: 0,
        easing: Easing.inOut(Easing.quad),
        reduceMotion: ReduceMotion.System,
      },
    )

    setExpanded(true)
  }

  async function sendMessage(
    kind: MessageKindEnum,
    messageText: string,
    mediaFile: FileType[],
    sticker?: { sticker: StickerType; stickerPackId: string },
    user?: {
      id: string
      name: string
      photo: FileType | null
    },
  ) {
    if (!accountId || !currentRoomUISettings) return

    if (channel && channel.slowMode) {
      if (Date.now() - room.lastMessageSendTime > channel.slowMode * 1000) {
        await AppController.room.update({
          id: room.id,
          lastMessageSendTime: Date.now(),
        })
      } else {
        return
      }
    }

    let attachments: AttachmentType[] = []

    for (let file of mediaFile) {
      if (!attachmentKind) return
      const attachment: AttachmentType = {
        id: RandomUtils.uuid(),
        createdAt: Date.now(),
        kind: attachmentKind,
        name: file.name,
        size: file.size,
        roomId: room.id,
        messageId: null,
        senderId: accountId,
        mimeType:
          kind === MessageKindEnum.audio
            ? "audio-record"
            : kind === MessageKindEnum.video
              ? "video-record"
              : file.mimeType.startsWith("application")
                ? file.mimeType.split("/")[1]
                : file.mimeType.split("/")[0],
        preview: file.data,
        fileId: file.id,
      }

      attachments.push(attachment)
    }

    let links: LinkType[] = []
    for (let messageLink of messageLinks) {
      const link: LinkType = {
        id: RandomUtils.uuid(),
        createdAt: Date.now(),
        roomId: room.id,
        ...messageLink,
      }

      links.push(link)
    }

    const metadata: MessageMetadataType = {
      id: RandomUtils.uuid(),
      replyCount: 0,
    }

    const message: MessageType = {
      id: RandomUtils.uuid(),
      createdAt: Date.now(),
      text: messageText,
      roomId: room.id,
      isEdited: false,
      isDeleted: false,
      isDelivered: false,
      senderId: accountId,
      reactions: [],
      forward: null,
      regular: {
        kind: kind,
        quote: quoteMessage ? quoteMessage : null,
        sharedUser: user ? user : null,
        sticker: sticker ? sticker : null,
      },
      question: null,
      answer:
        room.kind === RoomKindEnum.QUESTION_ANSWERS
          ? {
              negativeVotes: [],
              positiveVotes: [],
            }
          : null,
      news: null,
      issue: null,
      board: null,
    }

    newMessagePacks({
      message,
      metadata,
      links,
      attachments,
      files: [],
      poll: undefined,
    })

    await AppController.message.insert([
      {
        links,
        message,
        metadata,
        attachments,
        files: mediaFile,
        poll: undefined,
      },
    ])

    AppStore.for(CurrentRoomUISettingsModel).set([
      {
        ...currentRoomUISettings,
        quotedMessage: undefined,
      },
    ])
    MessageTextAreaUtils.setDraft(room.id, null, room.draftMessage)

    setTextMessage("")

    await TrackPlayer.add({
      id: "send",
      url: require("../../../../public/sounds/message_send.wav"),
      title: "Track Title",
      artist: "Track Artist",
    })

    // Start playing it
    await TrackPlayer.play()
    removeAttachedData()
  }

  async function onMessageUpdate(
    editedMessage: MessageType,
    value: string,
    attachments: AttachmentType[],
    files: FileType[],
    poll?: PollType,
  ) {
    let links: LinkType[] = []
    for (let messageLink of messageLinks) {
      const link: LinkType = {
        id: RandomUtils.uuid(),
        createdAt: Date.now(),
        roomId: room.id,
        ...messageLink,
      }

      links.push(link)
    }
    const metadata: MessageMetadataType = {
      id: RandomUtils.uuid(),
      replyCount: 0,
    }

    updateMessagePacks({
      message: {
        ...editedMessage,
        text: value,
        isEdited: true,
      },
      files,
      attachments,
      links,
      metadata,
      poll: undefined,
    })

    await AppController.message.update({
      roomId: editedMessage.roomId,
      messageId: editedMessage.id,
      message: {
        ...editedMessage,
        text: value,
        isEdited: true,
      },
      files,
      attachments,
      links,
    })

    AppStore.for(CurrentRoomUISettingsModel).update([
      {
        ...currentRoomUISettings,
        editMessage: undefined,
      },
    ])
    setEditTextMessage("")
    removeAttachedData()
  }

  function removeAttachedData() {
    setEditMessageInput(undefined)
    setFiles([])
    setMessageLinks([])
  }

  async function shareProfile(
    users: {
      id: string
      name: string
      photo: FileType | null
    }[],
  ) {
    for (let user of users) {
      sendMessage(MessageKindEnum.sharedUser, "", [], undefined, user)
    }
  }

  function onKeyPress(e: NativeSyntheticEvent<TextInputKeyPressEventData>) {
    if (e.nativeEvent.key === "Enter") {
      if (
        selectedToolbarIcon === "bulletList" ||
        selectedToolbarIcon === "orderedList"
      ) {
        setToggleMarkdownList(selectedToolbarIcon)
      }
    }
  }

  async function loadDraft() {
    if (!room.draftMessage) return
    setTextMessage(room.draftMessage.text)
    setFiles(room.draftMessage.files)
  }

  async function onMessageTyping(value: string) {
    const afterAt = /\s@([^@]*)$/
    const afterHash = /\s#([^#]*)$/

    const resultAfterAt = value.match(afterAt)
    const resultAfterHash = value.match(afterHash)

    if (
      resultAfterAt &&
      (!resultAfterHash || resultAfterHash[1].length > resultAfterAt[1].length)
    ) {
      const textAfterAt = resultAfterAt[1]

      const users = members.map((member) => {
        return UserProfileUtils.unify(
          UserProfileUtils.toPartialFromMember(member),
          userProfiles.find(
            (userProfile) => userProfile.id === member.identityId,
          ),
        )
      })

      setFilteredUsers(users.filter((user) => user.name.includes(textAfterAt)))
    } else {
      if (resultAfterHash) {
        const textAfterHash = resultAfterHash[1]

        setFilteredChannels(
          channels.filter((channel) => channel.name.includes(textAfterHash)),
        )
      } else {
        setFilteredUsers([])
        setFilteredChannels([])
      }
    }

    setTextMessage(value)
    if (value.trim() !== "" || files.length !== 0) {
      MessageTextAreaUtils.setDraft(
        room.id,
        {
          text: value,
          files,
        },
        room.draftMessage,
      )
    } else {
      MessageTextAreaUtils.setDraft(room.id, null, room.draftMessage)
    }
    MessageTextAreaUtils.extractMessageLinks({
      text: value,
      ignoreList: linkIgnoreList,
      onLinkExist: (links) => {
        setMessageLinks(links)
      },
      onLinkIgnore: (links) => {
        setLinkIgnoreList(links)
      },
    })
    await AppController.message.typing(room.id)
  }

  async function onGallerySelect() {
    const files = await launchImageLibrary({
      mediaType: "mixed",
      includeBase64: true,
      includeExtra: true,
      selectionLimit: 50,
      maxHeight: 110,
    })

    if (!files.assets) return

    for (let selectedFile of files.assets) {
      if (!selectedFile.uri) return

      const file = await fetch(selectedFile.uri).then((response) => {
        return response.blob()
      })

      const reader = new FileReader()

      reader.onload = () => {
        const dataUrl = reader.result as string

        setFiles([
          {
            id: CryptoUtils.sha256(dataUrl),
            name: selectedFile.fileName ? selectedFile.fileName : "",
            size: file.size,
            mimeType: file.type,
            data: dataUrl,
            duration: null,
          },
        ])
      }
      reader.readAsDataURL(file)
    }
  }

  function openMessageInputPopup() {
    modal.open({
      component: (
        <MessageInputPopup
          roomId={room.id}
          newMessagePacks={newMessagePacks}
          isShowFileAndProfile={true}
          onProfileSelect={shareProfile}
          onFilesSelected={(files, kind) => {
            setAttachmentKind(kind)
            setFiles((prev) => [...prev, ...files])
          }}
        />
      ),

      height: 180,
    })
  }

  // ---------------------------------------------------------------------------
  return (
    <>
      {maxShowEmoji && <View style={styles.maxShowInputAnimatedStyle} />}

      <Animated.View
        ref={inputWrapperRef}
        style={[
          animatedInputStyles,
          styles.inputContainer,
          {
            position: maxShowEmoji ? "absolute" : "relative",
          },
          deviceActiveState.cameraActive
            ? { height: screenHeight - insets.bottom }
            : {},
        ]}
      >
        {/* --------------------------------------------------------------------------- */}
        {/* MENTION */}
        {/* --------------------------------------------------------------------------- */}

        {(filteredUsers.length > 0 || filteredChannels.length > 0) && (
          <MessageInputMention
            filteredChannels={filteredChannels}
            filteredUsers={filteredUsers}
            mentionPress={(type: string, name: string) => {
              const afterAt = /@([^@]*)$/
              const afterHash = /#([^#]*)$/

              const resultAfterAt = textMessage.match(afterAt)
              const resultAfterHash = textMessage.match(afterHash)

              let textAfterMention = ""

              if (resultAfterAt && type === "member") {
                textAfterMention = resultAfterAt[1]
              }
              if (resultAfterHash && type === "channel") {
                textAfterMention = resultAfterHash[1]
              }

              onMessageTyping(
                textMessage.slice(
                  0,
                  textMessage.length - textAfterMention.length,
                ) +
                  name +
                  " ",
              )
            }}
          />
        )}

        <MessageInputPreviewContainer
          files={files}
          setFiles={(files) => setFiles(files)}
          links={messageLinks}
          onRemove={() => {
            removeAttachedData(), setTextMessage(""), setEditTextMessage("")
          }}
        />

        {quoteMessage && (
          <Pressable onPress={() => scrollToMessage(quoteMessage.id)}>
            <MessageInputQuote
              room={room}
              messageQuote={quoteMessage}
              onRemoveQuotePress={() => {
                AppStore.for(CurrentRoomUISettingsModel).set([
                  {
                    ...currentRoomUISettings,
                    quotedMessage: undefined,
                  },
                ])
              }}
            />
          </Pressable>
        )}

        {editMessageInput && (
          <Pressable onPress={() => scrollToMessage(editMessageInput.id)}>
            <MessageInputEditable
              message={editMessageInput}
              room={room}
              onRemoveMessageEditPress={() => {
                AppStore.for(CurrentRoomUISettingsModel).update([
                  {
                    ...currentRoomUISettings,
                    editMessage: undefined,
                  },
                ])
                removeAttachedData()
                setEditTextMessage("")
              }}
            />
          </Pressable>
        )}

        <View
          style={[
            styles.messageInput,
            quoteMessage
              ? {
                  borderTopRightRadius: 0,
                  borderTopLeftRadius: 0,
                  borderTopWidth: 0,
                }
              : {},
            maxShowEmoji
              ? { borderTopLeftRadius: 10, borderTopRightRadius: 10 }
              : {},
            {
              paddingLeft: insets.left,
              paddingRight: insets.right,
            },
          ]}
        >
          <View style={[styles.iconsInput]}>
            {/* --------------------------------------------------------------------------- */}
            {/* MESSAGE INPUT */}
            {/* --------------------------------------------------------------------------- */}

            <ViewIf
              if={
                !deviceActiveState.microphoneActive &&
                !deviceActiveState.cameraActive
              }
            >
              <View style={styles.msgInputWrap}>
                {/* --------------------------------------------------------------------------- */}
                {/* LEFT ICONS OF INPUT */}
                {/* --------------------------------------------------------------------------- */}

                {!editMessageInput ? (
                  <TouchableOpacity
                    style={styles.leftIconWrapper}
                    onPress={openMessageInputPopup}
                  >
                    <Icon name="fal fa-plus" size={18} bald />
                  </TouchableOpacity>
                ) : (
                  <TouchableOpacity
                    style={styles.leftIconWrapper}
                    onPress={onGallerySelect}
                  >
                    <Icon name="fal fa-icons" size={18} bald />
                  </TouchableOpacity>
                )}

                <View
                  style={[
                    showTools || (currentType === "emoji" && !showTools)
                      ? styles.inputWrapperWithDecorator
                      : styles.inputWrapper,
                  ]}
                >
                  <TextInput
                    ref={inputRef}
                    value={editMessage ? editTextMessage : textMessage}
                    onChangeText={(text) => {
                      editMessageInput
                        ? setEditTextMessage(text)
                        : onMessageTyping(text)
                    }}
                    placeholder="Write a message..."
                    onSelectionChange={(syntheticEvent) => {
                      const { nativeEvent } = syntheticEvent
                      const { selection } = nativeEvent
                      setSelection(selection)
                    }}
                    onBlur={() => {
                      if (!textMessage && !isShowEmojiBox)
                        setCurrentType("keyboard")
                      else setCurrentType(emotionCategory)
                    }}
                    onPressIn={() => {}}
                    onFocus={() => {
                      goDown()
                      setCurrentType(emotionCategory)
                      setIsShowEmojiBox(false)
                    }}
                    placeholderTextColor={AppColors.placeholderText}
                    onKeyPress={onKeyPress}
                    textAlignVertical="top"
                    multiline
                    style={[
                      styles.inputMsg,
                      showTools || (currentType === "emoji" && !showTools)
                        ? {}
                        : { flex: 1 },
                    ]}
                  />

                  {/* --------------------------------------------------------------------------- */}
                  {/* KEYWORD ICON */}
                  {/* --------------------------------------------------------------------------- */}

                  {currentType === "keyboard" && (
                    <TouchableOpacity
                      onPress={() => {
                        setCurrentType(emotionCategory)
                        setIsShowEmojiBox(false)
                      }}
                    >
                      <Icon name="fal fa-note-sticky" height={18} width={16} />
                    </TouchableOpacity>
                  )}

                  {currentType === "emoji" && !showTools && (
                    <View style={styles.keywordIconWrap}>
                      <TouchableOpacity
                        style={styles.keywordIconAaWrap}
                        onPress={() => setShowTools(true)}
                      >
                        <StyledText style={styles.keywordIconAa}>Aa</StyledText>
                      </TouchableOpacity>

                      <TouchableOpacity
                        onPress={() => {
                          setIsShowEmojiBox(true)
                          Keyboard.dismiss()
                        }}
                      >
                        <Icon
                          bald={true}
                          name="fal fa-face-smile"
                          height={16}
                          width={16}
                        />
                      </TouchableOpacity>

                      <TouchableOpacity>
                        <Icon
                          bald={true}
                          name="far fa-at"
                          height={18}
                          width={17}
                        />
                      </TouchableOpacity>
                    </View>
                  )}

                  {/* --------------------------------------------------------------------------- */}
                  {/* INPUT DECORATOR */}
                  {/* --------------------------------------------------------------------------- */}

                  {showTools && (
                    <MessageInputDecorator
                      value={editMessage ? editTextMessage : textMessage}
                      onChange={(value) => {
                        editMessage
                          ? setEditTextMessage(value)
                          : setTextMessage(value)
                      }}
                      selection={selection}
                      setSelection={(start, end) =>
                        setSelection({
                          start,
                          end,
                        })
                      }
                      onClose={() => setShowTools(false)}
                      onMarkdownType={(value) => setSelectedToolbarIcon(value)}
                      toggleMarkdownList={toggleMarkdownList}
                    />
                  )}

                  {/* --------------------------------------------------------------------------- */}
                  {/* STICKER ICON */}
                  {/* --------------------------------------------------------------------------- */}

                  {currentType !== "emoji" &&
                    currentType !== "keyboard" &&
                    currentType === "sticker" && (
                      <TouchableOpacity
                        onPress={() => {
                          Keyboard.dismiss()
                          setCurrentType("keyboard")
                          setIsShowEmojiBox(true)
                          setEmotionCategory("sticker")
                        }}
                      >
                        <SvgXml
                          xml={SVGIcons.regularStickerIcon(
                            AppColors.iconDefault,
                          )}
                          width={20}
                          height={18}
                        />
                      </TouchableOpacity>
                    )}

                  {/* --------------------------------------------------------------------------- */}
                  {/* GIF ICON */}
                  {/* --------------------------------------------------------------------------- */}

                  {currentType !== "emoji" &&
                    currentType !== "keyboard" &&
                    currentType !== "sticker" &&
                    currentType === "gif" && (
                      <TouchableOpacity
                        onPress={() => {
                          Keyboard.dismiss()
                          setCurrentType("keyboard")
                          setIsShowEmojiBox(true)
                          setEmotionCategory("gif")
                        }}
                      >
                        <Image
                          source={require("../../../../assets/gif.png")}
                          alt="gif"
                          style={styles.gifIcon}
                        />
                      </TouchableOpacity>
                    )}
                </View>
              </View>
            </ViewIf>

            {/* --------------------------------------------------------------------------- */}
            {/* AUDIO RECORDING  */}
            {/* --------------------------------------------------------------------------- */}

            <ViewIf if={deviceActiveState.microphoneActive}>
              <MessageInputAudio
                setIsRecording={() => {
                  setDeviceActiveState({
                    ...deviceActiveState,
                    microphoneActive: false,
                  })
                }}
                isRecord={deviceActiveState.microphoneActive}
                onAudioReady={(audio: FileType) =>
                  sendMessage(MessageKindEnum.audio, "", [audio])
                }
              />
            </ViewIf>

            {/* --------------------------------------------------------------------------- */}
            {/*  VIDEO RECORDING  */}
            {/* --------------------------------------------------------------------------- */}

            <ViewIf if={deviceActiveState.cameraActive}>
              <View style={styles.videoRecordWrap}>
                <View style={styles.videoRecordSubWrap}>
                  <Icon
                    name="far fa-circle-dot"
                    bald
                    fill={AppColors.danger}
                    size={12}
                  />
                  <StyledText style={styles.videoRecordTime}>
                    0:09,18
                  </StyledText>
                </View>
                <View style={styles.videoRecordBtnWrap}>
                  <StyledText style={styles.videoRecordBtn}>Cancel</StyledText>
                </View>
              </View>
            </ViewIf>

            {textMessage.length === 0 &&
              (emotionCategory === "sticker" ||
                emotionCategory === "gif" ||
                emotionCategory === "emoji") &&
              slowModeTime <= 0 &&
              isShowEmojiBox && (
                <View>
                  {!expanded ? (
                    <TouchableOpacity
                      style={styles.leftIconWrapper}
                      onPress={goUp}
                    >
                      <SvgXml xml={SVGIcons.chervonUp(AppColors.iconDefault)} />
                    </TouchableOpacity>
                  ) : (
                    <TouchableOpacity
                      style={styles.leftIconWrapper}
                      onPress={goDown}
                    >
                      <SvgXml
                        xml={SVGIcons.chervonDown(AppColors.iconDefault)}
                      />
                    </TouchableOpacity>
                  )}
                </View>
              )}
            {!files ||
              (slowModeTime <= 0 &&
                !textMessage &&
                !editTextMessage &&
                !isShowEmojiBox &&
                (deviceState.microphone ? (
                  <Pressable
                    style={[
                      styles.leftIconWrapper,
                      deviceActiveState.microphoneActive
                        ? styles.microphoneActiveWrap
                        : {},
                    ]}
                    onLongPress={() => {
                      setDeviceActiveState({
                        ...deviceActiveState,
                        microphoneActive: true,
                      })
                    }}
                    onPressOut={() => {
                      setDeviceActiveState({
                        ...deviceActiveState,
                        microphoneActive: false,
                      })
                    }}
                    onPress={() => {
                      setDeviceState({
                        ...deviceState,
                        camera: true,
                        microphone: false,
                      })
                    }}
                  >
                    {deviceActiveState.microphoneActive && (
                      <View style={styles.microphoneActive} />
                    )}

                    <Icon
                      name="fal fa-microphone"
                      width={14}
                      height={18}
                      fill={
                        deviceActiveState.microphoneActive ? "white" : "#8592AA"
                      }
                    />
                  </Pressable>
                ) : (
                  <Pressable
                    style={styles.leftIconWrapper}
                    onLongPress={() => {
                      setDeviceActiveState({
                        ...deviceActiveState,
                        cameraActive: true,
                      })
                    }}
                    onPressOut={() => {
                      setDeviceActiveState({
                        ...deviceActiveState,
                        cameraActive: false,
                      })
                    }}
                    onPress={() => {
                      setDeviceState({
                        ...deviceState,
                        camera: false,
                        microphone: true,
                      })
                    }}
                  >
                    {!deviceActiveState.cameraActive ? (
                      <Icon
                        name="fal fa-camera-viewfinder"
                        width={18}
                        height={18}
                      />
                    ) : (
                      <SvgXml
                        xml={SVGIcons.cameraActiveIcon({
                          bgColor: AppColors.primary,
                          color: AppColors.textPrimaryLight,
                        })}
                      />
                    )}
                  </Pressable>
                )))}

            {/* --------------------------------------------------------------------------- */}
            {/* SLOWMODE TIMER */}
            {/* --------------------------------------------------------------------------- */}

            {slowModeTime > 0 && (
              <Tooltip
                text={`Slowmode is enabled. You can send message in ${channel ? channel.slowMode : 0} seconds.`}
              >
                <StyledText style={styles.recordTimeText}>
                  {DateUtils.recordingTime(slowModeTime * 4)}
                </StyledText>
              </Tooltip>
            )}

            {/* --------------------------------------------------------------------------- */}
            {/* SEND MESSAGE BUTTON */}
            {/* --------------------------------------------------------------------------- */}

            {(files.length > 0 ||
              editTextMessage.length > 0 ||
              (textMessage.length > 0 && slowModeTime <= 0)) && (
              <TouchableOpacity
                style={{ marginBottom: 6 }}
                onPress={() => {
                  editMessage && editMessageInput
                    ? onMessageUpdate(
                        editMessageInput,
                        editTextMessage,
                        [],
                        [],
                        undefined,
                      )
                    : sendMessage(MessageKindEnum.text, textMessage, files)
                }}
              >
                <SvgXml
                  xml={SVGIcons.arrowUpIcon({
                    color: AppColors.textPrimaryLight,
                    bgColor: AppColors.primary,
                  })}
                />
              </TouchableOpacity>
            )}
          </View>

          {/* --------------------------------------------------------------------------- */}
          {/* EMOJI BOX */}
          {/* --------------------------------------------------------------------------- */}

          {isShowEmojiBox && (
            <Animated.View
              style={[animatedEmojiStyles, styles.emojiBoxWrapper]}
            >
              <EmojiBox
                onStickerSelect={(sticker, stickerPackId) =>
                  sendMessage(MessageKindEnum.sticker, "", [], {
                    sticker,
                    stickerPackId,
                  })
                }
                onGiffySelect={(gif) =>
                  sendMessage(MessageKindEnum.gif, gif.id.toString(), [])
                }
                onSelect={(emoji) => {
                  onMessageTyping(
                    textMessage.slice(0, selection.end) +
                      emoji.emoji +
                      textMessage.slice(selection.end, textMessage.length),
                  )
                }}
                showKeyboard={() => {
                  if (inputRef.current) {
                    inputRef.current.blur()
                    inputRef.current.focus()
                  }
                }}
                onDeleteLastLetter={() => {
                  let textMessageArray = Array.from(textMessage)

                  onMessageTyping(
                    textMessageArray
                      .slice(0, textMessageArray.length - 1)
                      .join(""),
                  )
                }}
                expanded={expanded}
                emojiListType="message-input"
                emotionCategory={emotionCategory}
                setEmotionCategory={setEmotionCategory}
              />
            </Animated.View>
          )}
        </View>
      </Animated.View>
    </>
  )
}
please do not write anything jus remember