import { RoomUtils } from "@openchat/models"
import {
  AccountUserType,
  ContactType,
  RoomKindEnum,
  StoryType,
} from "@openchat/types"
import {
  useAccountId,
  useAccountStories,
  useAccountUser,
  useContacts,
  useDashboardSettings,
  useFolder,
  useFolderCount,
  useRooms,
  useRoomsFilter,
  useStories,
} from "@openchat/ui"
import React, { useState } from "react"
import {
  Dimensions,
  FlatList,
  Pressable,
  SafeAreaView,
  ScrollView,
  TouchableOpacity,
  View,
} from "react-native"
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withSpring,
  interpolate,
  Extrapolate,
  useAnimatedScrollHandler,
} from "react-native-reanimated"
import { Gesture, GestureDetector } from "react-native-gesture-handler"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { AppAssets } from "../../../../app/app-assets"
import { AppColors } from "../../../../app/app-colors"
import { NavigationRef } from "../../../../navigation/navigation.hooks"
import { EmptyState } from "../../../../ui-components/empty-state/empty-state.component"
import { Icon } from "../../../../ui-components/icon/icon.component"
import { Input } from "../../../../ui-components/input/input.component"
import { MenuOpener } from "../../../../ui-components/menu/menu-opener.provider"
import { StyledText } from "../../../../ui-components/styled-text/styled-text"
import { UnderlineText } from "../../../../ui-components/underline-text/underline-text.component"
import { FolderTabs } from "../../../folder/folder-tabs/folder-tabs.component"
import { StoryList } from "../../../story/story-list/story-list.component"
import { UserPhoto } from "../../../user/user-photo/user-photo.component"
import { DashboardMessagesItem } from "../dashboard-messages-item/dashboard-messages-item.component"
import { DashboardMessagesMenu } from "./dashboard-messages-menu.component"
import { useStyles } from "./dashboard-messages.style"

const SCREEN_WIDTH = Dimensions.get("window").width
const HEADER_BASE_HEIGHT = 70
const HEADER_MAX_HEIGHT = 150
const TOGGLE_THRESHOLD = 100
const STORY_SIZE_MIN = 21
const STORY_SIZE_MAX = 60

type StoryItem =
  | { isUser: true; user: AccountUserType }
  | { isUser: false; contact: ContactType; stories: StoryType[] }

