import {
  Animated as Animation,
  Dimensions,
  Linking,
  Platform,
  Text,
  TextInput,
  TouchableOpacity,
  View,
  Image
} from 'react-native';
import React, { useEffect, useMemo, useRef, useState, useCallback } from 'react';
import MapView, { Geojson, Marker, UrlTile } from 'react-native-maps';
import * as turf from '@turf/turf';
import * as FileSystem from 'expo-file-system';
import * as Location from 'expo-location';
import { storage, StoreType } from '../../../storage';

import SearchIcon from '../../../../assets/icons/search.svg';
import LocationIcon from '../../../../assets/icons/location.svg';
import CloseSvg from '../../../../assets/icons/close.svg';
import FilterIcon from 'assets/icons/filter.svg';
import ProfileIcon from 'assets/icons/bottom-navigation/profile.svg';

import regions from '../../../../assets/geojson/nm2022.json';
import jsonData, { fetchJsonData } from '../../../database/geojsonService';

import {
  getCountriesDatabase,
  getFirstDatabase,
  getSecondDatabase,
  refreshDatabases
} from '../../../db';
import { LocationPopup, WarningModal, EditNmModal, AvatarWithInitials } from '../../../components';

import { styles } from './style';
import {
  calculateMapCountry,
  calculateMapRegion,
  filterCandidates,
  filterCandidatesMarkers,
  findRegionInDataset,
  processMarkerData
} from '../../../utils/mapHelpers';
import { getData } from '../../../modules/map/regionData';
import { fetchSeriesData, usePostSetToggleItem } from '@api/series';
import MarkerItem from './MarkerItem';
import ClusterItem from './ClusterItem';
import { FeatureCollection, ItemSeries, MapScreenProps, Region, Series } from '../../../types/map';
import { API_HOST, FASTEST_MAP_HOST } from 'src/constants';
import { useConnection } from 'src/contexts/ConnectionContext';
import ClusteredMapView from 'react-native-map-clustering';
import { fetchUserData, fetchUserDataDare } from '@api/regions';
import RegionPopup from 'src/components/RegionPopup';
import moment from 'moment';
import { qualityOptions } from '../TravelsScreen/utils/constants';
import Animated, { Easing } from 'react-native-reanimated';
import { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
import { Colors } from 'src/theme';
import { useGetUniversalSearch } from '@api/search';
import SearchModal from './UniversalSearch';
import FilterModal from './FilterModal';
import InfoIcon from 'assets/icons/info-solid.svg';
import { NAVIGATION_PAGES } from 'src/types';
import { useRegion } from 'src/contexts/RegionContext';
import { useFocusEffect } from '@react-navigation/native';
import { openstreetmapUrl } from 'src/constants/constants';
import { fetchCountryUserData } from '@api/countries';
import EditModal from '../TravelsScreen/Components/EditSlowModal';

const localTileDir = `${FileSystem.cacheDirectory}tiles/background`;
const localGridDir = `${FileSystem.cacheDirectory}tiles/grid`;
const localVisitedDir = `${FileSystem.cacheDirectory}tiles/user_visited`;
const localDareDir = `${FileSystem.cacheDirectory}tiles/regions_mqp`;

const AnimatedMarker = Animation.createAnimatedComponent(Marker);

const MapScreen: React.FC<MapScreenProps> = ({ navigation, route }) => {
  const [dareData, setDareData] = useState(jsonData);
  const tilesBaseURL = `${FASTEST_MAP_HOST}/tiles_osm`;
  const gridUrl = `${FASTEST_MAP_HOST}/tiles_nm/grid`;
  const dareTiles = `${FASTEST_MAP_HOST}/tiles_nm/regions_mqp`;

  const userId = storage.get('uid', StoreType.STRING);
  const token = storage.get('token', StoreType.STRING) as string;
  const netInfo = useConnection();

  const { mutateAsync } = fetchSeriesData();
  const { mutateAsync: mutateUserData } = fetchUserData();
  const { mutateAsync: mutateUserDataDare } = fetchUserDataDare();
  const { mutateAsync: mutateCountriesData } = fetchCountryUserData();
  const { mutate: updateSeriesItem } = usePostSetToggleItem();
  const visitedDefaultTiles = `${FASTEST_MAP_HOST}/tiles_nm/user_visited/${userId}`;
  const mapRef = useRef<MapView>(null);

  const [isConnected, setIsConnected] = useState<boolean | null>(true);
  const [selectedRegion, setSelectedRegion] = useState<FeatureCollection | null>(null);
  const [regionPopupVisible, setRegionPopupVisible] = useState<boolean | null>(false);
  const [regionData, setRegionData] = useState<Region | null>(null);
  const [userAvatars, setUserAvatars] = useState<string[]>([]);
  const [location, setLocation] = useState<Location.LocationObjectCoords | null>(null);
  const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
  const [openSettingsVisible, setOpenSettingsVisible] = useState<boolean>(false);
  const [isWarningModalVisible, setIsWarningModalVisible] = useState<boolean>(false);
  const [isEditSlowModalVisible, setIsEditSlowModalVisible] = useState<boolean>(false);

  const [markers, setMarkers] = useState<ItemSeries[]>([]);
  const [series, setSeries] = useState<Series[] | null>(null);
  const [processedMarkers, setProcessedMarkers] = useState<ItemSeries[]>([]);
  const [zoomLevel, setZoomLevel] = useState<number>(0);
  const [isEditModalVisible, setIsEditModalVisible] = useState(false);
  const [modalState, setModalState] = useState({
    selectedFirstYear: 2021,
    selectedLastYear: 2021,
    selectedQuality: qualityOptions[2],
    selectedNoOfVisits: 1,
    years: [],
    id: null
  });
  const [search, setSearch] = useState('');
  const [searchInput, setSearchInput] = useState('');
  const { data: searchData } = useGetUniversalSearch(search, search.length > 0);
  const [isFilterVisible, setIsFilterVisible] = useState(false);
  const [tilesType, setTilesType] = useState({ label: 'NM regions', value: 0 });
  const tilesTypes = [
    { label: 'NM regions', value: 0 },
    { label: 'UN countries', value: 1 },
    { label: 'DARE places', value: 2 }
  ];
  const [type, setType] = useState(0);
  const [visitedTiles, setVisitedTiles] = useState(visitedDefaultTiles);
  const [seriesFilter, setSeriesFilter] = useState<any>({
    visible: true,
    groups: [],
    applied: false,
    status: -1
  });

  const { handleUpdateNM, handleUpdateDare, handleUpdateSlow, userData, setUserData } = useRegion();
  const userInfo = storage.get('currentUserData', StoreType.STRING) as string;
  const [userInfoData, setUserInfoData] = useState<any>(null);

  useFocusEffect(
    useCallback(() => {
      const updateMarkers = async () => {
        await mutateAsync(
          { regions: JSON.stringify([regionData?.id]), token: String(token) },
          {
            onSuccess: (data) => {
              setSeries(data.series);

              const allMarkers = data.items.map(processMarkerData);
              setProcessedMarkers(allMarkers);
              setMarkers(allMarkers);
            }
          }
        );
      };

      if (userData && userData?.type === 'nm') {
        updateMarkers();
      }
    }, [userData])
  );

  useEffect(() => {
    if (route.params?.id && route.params?.type && dareData) {
      handleFindRegion(route.params?.id, route.params?.type);
    }
  }, [route, dareData]);

  useEffect(() => {
    if (userInfo) {
      setUserInfoData(JSON.parse(userInfo));
    }
  }, [userInfo]);

  useEffect(() => {
    if (!dareData) {
      const fetchData = async () => {
        const fetchedData = await fetchJsonData();
        setDareData(fetchedData);
      };

      fetchData();
    }
  }, [dareData]);

  const handleModalStateChange = (updates: { [key: string]: any }) => {
    setModalState((prevState) => ({ ...prevState, ...updates }));
  };

  const handleOpenEditModal = () => {
    handleModalStateChange({
      selectedFirstYear: userData?.first_visit_year,
      selectedLastYear: userData?.last_visit_year,
      selectedQuality:
        qualityOptions.find((quality) => quality.id === userData?.best_visit_quality) ||
        qualityOptions[2],
      selectedNoOfVisits: userData?.no_of_visits || 1,
      id: regionData?.id
    });
    setIsEditModalVisible(true);
  };

  useEffect(() => {
    const currentYear = moment().year();
    let yearSelector: { label: string; value: number }[] = [{ label: 'visited', value: 1 }];
    for (let i = currentYear; i >= 1951; i--) {
      yearSelector.push({ label: i.toString(), value: i });
    }
    handleModalStateChange({ years: yearSelector });
  }, []);

  const cancelTokenRef = useRef(false);
  const currentTokenRef = useRef(0);
  const strokeWidthAnim = useRef(new Animation.Value(2)).current;

  const [isExpanded, setIsExpanded] = useState(false);
  const [searchVisible, setSearchVisible] = useState(false);
  const [index, setIndex] = useState<number>(0);
  const width = useSharedValue(48);
  const usableWidth = Dimensions.get('window').width - 32;

  useEffect(() => {
    if (netInfo?.isInternetReachable) {
      setIsConnected(true);
    } else {
      setIsConnected(false);
    }
  }, [netInfo?.isInternetReachable]);

  useEffect(() => {
    Animation.loop(
      Animation.sequence([
        Animation.timing(strokeWidthAnim, {
          toValue: 3,
          duration: 700,
          useNativeDriver: false
        }),
        Animation.timing(strokeWidthAnim, {
          toValue: 2,
          duration: 700,
          useNativeDriver: false
        })
      ])
    ).start();
  }, [strokeWidthAnim]);

  useFocusEffect(
    useCallback(() => {
      navigation.getParent()?.setOptions({
        tabBarStyle: {
          display: regionPopupVisible ? 'none' : 'flex',
          position: 'absolute',
          ...Platform.select({
            android: {
              height: 58
            }
          })
        }
      });
    }, [regionPopupVisible, navigation])
  );

  useEffect(() => {
    (async () => {
      let { status } = await Location.getForegroundPermissionsAsync();
      if (status !== 'granted') {
        return;
      }

      let currentLocation = await Location.getCurrentPositionAsync({});
      setLocation(currentLocation.coords);
    })();
  }, []);

  const findFeaturesInVisibleMapArea = async (visibleMapArea: {
    latitude?: any;
    longitude?: any;
    latitudeDelta: any;
    longitudeDelta?: any;
  }) => {
    if (!isConnected) return;
    const currentZoom = Math.log2(360 / visibleMapArea.latitudeDelta);
    setZoomLevel(currentZoom);

    if (cancelTokenRef.current) {
      setMarkers(processedMarkers);
      return;
    }
    const thisToken = ++currentTokenRef.current;

    if (!regions || !dareData) return;

    if (currentZoom < 7) {
      setMarkers([]);

      return;
    }

    const { latitude, longitude, latitudeDelta, longitudeDelta } = visibleMapArea;
    const bbox: turf.BBox = [
      longitude - longitudeDelta / 2,
      latitude - latitudeDelta / 2,
      longitude + longitudeDelta / 2,
      latitude + latitudeDelta / 2
    ];
    const visibleAreaPolygon = turf.bboxPolygon(bbox);
    const regionsFound = filterCandidates(regions, bbox);
    // const daresFound = filterCandidates(dareRegions, bbox);

    const regionIds = regionsFound.map(
      (region: { properties: { id: any } }) => region.properties.id
    );

    isConnected &&
      (await mutateAsync(
        { regions: JSON.stringify(regionIds), token: String(token) },
        {
          onSuccess: (data) => {
            if (thisToken !== currentTokenRef.current) return;

            setSeries(data.series);

            const markersVisible = filterCandidatesMarkers(data.items, visibleAreaPolygon);
            const allMarkers = markersVisible.map(processMarkerData);
            setMarkers(allMarkers);
          }
        }
      ));
  };

  const handleGetLocation = async () => {
    let { status, canAskAgain } = await Location.getForegroundPermissionsAsync();

    if (status === 'granted') {
      getLocation();
    } else if (!canAskAgain) {
      setOpenSettingsVisible(true);
    } else {
      setAskLocationVisible(true);
    }
  };

  const getLocation = async () => {
    let currentLocation = await Location.getCurrentPositionAsync({
      accuracy: Location.Accuracy.Balanced
    });
    setLocation(currentLocation.coords);

    mapRef.current?.animateToRegion(
      {
        latitude: currentLocation.coords.latitude,
        longitude: currentLocation.coords.longitude,
        latitudeDelta: 5,
        longitudeDelta: 5
      },
      800
    );

    handleClosePopup();
  };

  const handleAcceptPermission = async () => {
    setAskLocationVisible(false);
    let { status, canAskAgain } = await Location.requestForegroundPermissionsAsync();

    if (status === 'granted') {
      getLocation();
    } else if (!canAskAgain) {
      setOpenSettingsVisible(true);
    }
  };

  const handleRegionData = (regionData: Region, avatars: string[]) => {
    setRegionData(regionData);
    setUserAvatars(avatars);
  };

  const handleMapPress = async (event: {
    nativeEvent: { coordinate: { latitude: any; longitude: any }; action?: string };
  }) => {
    if (event.nativeEvent?.action === 'marker-press') return;

    cancelTokenRef.current = true;
    const { latitude, longitude } = event.nativeEvent.coordinate;
    const point = turf.point([longitude, latitude]);

    let db = getSecondDatabase();
    let tableName = 'places';
    let foundRegion: any;

    type !== 1 && (foundRegion = findRegionInDataset(dareData, point));

    if (type === 1) {
      foundRegion = findRegionInDataset(regions, point);
      db = getFirstDatabase();
      tableName = 'regions';

      if (foundRegion) {
        const countryId = foundRegion.properties?.country_id;

        if (countryId) {
          if (countryId === regionData?.id) return;

          setSelectedRegion(null);
          setMarkers([]);
          setProcessedMarkers([]);

          db = getCountriesDatabase();
          tableName = 'countries';

          await getData(db, countryId, tableName, handleRegionData)
            .then(() => {
              setRegionPopupVisible(true);
            })
            .catch((error) => {
              console.error('Error fetching data', error);
              refreshDatabases();
            });

          await mutateCountriesData(
            { id: +countryId, token },
            {
              onSuccess: (data) => {
                setUserData({ type: 'countries', ...data.data });
                const bounds = turf.bbox(data.data.bbox);
                const center = data.data.center;
                const region = calculateMapCountry(bounds, center);

                mapRef.current?.animateToRegion(region, 1000);
              }
            }
          );

          return;
        }
      }
    }

    if (!foundRegion) {
      foundRegion = findRegionInDataset(regions, point);
      db = getFirstDatabase();
      tableName = 'regions';
    }

    if (foundRegion) {
      if (foundRegion.properties?.id === regionData?.id) return;
      const id = foundRegion.properties?.id;

      setSelectedRegion({
        type: 'FeatureCollection',
        features: [
          {
            geometry: foundRegion.geometry,
            properties: {
              ...foundRegion.properties,
              fill: 'rgba(57, 115, 172, 0.2)',
              stroke: '#3973AC'
            },
            type: 'Feature'
          }
        ]
      });

      await getData(db, id, tableName, handleRegionData)
        .then(() => {
          setRegionPopupVisible(true);
        })
        .catch((error) => {
          console.error('Error fetching data', error);
          refreshDatabases();
        });

      const bounds = turf.bbox(foundRegion);
      const region = calculateMapRegion(bounds);

      zoomLevel < 7 && mapRef.current?.animateToRegion(region, 1000);

      if (tableName === 'regions') {
        await mutateUserData(
          { region_id: +id, token: String(token) },
          {
            onSuccess: (data) => {
              setUserData({ type: 'nm', ...data });
            }
          }
        );
        await mutateAsync(
          { regions: JSON.stringify([id]), token: String(token) },
          {
            onSuccess: (data) => {
              setSeries(data.series);

              const allMarkers = data.items.map(processMarkerData);
              setProcessedMarkers(allMarkers);
            }
          }
        );
      } else {
        await mutateUserDataDare(
          { dare_id: +id, token: String(token) },
          {
            onSuccess: (data) => {
              setUserData({ type: 'dare', ...data });
            }
          }
        );
        setProcessedMarkers([]);
      }
    } else {
      handleClosePopup();
    }
  };

  const handleFindRegion = async (id: number, type: string) => {
    cancelTokenRef.current = true;
    const db = type === 'regions' ? getFirstDatabase() : getSecondDatabase();
    const dataset = type === 'regions' ? regions : dareData;

    const foundRegion = dataset.features.find((region: any) => region.properties.id === id);

    if (foundRegion) {
      setSelectedRegion({
        type: 'FeatureCollection',
        features: [
          {
            geometry: foundRegion.geometry,
            properties: {
              ...foundRegion.properties,
              fill: 'rgba(57, 115, 172, 0.2)',
              stroke: '#3973AC'
            },
            type: 'Feature'
          }
        ]
      });

      await getData(db, id, type, handleRegionData)
        .then(() => {
          setRegionPopupVisible(true);
        })
        .catch((error) => {
          console.error('Error fetching data', error);
          refreshDatabases();
        });

      const bounds = turf.bbox(foundRegion);
      const region = calculateMapRegion(bounds);

      mapRef.current?.animateToRegion(region, 1000);

      if (type === 'regions') {
        await mutateUserData(
          { region_id: +id, token: String(token) },
          {
            onSuccess: (data) => {
              setUserData({ type: 'nm', ...data });
            }
          }
        );
        await mutateAsync(
          { regions: JSON.stringify([id]), token: String(token) },
          {
            onSuccess: (data) => {
              setSeries(data.series);

              const allMarkers = data.items.map(processMarkerData);
              setProcessedMarkers(allMarkers);
              setMarkers(allMarkers);
            }
          }
        );
      } else {
        await mutateUserDataDare(
          { dare_id: +id, token: String(token) },
          {
            onSuccess: (data) => {
              setUserData({ type: 'dare', ...data });
            }
          }
        );
        setProcessedMarkers([]);
        setMarkers([]);
      }
    } else {
      handleClosePopup();
    }
  };

  const renderMapTiles = (url: string, cacheDir: string, zIndex: number, opacity = 1) => (
    <UrlTile
      key={`${url}-${cacheDir}-${zoomLevel > 6 ? 0 : 1}`}
      urlTemplate={url === tilesBaseURL && zoomLevel > 13 ? openstreetmapUrl : `${url}/{z}/{x}/{y}`}
      maximumZ={18}
      maximumNativeZ={url === tilesBaseURL ? 18 : 13}
      tileCachePath={cacheDir !== localVisitedDir && zoomLevel < 8 ? `${cacheDir}` : undefined}
      shouldReplaceMapContent
      minimumZ={0}
      offlineMode={!isConnected}
      opacity={opacity}
      zIndex={zIndex}
    />
  );

  function renderGeoJSON() {
    if (!selectedRegion) return null;

    return (
      <Geojson
        geojson={selectedRegion as any}
        fillColor="rgba(57, 115, 172, 0.2)"
        strokeColor="#3973ac"
        strokeWidth={Platform.OS == 'android' ? 3 : 2}
        zIndex={3}
      />
    );
  }

  const handleClosePopup = async () => {
    cancelTokenRef.current = false;

    setRegionPopupVisible(false);
    setMarkers([]);
    setSelectedRegion(null);
    setRegionData(null);
    const boundaries = await mapRef.current?.getMapBoundaries();
    const { northEast, southWest } = boundaries || {};

    const latitudeDelta = (northEast?.latitude ?? 0) - (southWest?.latitude ?? 0);
    const longitudeDelta = (northEast?.longitude ?? 0) - (southWest?.longitude ?? 0);
    const latitude = (southWest?.latitude ?? 0) + latitudeDelta / 2;
    const longitude = (southWest?.longitude ?? 0) + longitudeDelta / 2;

    findFeaturesInVisibleMapArea({ latitude, longitude, latitudeDelta, longitudeDelta });
  };

  const renderedGeoJSON = useMemo(() => renderGeoJSON(), [selectedRegion]);

  const toggleSeries = useCallback(
    async (item: any) => {
      if (!token) {
        setIsWarningModalVisible(true);
        return;
      }

      setMarkers((currentMarkers) =>
        currentMarkers.map((marker) =>
          marker.id === item.id ? { ...marker, visited: Number(!marker.visited) as 0 | 1 } : marker
        )
      );
      setProcessedMarkers((currentMarkers) =>
        currentMarkers.map((marker) =>
          marker.id === item.id ? { ...marker, visited: Number(!marker.visited) as 0 | 1 } : marker
        )
      );

      const itemData = {
        token: token,
        series_id: item.series_id,
        item_id: item.id,
        checked: (!item.visited ? 1 : 0) as 0 | 1,
        double: 0 as 0 | 1
      };

      try {
        updateSeriesItem(itemData);
      } catch (error) {
        console.error('Failed to update series state', error);
      }
    },
    [token, updateSeriesItem]
  );

  const renderMarkers = () => {
    let filteredMarkers = markers;

    if (seriesFilter.applied) {
      filteredMarkers = filteredMarkers.filter((marker) =>
        seriesFilter.groups.includes(marker.series_id)
      );
      if (seriesFilter.status !== -1) {
        filteredMarkers = filteredMarkers.filter(
          (marker) => marker.visited === seriesFilter.status
        );
      }
    }

    return filteredMarkers.map((marker, idx) => {
      const coordinate = { latitude: marker.pointJSON[0], longitude: marker.pointJSON[1] };
      const markerSeries = series?.find((s) => s.id === marker.series_id);
      const iconUrl = markerSeries ? API_HOST + markerSeries.icon : 'default_icon_url';
      const seriesName = markerSeries ? markerSeries.name : 'Unknown';

      return (
        <MarkerItem
          marker={marker}
          iconUrl={iconUrl}
          key={`${idx} - ${marker.id}`}
          coordinate={coordinate}
          seriesName={seriesName}
          toggleSeries={toggleSeries}
          token={token}
        />
      );
    });
  };

  const handlePress = () => {
    if (isExpanded) {
      setIndex(0);
      setSearchInput('');
    }
    setIsExpanded((prev) => !prev);
    width.value = withTiming(isExpanded ? 48 : usableWidth, {
      duration: 300,
      easing: Easing.inOut(Easing.ease)
    });
  };

  const animatedStyle = useAnimatedStyle(() => {
    return {
      width: width.value
    };
  });

  const handleSearch = async () => {
    setSearch(searchInput);
    setSearchVisible(true);
  };

  const handleCloseModal = () => {
    setSearchInput('');
    setSearchVisible(false);
    handlePress();
  };

  const handleOpenEditSlowModal = () => {
    setIsEditSlowModalVisible(true);
  };

  return (
    <View style={styles.container}>
      <ClusteredMapView
        initialRegion={{
          latitude: 0,
          longitude: 0,
          latitudeDelta: 180,
          longitudeDelta: 180
        }}
        ref={mapRef}
        showsMyLocationButton={false}
        showsCompass={false}
        zoomControlEnabled={false}
        onPress={handleMapPress}
        style={styles.map}
        mapType={Platform.OS == 'android' ? 'none' : 'standard'}
        maxZoomLevel={17}
        minZoomLevel={0}
        onRegionChangeComplete={findFeaturesInVisibleMapArea}
        minPoints={zoomLevel < 7 ? 0 : 12}
        tracksViewChanges={false}
        renderCluster={(cluster) => <ClusterItem key={cluster.id} cluster={cluster} />}
      >
        {renderedGeoJSON}
        {renderMapTiles(tilesBaseURL, localTileDir, 1)}
        {type !== 1 && renderMapTiles(gridUrl, localGridDir, 2)}
        {userId && renderMapTiles(visitedTiles, localVisitedDir, 3, 0.5)}
        {renderMapTiles(dareTiles, localDareDir, 2, 0.5)}
        {location && (
          <AnimatedMarker coordinate={location} anchor={{ x: 0.5, y: 0.5 }}>
            <Animation.View style={[styles.location, { borderWidth: strokeWidthAnim }]} />
          </AnimatedMarker>
        )}
        {markers && seriesFilter.visible && renderMarkers()}
      </ClusteredMapView>

      <LocationPopup
        visible={askLocationVisible}
        onClose={() => setAskLocationVisible(false)}
        onAccept={handleAcceptPermission}
        modalText="To use this feature we need your permission to access your location. If you press OK your system will ask you to approve location sharing with NomadMania app."
      />
      <LocationPopup
        visible={openSettingsVisible}
        onClose={() => setOpenSettingsVisible(false)}
        onAccept={() =>
          Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings()
        }
        modalText="NomadMania app needs location permissions to function properly. Open settings?"
      />

      {regionPopupVisible && regionData ? (
        <>
          <TouchableOpacity
            style={[styles.cornerButton, styles.topLeftButton, styles.closeLeftButton]}
            onPress={handleClosePopup}
          >
            <CloseSvg fill="white" width={13} height={13} />
            <Text style={styles.textClose}>Close</Text>
          </TouchableOpacity>

          <TouchableOpacity
            onPress={handleGetLocation}
            style={[styles.cornerButton, styles.topRightButton, styles.bottomButton]}
          >
            <LocationIcon />
          </TouchableOpacity>

          <RegionPopup
            region={regionData}
            userAvatars={userAvatars}
            userData={userData}
            openEditModal={handleOpenEditModal}
            updateNM={(id, first, last, visits, quality) => {
              if (!token) {
                setIsWarningModalVisible(true);
                return;
              }
              handleUpdateNM(id, first, last, visits, quality);
            }}
            updateDare={(id, visits) => {
              if (!token) {
                setIsWarningModalVisible(true);
                return;
              }
              handleUpdateDare(id, visits);
            }}
            disabled={!token || !isConnected}
            updateSlow={handleUpdateSlow}
            openEditSlowModal={handleOpenEditSlowModal}
          />
        </>
      ) : (
        <>
          {!isExpanded ? (
            <TouchableOpacity
              style={[styles.cornerButton, styles.topRightButton]}
              onPress={() => navigation.navigate(NAVIGATION_PAGES.PROFILE_TAB)}
            >
              {token ? (
                userInfoData?.avatar ? (
                  <Image
                    style={styles.avatar}
                    source={{ uri: API_HOST + '/img/avatars/' + userInfoData?.avatar }}
                  />
                ) : (
                  <AvatarWithInitials
                    text={`${userInfoData?.first_name[0] ?? ''}${userInfoData?.last_name[0] ?? ''}`}
                    flag={API_HOST + '/img/flags_new/' + userInfoData?.homebase_flag}
                    size={48}
                    borderColor={Colors.WHITE}
                  />
                )
              ) : (
                <ProfileIcon fill={Colors.DARK_BLUE} />
              )}
            </TouchableOpacity>
          ) : null}

          <Animated.View
            style={[
              styles.searchContainer,
              styles.cornerButton,
              styles.topLeftButton,
              animatedStyle,
              { padding: 5 }
            ]}
          >
            {isExpanded ? (
              <>
                <TouchableOpacity onPress={handlePress} style={styles.iconButton}>
                  <CloseSvg fill={'#0F3F4F'} />
                </TouchableOpacity>
                <TextInput
                  style={styles.input}
                  placeholder="Search regions, places, nomads"
                  placeholderTextColor={Colors.LIGHT_GRAY}
                  value={searchInput}
                  onChangeText={(text) => setSearchInput(text)}
                  onSubmitEditing={handleSearch}
                />
                <TouchableOpacity onPress={handleSearch} style={styles.iconButton}>
                  <SearchIcon fill={'#0F3F4F'} />
                </TouchableOpacity>
              </>
            ) : (
              <TouchableOpacity onPress={handlePress} style={[styles.iconButton]}>
                <SearchIcon fill={'#0F3F4F'} />
              </TouchableOpacity>
            )}
          </Animated.View>

          <TouchableOpacity
            style={[styles.cornerButton, styles.bottomButton, styles.bottomLeftButton]}
            onPress={() => {
              token ? setIsFilterVisible(true) : setIsWarningModalVisible(true);
            }}
          >
            <FilterIcon />
          </TouchableOpacity>

          <TouchableOpacity
            onPress={handleGetLocation}
            style={[styles.cornerButton, styles.bottomButton, styles.bottomRightButton]}
          >
            <LocationIcon />
          </TouchableOpacity>
        </>
      )}
      <WarningModal
        type={'unauthorized'}
        isVisible={isWarningModalVisible}
        onClose={() => setIsWarningModalVisible(false)}
      />
      <EditNmModal
        isVisible={isEditModalVisible}
        onClose={() => setIsEditModalVisible(false)}
        modalState={modalState}
        updateModalState={handleModalStateChange}
        updateNM={handleUpdateNM}
      />
      <SearchModal
        searchVisible={searchVisible}
        handleCloseModal={handleCloseModal}
        handleFindRegion={handleFindRegion}
        index={index}
        searchData={searchData}
        setIndex={setIndex}
        token={token}
      />
      <FilterModal
        isFilterVisible={isFilterVisible}
        setIsFilterVisible={setIsFilterVisible}
        tilesTypes={tilesTypes}
        tilesType={tilesType}
        setTilesType={setTilesType}
        type={type}
        setType={setType}
        userId={userId ? +userId : 0}
        setVisitedTiles={setVisitedTiles}
        setSeriesFilter={setSeriesFilter}
        isPublicView={false}
      />
      <EditModal
        isVisible={isEditSlowModalVisible}
        onClose={() => setIsEditSlowModalVisible(false)}
        item={{ ...userData, country_id: regionData?.id }}
        updateSlow={(id, v, s11, s31, s101) => handleUpdateSlow(id, v, s11, s31, s101)}
      />
    </View>
  );
};

export default MapScreen;
