import React, { useCallback, useEffect, useRef, useState } from 'react';
import { View, Text, Image, TouchableOpacity, LayoutAnimation, Modal, Linking } from 'react-native';
import { FlashList, FlashListRef } from '@shopify/flash-list';
import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
import { popupStyles, styles } from './styles';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  runOnJS,
  interpolate,
  Extrapolation
} from 'react-native-reanimated';
import { FilterImage } from 'react-native-svg/filter-image';

import { NAVIGATION_PAGES } from 'src/types';
import { StoreType, storage } from 'src/storage';

import { Header, Input, PageWrapper } from 'src/components';
import { Colors } from 'src/theme';

import SearchIcon from 'assets/icons/search.svg';
import CalendarIcon from 'assets/icons/events/calendar-solid.svg';
import EarthIcon from 'assets/icons/travels-section/earth.svg';
import NomadsIcon from 'assets/icons/bottom-navigation/travellers.svg';
import CalendarPlusIcon from 'assets/icons/events/calendar-plus.svg';
import ShoppingCartIcon from 'assets/icons/events/shopping-cart.svg';
import StarIcon from 'assets/icons/events/star.svg';

import {
  PostGetEventsListReturn,
  SingleEvent,
  useGetCanAddEventQuery,
  useGetEventsListQuery
} from '@api/events';
import moment from 'moment';
import { API_HOST } from 'src/constants';
import { renderSpotsText } from './utils';
import ChevronIcon from 'assets/icons/chevron-left.svg';
import Tooltip from 'react-native-walkthrough-tooltip';
import InfoIcon from 'assets/icons/info-solid.svg';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import TabViewWrapper from 'src/components/TabViewWrapper';
import { getFontSize } from 'src/utils';

function TabViewDelayed({
  children,
  waitBeforeShow = 0
}: {
  children: React.ReactNode;
  waitBeforeShow?: number;
}) {
  const [isShown, setIsShown] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setIsShown(true);
    }, waitBeforeShow);
    return () => clearTimeout(timer);
  }, [waitBeforeShow]);

  return isShown ? children : null;
}