// @reviewed
export function DashboardMessages() {
  // ---------------------------------------------------------------------------
  // variables
  // ---------------------------------------------------------------------------

  const styles = useStyles()

  const { selectedFolderId } = useDashboardSettings()
  const foldersCount = useFolderCount()
  const selectedFolder = useFolder(selectedFolderId)
  const allRooms = useRooms()
  const accountUser = useAccountUser()
  const accountId = useAccountId()
  const contacts = useContacts()
  const stories = useStories()
  const accountStories = useAccountStories()

  const storiesContact = contacts.map((contact) => {
    const contactStories = {
      contact: contact,
      stories: stories.filter((story) => story.owner === contact.identityId),
    }
    return contactStories
  })

  const [keyword, setKeyword] = useState<string>("")
  const [showStory, setShowStory] = useState<boolean>(true)

  const filteredRooms = useRoomsFilter(allRooms, {
    draftMessage: true,
    folder: selectedFolder,
    keyword: keyword,
    noReplies: true,
    recents: false,
  })

  const currentRoomId =
    accountId &&
    RoomUtils.createId({
      kind: RoomKindEnum.DM,
      userId: accountId,
    })

  const { top } = useSafeAreaInsets()
  const scrollY = useSharedValue(0)
  const shouldAnimateHeader = useSharedValue(false)
  const startHeaderHeight = useSharedValue(HEADER_BASE_HEIGHT)
  const headerHeight = useSharedValue(HEADER_BASE_HEIGHT)
  const storyListHeight = useSharedValue(60) // Initial height for story list
  const storyItemSize = useSharedValue(STORY_SIZE_MIN)
  const headerToggle = useSharedValue(false)

  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      if (event.translationY < 0) {
        headerHeight.value = Math.max(
          HEADER_BASE_HEIGHT,
          event.translationY + startHeaderHeight.value,
        )
        headerToggle.value = false
        return
      }
      if (!shouldAnimateHeader.value) return

      scrollY.value = event.translationY
      headerHeight.value = Math.max(
        HEADER_BASE_HEIGHT,
        scrollY.value + startHeaderHeight.value,
      )

      if (event.translationY > TOGGLE_THRESHOLD && !headerToggle.value) {
        headerToggle.value = true
      }
    })
    .onEnd(() => {
      if (headerToggle.value) {
        headerHeight.value = withSpring(HEADER_MAX_HEIGHT, {
          damping: 20,
          stiffness: 150,
        })
        startHeaderHeight.value = HEADER_MAX_HEIGHT
      } else {
        headerHeight.value = withSpring(HEADER_BASE_HEIGHT, {
          damping: 20,
          stiffness: 150,
        })
        startHeaderHeight.value = HEADER_BASE_HEIGHT
      }
    })

  const nativeGesture = Gesture.Native()
  const composedGesture = Gesture.Simultaneous(panGesture, nativeGesture)

  const headerAnimatedStyle = useAnimatedStyle(() => ({
    height: headerHeight.value,
  }))
  console.log("==================stories==================")
  console.log(storiesContact)
  console.log("=================stories===================")
  const renderStoryItem = ({ item }: { item: StoryItem }) => {
    const user = item.isUser ? item.user : item.contact
    const hasStories = item.isUser
      ? accountStories.length > 0
      : item.stories.length > 0

    return (
      <Pressable onPress={() => setShowStory(!showStory)}>
        <Animated.View
          style={[
            styles.wraperStory,
            {
              borderColor: hasStories ? AppColors.danger : AppColors.light,
            },
          ]}
        >
          <UserPhoto
            user={user}
            size={21}
            onPress={() => setShowStory(!showStory)}
          />
        </Animated.View>
      </Pressable>
    )
  }

  const scrollHandler = useAnimatedScrollHandler({
    onScroll: (event) => {
      const offsetY = event.contentOffset.y
      if (offsetY <= 100) {
        shouldAnimateHeader.value = true
      } else {
        shouldAnimateHeader.value = false
      }
    },
  })

  const storyData: StoryItem[] = [
    { isUser: true, user: accountUser as AccountUserType },
    ...storiesContact.map((item) => ({
      isUser: false as const,
      contact: item.contact,
      stories: item.stories,
    })),
  ]

  // ---------------------------------------------------------------------------
  if (!accountUser) return null
  return (
    <SafeAreaView style={[styles.container]}>
      {/* --------------------------------------------------------------------------- */}
      {/* HEADER */}
      {/* --------------------------------------------------------------------------- */}

      <Animated.View style={[styles.headerWrapper, headerAnimatedStyle]}>
        <StyledText style={styles.header}>Messages</StyledText>
        <Animated.FlatList
          data={storyData}
          renderItem={renderStoryItem}
          keyExtractor={(item) => (item.isUser ? "user" : item.contact.id)}
          horizontal
          showsHorizontalScrollIndicator={false}
          contentContainerStyle={[styles.contactsStories]}
        />
        <Animated.View style={styles.iconsWrapper}>
          {/* --------------------------------------------------------------------------- */}
          {/* ADD STORIES BUTTON */}
          {/* --------------------------------------------------------------------------- */}

          {accountStories.length !== 0 && (
            <TouchableOpacity
              style={styles.iconWrapperHours}
              onPress={() => {
                NavigationRef.navigate("StoryUpset")
              }}
            >
              <Icon name="far fa-plus" fill={AppColors.primary} size={7} />
            </TouchableOpacity>
          )}

          <MenuOpener touchOpacity={0.7} content={<DashboardMessagesMenu />}>
            <Icon name="far fa-ellipsis-vertical" height={18} width={5} />
          </MenuOpener>
        </Animated.View>
      </Animated.View>

      <GestureDetector gesture={composedGesture}>
        <Animated.ScrollView
          contentContainerStyle={{ flexGrow: 1 }}
          stickyHeaderIndices={foldersCount > 0 ? [1] : []}
          onScroll={scrollHandler}
          scrollEventThrottle={16}
        >
          <>
            {/* --------------------------------------------------------------------------- */}
            {/* SEARCH INPUT */}
            {/* --------------------------------------------------------------------------- */}
            {allRooms.length > 0 && (
              <View style={styles.inputWrapper}>
                <Input
                  mode="secondary"
                  iconName={
                    keyword ? "fal fa-xmark" : "fal fa-magnifying-glass"
                  }
                  placeholder="Search messages"
                  value={keyword}
                  onChangeText={(text) => setKeyword(text)}
                  onIconPress={() => setKeyword("")}
                  // autoFocus={true}
                />
              </View>
            )}

            {/* --------------------------------------------------------------------------- */}
            {/* FOLDER TABS */}
            {/* --------------------------------------------------------------------------- */}

            {!keyword && <FolderTabs />}

            {/* --------------------------------------------------------------------------- */}
            {/* NO CONVERSATIONS STATUS MESSAGES */}
            {/* --------------------------------------------------------------------------- */}

            {(allRooms.length === 0 ||
              (!selectedFolder && filteredRooms.length === 0 && !keyword)) && (
              <View style={styles.view}>
                <EmptyState
                  title="No conversations yet"
                  description={`Search for people and communities${"\n"} to start a new conversation.`}
                  style={styles.viewContent}
                  image={AppAssets.images.chatPhoto}
                />
              </View>
            )}

            {allRooms.length > 0 &&
              selectedFolder &&
              filteredRooms.length === 0 &&
              !accountId &&
              !keyword && (
                <View>
                  <View style={styles.view}>
                    <EmptyState
                      image={AppAssets.images.chatPhoto}
                      title="No conversations"
                      description={
                        <>
                          Folder doesn't have any conversations. {"\n"} Press{" "}
                          <UnderlineText
                            onPress={() => {
                              if (!selectedFolder) return
                              NavigationRef.navigate("FolderUpsert", {
                                folder: selectedFolder,
                              })
                            }}
                          >
                            here
                          </UnderlineText>{" "}
                          to add conversations to this folder.
                        </>
                      }
                      style={styles.viewContent}
                    />
                  </View>
                </View>
              )}

            {filteredRooms.length === 0 && !!keyword && (
              <View style={styles.view}>
                <EmptyState
                  image={AppAssets.images.dashboardEmptyPhoto}
                  title="Nothing found"
                  description={
                    <>
                      “{keyword}” did not match any conversations. {"\n"} Press{" "}
                      <UnderlineText onPress={() => setKeyword("")}>
                        here
                      </UnderlineText>{" "}
                      to reset search.
                    </>
                  }
                />
              </View>
            )}

            {allRooms.length > 0 && (
              <Pressable
                style={({ pressed }) => [
                  styles.savedMsg,
                  {
                    backgroundColor: pressed
                      ? AppColors.backgroundDark
                      : "transparent",
                  },
                ]}
                onPress={() => {
                  if (currentRoomId) {
                    NavigationRef.navigate("MessageRoom", {
                      roomId: currentRoomId,
                    })
                  }
                }}
              >
                <View style={styles.savedMsgIcon}>
                  <Icon
                    name="fal fa-bookmark"
                    size={16}
                    fill={AppColors.light}
                  />
                </View>
                <StyledText style={styles.savedMsgText}>
                  Saved messages
                </StyledText>
              </Pressable>
            )}

            {/* --------------------------------------------------------------------------- */}
            {/* ROOMS LIST */}
            {/* --------------------------------------------------------------------------- */}

            {!currentRoomId &&
              filteredRooms.map((room) => (
                <DashboardMessagesItem key={room.id} room={room} />
              ))}
          </>
        </Animated.ScrollView>
      </GestureDetector>
    </SafeAreaView>
  )
}
How to  implement swipe up and down gestures specifically for the renderStoryItem component ?