const EventsScreen = () => {
  const insets = useSafeAreaInsets();
  const token = (storage.get('token', StoreType.STRING) as string) ?? null;
  const { data, refetch } = useGetEventsListQuery(token, 0, true);
  const { data: pastData } = useGetEventsListQuery(token, 1, true);
  const { data: canAddEvent } = useGetCanAddEventQuery(token, true);
  const navigation = useNavigation();
  const [searchQuery, setSearchQuery] = useState('');
  const [events, setEvents] = useState<PostGetEventsListReturn>({
    local_meetings: [],
    nm: [],
    shared_trips: []
  } as never);
  const [pastEvents, setPastEvents] = useState<PostGetEventsListReturn>({
    local_meetings: [],
    nm: [],
    shared_tripsv: []
  } as never);
  const [filteredEvents, setFilteredEvents] = useState<PostGetEventsListReturn>({
    local_meetings: [],
    nm: [],
    shared_trips: []
  } as never);
  const [filteredPastEvents, setFilteredPastEvents] = useState<PostGetEventsListReturn>({
    local_meetings: [],
    nm: [],
    shared_trips: []
  } as never);
  const [tooltipStates, setTooltipStates] = useState<Record<number, boolean>>({});
  const date = new Date();

  const [expandedStates, setExpandedStates] = useState<Record<string, boolean>>({
    nm: false,
    shared_trips: false,
    local_meetings: false
  });

  const scrollViewRefs = useRef<Record<string, FlashListRef<SingleEvent> | null>>({
    nm: null,
    shared_trips: null,
    local_meetings: null
  });
  const sectionRef = useRef<View>(null);

  const [showPopup, setShowPopup] = useState(false);
  const [popupPosition, setPopupPosition] = useState({ x: 0, y: 0 });
  const [toolTipVisible, setToolTipVisible] = useState<boolean>(false);

  const buttonRef = useRef<TouchableOpacity>(null);

  const [index, setIndex] = useState<number>(0);
  const [routes] = useState<{ key: 'nm' | 'shared_trips' | 'local_meetings'; title: string }[]>([
    { key: 'nm', title: 'NomadMania Events' },
    { key: 'shared_trips', title: 'Shared Trips' },
    { key: 'local_meetings', title: 'Local Meetings' }
  ]);

  const SEARCH_CONTAINER_HEIGHT = 44;
  const searchContainerHeight = useSharedValue(SEARCH_CONTAINER_HEIGHT);
  const lastScrollY = useRef(0);
  const isSearchVisible = useRef(true);

  const hideSearchContainer = useCallback(() => {
    'worklet';
    if (isSearchVisible.current) {
      isSearchVisible.current = false;
      searchContainerHeight.value = withTiming(0, {
        duration: 150
      });
    }
  }, []);

  const showSearchContainer = useCallback(() => {
    'worklet';
    if (!isSearchVisible.current) {
      isSearchVisible.current = true;
      searchContainerHeight.value = withTiming(SEARCH_CONTAINER_HEIGHT, {
        duration: 150
      });
    }
  }, []);

  const handleScroll = useCallback(
    (event: any) => {
      const currentScrollY = event.nativeEvent.contentOffset.y;
      const diff = currentScrollY - lastScrollY.current;

      if (diff > 3 && currentScrollY > 20 && isSearchVisible.current) {
        runOnJS(hideSearchContainer)();
      } else if (currentScrollY <= 5 && !isSearchVisible.current) {
        runOnJS(showSearchContainer)();
      }

      lastScrollY.current = currentScrollY;
    },
    [hideSearchContainer, showSearchContainer]
  );

  const searchContainerAnimatedStyle = useAnimatedStyle(() => {
    return {
      height: searchContainerHeight.value,
      overflow: 'hidden',
      opacity: interpolate(
        searchContainerHeight.value,
        [0, SEARCH_CONTAINER_HEIGHT],
        [0, 1],
        Extrapolation.CLAMP
      )
    };
  });

  const handleAddButtonPress = () => {
    if (buttonRef.current) {
      buttonRef.current.measure((x, y, width, height, pageX, pageY) => {
        setPopupPosition({
          x: pageX - 120,
          y: pageY + height + 5
        });
        setShowPopup(true);
      });
    }
  };

  const handlePopupOption = (option: 'meeting' | 'trip') => {
    setShowPopup(false);

    if (option === 'meeting') {
      navigation.navigate(NAVIGATION_PAGES.CREATE_EVENT as never);
    } else if (option === 'trip') {
      navigation.navigate(NAVIGATION_PAGES.CREATE_SHARED_TRIP as never);
    }
  };

  const toggleExpand = (tabKey: string) => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut, () => {
      if (!expandedStates[tabKey] && sectionRef.current && scrollViewRefs.current[tabKey]) {
        scrollViewRefs.current[tabKey]?.scrollToEnd({
          animated: true
        });
      }
    });

    setExpandedStates((prev) => ({
      ...prev,
      [tabKey]: !prev[tabKey]
    }));
  };

  useEffect(() => {
    if (data && data.nm) {
      setEvents(data);
      setFilteredEvents(data);
    }
  }, [data]);

  useEffect(() => {
    if (pastData && pastData.nm) {
      setPastEvents(pastData);
      setFilteredPastEvents(pastData);
    }
  }, [pastData]);

  useFocusEffect(
    useCallback(() => {
      refetch();
    }, [navigation])
  );

  const handleSearch = (text: string) => {
    if (text) {
      const searchData =
        (index === 0
          ? events.nm
          : index === 1
            ? events.shared_trips
            : events.local_meetings
        ).filter((item: any) => {
          const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
          const textData = text.toLowerCase();
          return itemData.indexOf(textData) > -1;
        }) ?? [];
      setFilteredEvents(
        index === 0
          ? { ...events, nm: searchData }
          : index === 1
            ? { ...events, shared_trips: searchData }
            : { ...events, local_meetings: searchData }
      );

      const searchPastData =
        (index === 0
          ? pastEvents.nm
          : index === 1
            ? pastEvents.shared_trips
            : pastEvents.local_meetings
        ).filter((item: any) => {
          const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
          const textData = text.toLowerCase();
          return itemData.indexOf(textData) > -1;
        }) ?? [];
      setFilteredPastEvents(
        index === 0
          ? { ...events, nm: searchPastData }
          : index === 1
            ? { ...events, shared_trips: searchPastData }
            : { ...events, local_meetings: searchPastData }
      );

      setSearchQuery(text);
    } else {
      setFilteredEvents(events);
      setFilteredPastEvents(pastEvents);
      setSearchQuery(text);
    }
  };

  const formatEventDate = (event: SingleEvent) => {
    if (event.date_from && event.date_to) {
      if (event.date_tentative) {
        const dateFrom = moment(event.date_from, 'YYYY-MM').format('MMM YYYY');
        const dateTo = moment(event.date_to, 'YYYY-MM').format('MMM YYYY');

        if (dateFrom === dateTo) {
          return dateFrom;
        }

        return `${dateFrom} - ${dateTo}`;
      }
      return `${moment(event.date_from, 'YYYY-MM-DD').format('DD MMM YYYY')} - ${moment(event.date_to, 'YYYY-MM-DD').format('DD MMM YYYY')}`;
    } else {
      if (event.date_tentative) {
        return `${moment(event.date, 'YYYY-MM').format('MMM YYYY')}`;
      }
      return moment(event.date, 'YYYY-MM-DD').format('DD MMMM YYYY');
    }
  };

  const renderEventCard = ({ item }: { item: SingleEvent }) => {
    let staticImgUrl = '/static/img/events/meeting.webp';
    let badgeColor = Colors.DARK_BLUE;
    let badgeText = '';
    if (item.full) {
      badgeColor = Colors.LIGHT_GRAY;
      badgeText = 'FULL';
    } else if (item.closed) {
      badgeColor = Colors.LIGHT_GRAY;
      badgeText = 'CLOSED';
    } else if (item.type === 2) {
      badgeColor = Colors.ORANGE;
      badgeText = 'TOUR';
      staticImgUrl = '/static/img/events/trip.webp';
    } else if (item.type === 3) {
      badgeColor = Colors.DARK_BLUE;
      badgeText = 'CONF';
      staticImgUrl = '/static/img/events/conference.webp';
    }

    const photo = item.photo
      ? API_HOST + '/webapi/events/get-square-photo/' + item.id
      : API_HOST + staticImgUrl;

    return (
      <View>
        <TouchableOpacity
          style={[
            styles.card,
            item.type === 2 || item.type === 3 || item.full || item.closed
              ? { backgroundColor: Colors.FILL_LIGHT }
              : { backgroundColor: Colors.WHITE }
          ]}
          onPress={() => {
            if (index === 0 && item.wp_url) {
              const eventUrl = `${API_HOST}${item.wp_url}`;
              Linking.openURL(eventUrl).catch((err) => console.error('Failed to event URL:', err));
            } else {
              navigation.navigate(...([NAVIGATION_PAGES.EVENT, { url: item.url }] as never));
            }
          }}
          disabled={item.active === 0}
        >
          <View style={styles.imageWrapper}>
            {item.active === 0 ? (
              <FilterImage
                source={{ uri: photo }}
                style={[
                  styles.image,
                  {
                    filter: 'grayscale(100%)'
                  }
                ]}
              />
            ) : (
              <Image
                source={{ uri: photo, cache: 'reload' }}
                style={styles.image}
                resizeMode="cover"
              />
            )}

            {item.star === 1 && (
              <View style={styles.iconOverlay}>
                <StarIcon fill={Colors.WHITE} width={12} />
              </View>
            )}

            {item.joined && token ? (
              <View style={styles.joinedOverlay}>
                <Text style={{ color: Colors.WHITE, fontSize: 12, fontFamily: 'redhat-700' }}>
                  Joined
                </Text>
              </View>
            ) : null}
          </View>

          <View style={styles.info}>
            <Text style={styles.title} numberOfLines={1}>
              {item.name}
            </Text>

            <View style={styles.row}>
              {item.type === 1 && item?.flag ? (
                <Tooltip
                  key={item.id}
                  isVisible={!!tooltipStates[item.id]}
                  content={<Text style={{ color: Colors.BLACK }}>{item.country}</Text>}
                  contentStyle={{ backgroundColor: Colors.FILL_LIGHT }}
                  tooltipStyle={{
                    position: 'absolute',
                    zIndex: 1000
                  }}
                  arrowStyle={{
                    width: 16,
                    height: 8
                  }}
                  placement="top"
                  onClose={() => setTooltipStates((prev) => ({ ...prev, [item.id]: false }))}
                  backgroundColor="transparent"
                  allowChildInteraction={false}
                >
                  <TouchableOpacity
                    onPress={() => setTooltipStates((prev) => ({ ...prev, [item.id]: true }))}
                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                  >
                    <Image
                      source={{ uri: API_HOST + item.flag }}
                      style={{
                        width: 14,
                        height: 14,
                        borderRadius: 7,
                        borderWidth: 0.5,
                        borderColor: Colors.DARK_LIGHT
                      }}
                    />
                  </TouchableOpacity>
                </Tooltip>
              ) : (
                <EarthIcon fill={Colors.DARK_BLUE} height={14} width={14} />
              )}
              <Text style={styles.dateAndLocation} numberOfLines={1}>
                {item.address1}
              </Text>
            </View>

            <View style={[styles.row]}>
              <View style={styles.row}>
                <CalendarIcon fill={Colors.DARK_BLUE} height={14} width={14} />
                <Text style={[styles.dateAndLocation, { flex: 0 }]} numberOfLines={1}>
                  {formatEventDate(item)}
                </Text>
              </View>
            </View>

            {item.registrations_info !== 1 && (
              <View style={styles.row}>
                <NomadsIcon fill={Colors.DARK_BLUE} height={14} width={14} />
                <Text style={styles.dateAndLocation} numberOfLines={1}>
                  {renderSpotsText(item)}
                </Text>
              </View>
            )}
          </View>

          {item.type === 2 || item.type === 3 || item.full || item.closed ? (
            <View
              style={[
                styles.statusBadge,
                { backgroundColor: item.active ? badgeColor : Colors.LIGHT_GRAY }
              ]}
            >
              <View style={styles.rotatedContainer}>
                <Text style={styles.statusText}>{badgeText}</Text>
              </View>
            </View>
          ) : null}
        </TouchableOpacity>
      </View>
    );
  };

  const renderScene = ({
    route
  }: {
    route: { key: 'nm' | 'shared_trips' | 'local_meetings'; title: string };
  }) => {
    const isCurrentTabExpanded = expandedStates[route.key];

    return (
      <>
        <FlashList
          ref={(ref) => {
            scrollViewRefs.current[route.key] = ref;
          }}
          data={filteredEvents[route.key] || []}
          ListHeaderComponent={
            route.key === 'shared_trips' ? (
              <TouchableOpacity
                onPress={() => setToolTipVisible(true)}
                style={{ flexDirection: 'row', alignItems: 'center', gap: 6, marginBottom: 12 }}
              >
                <Tooltip
                  isVisible={toolTipVisible}
                  content={
                    <Text style={{ fontSize: 12, color: Colors.DARK_BLUE }}>
                      Disclaimer: All trips listed here are shared by members of our travel
                      community. NomadMania is not the organizer of these trips, and we do not
                      verify their details, safety, or suitability. Participation is at your own
                      discretion and risk. We do not take any responsibility for arrangements,
                      agreements, or outcomes related to these community-shared trips.
                    </Text>
                  }
                  contentStyle={{ backgroundColor: Colors.WHITE }}
                  placement="bottom"
                  onClose={() => setToolTipVisible(false)}
                  backgroundColor="transparent"
                  allowChildInteraction={false}
                >
                  <TouchableOpacity
                    onPress={() => setToolTipVisible(true)}
                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                  >
                    <InfoIcon fill={Colors.DARK_BLUE} width={16} height={16} />
                  </TouchableOpacity>
                </Tooltip>
                <Text style={{ fontSize: 12, color: Colors.DARK_BLUE, fontWeight: '600' }}>
                  Disclaimer [read more]
                </Text>
              </TouchableOpacity>
            ) : null
          }
          scrollEnabled={true}
          keyExtractor={(item) => `${route.key}-${item.id}`}
          renderItem={renderEventCard}
          contentContainerStyle={styles.listContainer}
          showsVerticalScrollIndicator={false}
          onScroll={handleScroll}
          scrollEventThrottle={16}
          ListFooterComponent={
            filteredPastEvents[route.key] && filteredPastEvents[route.key].length ? (
              <View ref={sectionRef} style={styles.sectionContainer}>
                <TouchableOpacity onPress={() => toggleExpand(route.key)} style={styles.header}>
                  <View style={styles.headerContainer}>
                    <Text style={styles.headerText}>Past Events</Text>
                  </View>

                  <View style={styles.chevronContainer}>
                    <ChevronIcon
                      fill={Colors.DARK_BLUE}
                      style={[styles.headerIcon, isCurrentTabExpanded ? styles.rotate : null]}
                    />
                  </View>
                </TouchableOpacity>

                {isCurrentTabExpanded ? (
                  <FlashList
                    data={filteredPastEvents[route.key] || []}
                    scrollEnabled={true}
                    keyExtractor={(item) => item.id.toString()}
                    renderItem={renderEventCard}
                    contentContainerStyle={styles.listContainer}
                    showsVerticalScrollIndicator={false}
                  />
                ) : null}
              </View>
            ) : null
          }
        />
      </>
    );
  };

  const handleIndexChange = useCallback(
    (newIndex: number) => {
      setSearchQuery('');
      if (newIndex >= 0 && newIndex < routes.length) {
        setIndex(newIndex);
      }
    },
    [routes.length]
  );

  return (
    <View style={{ height: '100%', paddingTop: insets.top }}>
      <View style={{ marginLeft: '5%', marginRight: '5%' }}>
        <View
          style={{
            alignItems: 'center',
            flexDirection: 'row',
            justifyContent: 'space-between',
            paddingVertical: 16
          }}
        >
          <View style={{ width: 30 }} />
          <Text
            style={{ color: Colors.DARK_BLUE, fontFamily: 'redhat-700', fontSize: getFontSize(14) }}
          >
            Events
          </Text>
          {canAddEvent?.can ? (
            <TouchableOpacity
              ref={buttonRef}
              onPress={handleAddButtonPress}
              style={{ width: 30 }}
              hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
            >
              <CalendarPlusIcon fill={Colors.DARK_BLUE} />
            </TouchableOpacity>
          ) : <View style={{ width: 30 }} />}
        </View>

        <Animated.View style={[styles.searchContainer, searchContainerAnimatedStyle]}>
          <Input
            inputMode={'search'}
            placeholder={'Search'}
            onChange={(text) => handleSearch(text)}
            value={searchQuery}
            icon={<SearchIcon fill={'#C8C8C8'} width={14} height={14} />}
            height={38}
          />
        </Animated.View>
      </View>

      <TabViewWrapper
        routes={routes}
        renderScene={renderScene as never}
        setIndex={setIndex}
        lazy={false}
        selectedIndex={index}
      />

      <Modal
        visible={showPopup}
        transparent={true}
        animationType="fade"
        onRequestClose={() => setShowPopup(false)}
      >
        <TouchableOpacity
          style={{
            flex: 1,
            backgroundColor: 'rgba(0,0,0,0.1)'
          }}
          onPress={() => setShowPopup(false)}
          activeOpacity={1}
        >
          <View
            style={[
              popupStyles.popup,
              {
                top: popupPosition.y,
                left: popupPosition.x
              }
            ]}
          >
            <TouchableOpacity
              style={popupStyles.popupOption}
              onPress={() => handlePopupOption('meeting')}
            >
              <Text style={popupStyles.popupText}>Add meeting</Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={[popupStyles.popupOption, popupStyles.popupOptionLast]}
              onPress={() => handlePopupOption('trip')}
            >
              <Text style={popupStyles.popupText}>Add shared trip</Text>
            </TouchableOpacity>
          </View>
        </TouchableOpacity>
      </Modal>
    </View>
  );
};

export default EventsScreen;
