import {
  Dimensions,
  Linking,
  Platform,
  Text,
  TextInput,
  TouchableOpacity,
  View,
  Image,
  StatusBar,
  ActivityIndicator,
  ScrollView
} from 'react-native';
import React, { useEffect, useRef, useState, useCallback } from 'react';

import * as MapLibreRN from '@maplibre/maplibre-react-native';
import { styles } from './style';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Colors } from 'src/theme';
import { storage, StoreType } from 'src/storage';
import * as turf from '@turf/turf';
import * as Location from 'expo-location';
import { Image as ExpoImage } from 'expo-image';

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 RegionPopup from 'src/components/RegionPopup';
import { useRegion } from 'src/contexts/RegionContext';
import { qualityOptions } from '../TravelsScreen/utils/constants';
import { AvatarWithInitials, EditNmModal, WarningModal } from 'src/components';
import { API_HOST, VECTOR_MAP_HOST } from 'src/constants';
import { NAVIGATION_PAGES } from 'src/types';
import Animated, {
  Easing,
  useAnimatedStyle,
  useSharedValue,
  withTiming
} from 'react-native-reanimated';
import { getData } from 'src/modules/map/regionData';
import {
  getCountriesDatabase,
  getFirstDatabase,
  getSecondDatabase,
  refreshDatabases
} from 'src/db';
import { fetchUserData, fetchUserDataDare, useGetListRegionsQuery } from '@api/regions';
import { SQLiteDatabase } from 'expo-sqlite/legacy';
import { useFocusEffect } from '@react-navigation/native';
import { useGetUniversalSearch } from '@api/search';
import { fetchCountryUserData, useGetListCountriesQuery } from '@api/countries';
import SearchModal from './UniversalSearch';
import EditModal from '../TravelsScreen/Components/EditSlowModal';
import * as FileSystem from 'expo-file-system';

import CheckSvg from 'assets/icons/mark.svg';
import moment from 'moment';
import {
  usePostGetVisitedCountriesIdsQuery,
  usePostGetVisitedDareIdsQuery,
  usePostGetVisitedRegionsIdsQuery,
  usePostGetVisitedSeriesIdsQuery
} from '@api/maps';
import FilterModal from './FilterModal';
import { useGetListDareQuery } from '@api/myDARE';
import { useGetIconsQuery, usePostSetToggleItem } from '@api/series';
import MarkerItem from './MarkerItem';
import {
  usePostGetSettingsQuery,
  usePostGetUsersCountQuery,
  usePostGetUsersLocationQuery,
  usePostUpdateLocationMutation
} from '@api/location';
import UserItem from './UserItem';
import { useConnection } from 'src/contexts/ConnectionContext';

import TravelsIcon from 'assets/icons/bottom-navigation/globe-solid.svg';
import SeriesIcon from 'assets/icons/travels-section/series.svg';
import NomadsIcon from 'assets/icons/bottom-navigation/travellers.svg';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
import MapButton from 'src/components/MapButton';
import { useAvatarStore } from 'src/stores/avatarVersionStore';
import _ from 'lodash';
import ScaleBar from 'src/components/ScaleBar';
import MessagesDot from 'src/components/MessagesDot';
import {
  restartBackgroundLocationUpdates,
  startBackgroundLocationUpdates,
  stopBackgroundLocationUpdates
} from 'src/utils/backgroundLocation';

const clusteredUsersIcon = require('assets/icons/icon-clustered-users.png');
const defaultUserAvatar = require('assets/icon-user-share-location-solid.png');
const logo = require('assets/logo-ua.png');
const defaultSeriesIcon = require('assets/series-default.png');

MapLibreRN.Logger.setLogLevel('error');

const generateFilter = (ids: number[]) => {
  return ids?.length ? ['any', ...ids.map((id) => ['==', 'id', id])] : ['==', 'id', -1];
};

// to do refactor
let regions_visited = {
  id: 'regions_visited',
  type: 'fill',
  source: 'regions',
  'source-layer': 'regions',
  style: {
    fillColor: 'rgba(255, 126, 0, 1)',
    fillOpacity: 0.6,
    fillOutlineColor: 'rgba(14, 80, 109, 0)'
  },
  filter: generateFilter([]),
  maxzoom: 10
};

let countries_visited = {
  id: 'countries_visited',
  type: 'fill',
  source: 'countries',
  'source-layer': 'countries',
  style: {
    fillColor: 'rgba(255, 126, 0, 1)',
    fillOpacity: 0.6,
    fillOutlineColor: 'rgba(14, 80, 109, 0)'
  },
  filter: generateFilter([]),
  maxzoom: 10
};

let dare_visited = {
  id: 'dare_visited',
  type: 'fill',
  source: 'dare',
  'source-layer': 'dare',
  style: {
    fillColor: 'rgba(255, 126, 0, 0.6)',
    fillOutlineColor: 'rgba(255, 126, 0, 0)'
  },
  filter: generateFilter([]),
  maxzoom: 12
};

let regions = {
  id: 'regions',
  type: 'fill',
  source: 'regions',
  'source-layer': 'regions',
  style: {
    fillColor: 'rgba(15, 63, 79, 0)',
    fillOutlineColor: 'rgba(14, 80, 109, 0)'
  },
  filter: ['all'],
  maxzoom: 16
};

let countries = {
  id: 'countries',
  type: 'fill',
  source: 'countries',
  'source-layer': 'countries',
  style: {
    fillColor: 'rgba(15, 63, 79, 0)',
    fillOutlineColor: 'rgba(14, 80, 109, 0)'
  },
  filter: ['all'],
  maxzoom: 16
};

let dare = {
  id: 'dare',
  type: 'fill',
  source: 'dare',
  'source-layer': 'dare',
  style: {
    fillColor: 'rgba(14, 80, 109, 0.6)',
    fillOutlineColor: 'rgba(14, 80, 109, 0)'
  },
  filter: ['all'],
  maxzoom: 16
};

let selected_region = {
  id: 'selected_region',
  type: 'fill',
  source: 'regions',
  'source-layer': 'regions',
  style: {
    fillColor: 'rgba(57, 115, 172, 0.3)'
  },
  maxzoom: 12
};

let selected_region_outline = {
  id: 'selected_region_outline',
  type: 'line',
  source: 'regions',
  'source-layer': 'regions',
  style: {
    lineColor: '#ED9334',
    lineTranslate: [0, 0],
    lineTranslateAnchor: 'map',
    lineWidth: ['interpolate', ['linear'], ['zoom'], 0, 2, 4, 3, 5, 4, 12, 5]
  },
  maxzoom: 12
};

let series_layer = {
  id: 'series_layer',
  type: 'symbol',
  source: 'nomadmania_series',
  'source-layer': 'series',
  minzoom: 6,
  maxzoom: 60,
  layout: {
    'symbol-spacing': 1,
    'icon-image': '{series_id}',
    'icon-size': 0.15,
    'icon-allow-overlap': true,
    'icon-ignore-placement': true,
    'text-anchor': 'top',
    'text-field': '{name}',
    'text-font': ['Noto Sans Regular'],
    'text-max-width': 9,
    'text-offset': [0, 0.6],
    'text-padding': 2,
    'text-size': 12,
    visibility: 'visible',
    'text-optional': true,
    'text-ignore-placement': false,
    'text-allow-overlap': false
  },
  paint: {
    'text-color': '#666',
    'text-halo-blur': 0.5,
    'text-halo-color': '#ffffff',
    'text-halo-width': 1
  },
  filter: generateFilter([])
};

let series_visited = {
  id: 'series_visited',
  type: 'symbol',
  source: 'nomadmania_series',
  'source-layer': 'series',
  minzoom: 6,
  maxzoom: 60,
  layout: {
    'symbol-spacing': 1,
    'icon-image': '{series_id}v',
    'icon-size': 0.15,
    'icon-allow-overlap': true,
    'icon-ignore-placement': true,
    'text-anchor': 'top',
    'text-field': '{name}',
    'text-font': ['Noto Sans Regular'],
    'text-max-width': 9,
    'text-offset': [0, 0.6],
    'text-padding': 2,
    'text-size': 12,
    visibility: 'visible',
    'text-optional': true,
    'text-ignore-placement': false,
    'text-allow-overlap': false
  },
  paint: {
    'text-color': '#666',
    'text-halo-blur': 0.5,
    'text-halo-color': '#ffffff',
    'text-halo-width': 1
  },
  filter: generateFilter([])
};

const INITIAL_REGION = {
  latitude: 0,
  longitude: 0,
  latitudeDelta: 180,
  longitudeDelta: 180
};

const ICONS_DIR = FileSystem.documentDirectory + 'series_icons/';

const MapScreen: any = ({ navigation, route }: { navigation: any; route: any }) => {
  const tabBarHeight = useBottomTabBarHeight();
  const userId = storage.get('uid', StoreType.STRING) as string;
  const token = storage.get('token', StoreType.STRING) as string;

  const [isConnected, setIsConnected] = useState<boolean>(true);
  const netInfo = useConnection();
  const { avatarVersion } = useAvatarStore();

  const { data: usersOnMapCount } = usePostGetUsersCountQuery(token, !!token && isConnected);
  const { data: regionsList } = useGetListRegionsQuery(isConnected);
  const { data: countriesList } = useGetListCountriesQuery(isConnected);
  const { data: dareList } = useGetListDareQuery(isConnected);

  const [tilesType, setTilesType] = useState({ label: 'NM regions', value: 0 });
  const tilesTypes = [
    { label: 'Blank', value: -1 },
    { label: 'NM regions', value: 0 },
    { label: 'UN countries', value: 1 },
    { label: 'DARE places', value: 2 }
  ];
  const [type, setType] = useState<'regions' | 'countries' | 'dare' | 'blank'>('regions');
  const [seriesFilter, setSeriesFilter] = useState<any>({
    visible: true,
    groups: [],
    applied: false,
    status: -1
  });
  const [regionsFilter, setRegionsFilter] = useState<any>({
    visitedLabel: 'by',
    year: moment().year()
  });
  const [showNomads, setShowNomads] = useState(
    (storage.get('showNomads', StoreType.BOOLEAN) as boolean) ?? false
  );
  const { data: locationSettings, refetch } = usePostGetSettingsQuery(
    token,
    !!token && isConnected
  );
  const { mutateAsync: updateLocation } = usePostUpdateLocationMutation();
  const { data: visitedRegionIds, refetch: refetchVisitedRegions } =
    usePostGetVisitedRegionsIdsQuery(
      token,
      regionsFilter.visitedLabel,
      regionsFilter.year,
      +userId,
      type === 'regions' && !!userId && isConnected
    );
  const { data: visitedCountryIds, refetch: refetchVisitedCountries } =
    usePostGetVisitedCountriesIdsQuery(
      token,
      regionsFilter.visitedLabel,
      regionsFilter.year,
      +userId,
      type === 'countries' && !!userId && isConnected
    );
  const { data: visitedDareIds, refetch: refetchVisitedDare } = usePostGetVisitedDareIdsQuery(
    token,
    +userId,
    type === 'dare' && !!userId && isConnected
  );
  const { data: visitedSeriesIds } = usePostGetVisitedSeriesIdsQuery(
    token,
    !!userId && isConnected
  );
  const { data: seriesIcons } = useGetIconsQuery(isConnected);
  const userInfo = storage.get('currentUserData', StoreType.STRING) as string;
  const { mutateAsync: mutateUserData } = fetchUserData();
  const { mutateAsync: mutateUserDataDare } = fetchUserDataDare();
  const { mutateAsync: mutateCountriesData } = fetchCountryUserData();

  const [selectedRegion, setSelectedRegion] = useState<number | null>(null);
  const [initialRegion, setInitialRegion] = useState(INITIAL_REGION);
  const [regionPopupVisible, setRegionPopupVisible] = useState<boolean | null>(false);
  const [regionData, setRegionData] = useState<any | null>(null);
  const [location, setLocation] = useState<any | null>(null);
  const [userAvatars, setUserAvatars] = useState<string[]>([]);
  const [userInfoData, setUserInfoData] = useState<any>(null);
  const [selectedMarker, setSelectedMarker] = useState<any>(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 [isEditModalVisible, setIsEditModalVisible] = useState(false);
  const [isFilterVisible, setIsFilterVisible] = useState<string | null>(null);
  const [isLocationLoading, setIsLocationLoading] = useState(false);

  const [modalState, setModalState] = useState({
    selectedFirstYear: 2021,
    selectedLastYear: 2021,
    selectedQuality: qualityOptions[2],
    selectedNoOfVisits: 1,
    years: [],
    id: null
  });

  const [isExpanded, setIsExpanded] = useState(false);
  const [search, setSearch] = useState('');
  const { data: searchData } = useGetUniversalSearch(search, search.length > 0);
  const [searchInput, setSearchInput] = useState('');
  const [searchVisible, setSearchVisible] = useState<boolean>(false);
  const [index, setIndex] = useState<number>(0);
  const width = useSharedValue(48);
  const usableWidth = Dimensions.get('window').width - 32;

  const { handleUpdateNM, handleUpdateDare, handleUpdateSlow, userData, setUserData } = useRegion();

  const [db1, setDb1] = useState<SQLiteDatabase | null>(null);
  const [db2, setDb2] = useState<SQLiteDatabase | null>(null);
  const [db3, setDb3] = useState<SQLiteDatabase | null>(null);

  const [regionsVisitedFilter, setRegionsVisitedFilter] = useState(generateFilter([]));
  const [countriesVisitedFilter, setCountriesVisitedFilter] = useState(generateFilter([]));
  const [dareVisitedFilter, setDareVisitedFilter] = useState(generateFilter([]));
  const [seriesVisitedFilter, setSeriesVisitedFilter] = useState(generateFilter([]));
  const [seriesNotVisitedFilter, setSeriesNotVisitedFilter] = useState(generateFilter([]));
  const [regionsVisited, setRegionsVisited] = useState<any[]>([]);
  const [countriesVisited, setCountriesVisited] = useState<any[]>([]);
  const [dareVisited, setDareVisited] = useState<any[]>([]);
  const [seriesVisited, setSeriesVisited] = useState<any[]>([]);
  const [images, setImages] = useState<any>({});
  const { mutateAsync: updateSeriesItem } = usePostSetToggleItem();
  const [nomads, setNomads] = useState<GeoJSON.FeatureCollection | null>(null);
  const { data: usersLocation, refetch: refetchUsersLocation } = usePostGetUsersLocationQuery(
    token,
    !!token && showNomads && Boolean(location) && isConnected
  );
  const [selectedUser, setSelectedUser] = useState<any>(null);
  const [zoom, setZoom] = useState(0);
  const [center, setCenter] = useState<number[] | null>(null);
  const [isZooming, setIsZooming] = useState(true);
  const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const [markerCoords, setMarkerCoords] = useState<any>(null);
  const [interval, setInterval] = useState(0);

  const isSmallScreen = Dimensions.get('window').width < 383;
  const processedImages = useRef(new Set<string>());

  useEffect(() => {
    if (netInfo && netInfo.isConnected !== null) {
      setIsConnected(netInfo.isConnected);
    }
  }, [netInfo]);

  useEffect(() => {
    if (showNomads) {
      refetchUsersLocation();
    }
  }, [showNomads]);

  useEffect(() => {
    if (usersLocation && usersLocation.geojson && showNomads) {
      const filteredNomads: GeoJSON.FeatureCollection = {
        type: 'FeatureCollection',
        features: usersLocation.geojson.features.filter(
          (feature: GeoJSON.Feature) => feature.properties?.id !== +userId
        )
      };

      if (!nomads || JSON.stringify(filteredNomads) !== JSON.stringify(nomads)) {
        setNomads(filteredNomads);
      }
    }
  }, [usersLocation, showNomads]);

  useEffect(() => {
    const loadCachedIcons = async () => {
      try {
        const dirInfo = await FileSystem.getInfoAsync(ICONS_DIR);
        if (!dirInfo.exists) return;

        const files = await FileSystem.readDirectoryAsync(ICONS_DIR);
        const cachedImages: Record<string, { uri: string }> = {};

        files.forEach((fileName) => {
          if (!fileName.endsWith('.png')) return;

          const key = fileName.replace('.png', '');
          cachedImages[key] = {
            uri: ICONS_DIR + fileName
          };

          processedImages.current.add(key);
        });

        setImages((prev: any) => ({ ...prev, ...cachedImages }));
      } catch (e) {
        console.warn('Error loading cached icons:', e);
      }
    };

    loadCachedIcons();
  }, []);

  useEffect(() => {
    if (!seriesIcons) return;

    const updateCacheFromAPI = async () => {
      const loadedImages: Record<string, { uri: string }> = {};

      const dirInfo = await FileSystem.getInfoAsync(ICONS_DIR);
      if (!dirInfo.exists) {
        await FileSystem.makeDirectoryAsync(ICONS_DIR, { intermediates: true });
      }

      const promises = seriesIcons.data.map(async (icon) => {
        const id = icon.id?.toString();
        if (!id || processedImages.current.has(id)) return;

        const imgUrl = `${API_HOST}/static/img/series_new2_small/${icon.new_icon_png}`;
        const imgVisitedUrl = `${API_HOST}/static/img/series_new2_small/${icon.new_icon_visited_png}`;

        const localPath = `${ICONS_DIR}${id}.png`;
        const localPathVisited = `${ICONS_DIR}${id}v.png`;

        const [imgInfo, visitedInfo] = await Promise.all([
          FileSystem.getInfoAsync(localPath),
          FileSystem.getInfoAsync(localPathVisited)
        ]);

        try {
          if (!imgInfo.exists) {
            await FileSystem.downloadAsync(imgUrl, localPath);
          }
          if (!visitedInfo.exists) {
            await FileSystem.downloadAsync(imgVisitedUrl, localPathVisited);
          }
        } catch (e) {
          console.warn(`Download failed for ${id}:`, e);
          return;
        }

        processedImages.current.add(id);
        processedImages.current.add(`${id}v`);

        loadedImages[id] = { uri: localPath };
        loadedImages[`${id}v`] = { uri: localPathVisited };
      });

      await Promise.all(promises);
      setImages((prev: any) => ({ ...prev, ...loadedImages }));
    };

    updateCacheFromAPI();
  }, [seriesIcons]);

  useEffect(() => {
    const loadDatabases = async () => {
      const firstDb = await getFirstDatabase();
      const secondDb = await getSecondDatabase();
      const countriesDb = await getCountriesDatabase();

      setDb1(firstDb);
      setDb2(secondDb);
      setDb3(countriesDb);
    };

    if (!db1 || !db2 || !db3) {
      loadDatabases();
    }
  }, [db1, db2, db3]);

  useEffect(() => {
    const savedFilterSettings = storage.get('filterSettings', StoreType.STRING) as string;
    if (savedFilterSettings) {
      const filterSettings = JSON.parse(savedFilterSettings);
      setTilesType(filterSettings.tilesType);
      setType(filterSettings.type);
      setRegionsFilter({
        visitedLabel:
          filterSettings.selectedVisible?.value && filterSettings.selectedVisible.value === 1
            ? 'in'
            : 'by',
        year: filterSettings.selectedYear?.value ?? moment().year()
      });
      setSeriesFilter(filterSettings.seriesFilter);
    }
  }, []);

  useFocusEffect(
    useCallback(() => {
      if (token) {
        refetchVisitedRegions();
        refetchVisitedCountries();
        refetchVisitedDare();
      }
    }, [navigation])
  );

  // to do refactor
  useEffect(() => {
    if (visitedRegionIds) {
      setRegionsVisited(visitedRegionIds.ids);
      storage.set('visitedRegions', JSON.stringify(visitedRegionIds.ids));
    } else {
      const storedVisited = storage.get('visitedRegions', StoreType.STRING) as string;
      setRegionsVisited(storedVisited ? JSON.parse(storedVisited) : []);
    }
  }, [visitedRegionIds]);

  useEffect(() => {
    if (visitedCountryIds) {
      setCountriesVisited(visitedCountryIds.ids);
      storage.set('visitedCountries', JSON.stringify(visitedCountryIds.ids));
    } else {
      const storedVisited = storage.get('visitedCountries', StoreType.STRING) as string;
      setCountriesVisited(storedVisited ? JSON.parse(storedVisited) : []);
    }
  }, [visitedCountryIds]);

  useEffect(() => {
    if (visitedDareIds) {
      setDareVisited(visitedDareIds.ids);
      storage.set('visitedDares', JSON.stringify(visitedDareIds.ids));
    } else {
      const storedVisited = storage.get('visitedDares', StoreType.STRING) as string;
      setDareVisited(storedVisited ? JSON.parse(storedVisited) : []);
    }
  }, [visitedDareIds]);

  useEffect(() => {
    if (visitedSeriesIds && token) {
      setSeriesVisited(visitedSeriesIds.ids);
      storage.set('visitedSeries', JSON.stringify(visitedSeriesIds.ids));
    } else {
      const storedVisited = storage.get('visitedSeries', StoreType.STRING) as string;
      setSeriesVisited(storedVisited ? JSON.parse(storedVisited) : []);
    }
  }, [visitedSeriesIds]);

  useEffect(() => {
    if (regionsVisited && regionsVisited.length) {
      setRegionsVisitedFilter(generateFilter(regionsVisited));
    } else {
      setRegionsVisitedFilter(['==', 'id', -1]);
    }
  }, [regionsVisited]);

  useEffect(() => {
    if (countriesVisited && countriesVisited.length) {
      setCountriesVisitedFilter(generateFilter(countriesVisited));
    } else {
      setCountriesVisitedFilter(['==', 'id', -1]);
    }
  }, [countriesVisited]);

  useEffect(() => {
    if (dareVisited && dareVisited.length) {
      setDareVisitedFilter(generateFilter(dareVisited));
    } else {
      setDareVisitedFilter(['==', 'id', -1]);
    }
  }, [dareVisited]);

  useEffect(() => {
    if (!seriesFilter.visible) {
      setSeriesVisitedFilter(generateFilter([]));
      setSeriesNotVisitedFilter(generateFilter([]));
      return;
    }

    if (seriesFilter.applied) {
      if (seriesVisited?.length) {
        setSeriesVisitedFilter([
          'all',
          ['any', ...seriesVisited.map((id) => ['==', 'id', id])],
          ['any', ...seriesFilter.groups.map((groupId: number) => ['==', 'series_id', groupId])]
        ]);
        setSeriesNotVisitedFilter([
          'all',
          ['all', ...seriesVisited.map((id) => ['!=', 'id', id])],
          ['any', ...seriesFilter.groups.map((groupId: number) => ['==', 'series_id', groupId])]
        ]);
      } else {
        setSeriesNotVisitedFilter([
          'any',
          ...seriesFilter.groups.map((groupId: number) => ['==', 'series_id', groupId])
        ]);
      }
    } else {
      setSeriesVisitedFilter(['any', ...seriesVisited.map((id) => ['==', 'id', id])]);
      setSeriesNotVisitedFilter(['all', ...seriesVisited.map((id) => ['!=', 'id', id])]);
    }
  }, [seriesVisited, seriesFilter]);

  useEffect(() => {
    if (route.params?.lon && route.params?.lat) {
      setMarkerCoords([route.params.lon, route.params.lat]);
      const timeoutId = setTimeout(() => {
        if (cameraRef.current) {
          cameraRef.current.setCamera({
            centerCoordinate: [route.params?.lon, route.params?.lat],
            zoomLevel: 15,
            animationDuration: 800
          });
        } else {
          console.warn('Camera ref is not available.');
        }
      }, 800);

      return () => clearTimeout(timeoutId);
    }
    if (route.params?.id && route.params?.type && db1 && db2 && db3) {
      handleFindRegion(route.params?.id, route.params?.type);
    }
  }, [route, db1, db2, db3]);

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

  useEffect(() => {
    if (interval > 0 && showNomads) {
      const intervalId = setInterval(() => {
        if (location && token && showNomads) {
          refetchUsersLocation();
        }
      }, interval);

      return () => clearInterval(intervalId);
    }
  }, [interval, showNomads]);

  useEffect(() => {
    (async () => {
      let { status } = await Location.getForegroundPermissionsAsync();
      const isServicesEnabled = await Location.hasServicesEnabledAsync();

      if (locationSettings && locationSettings.sharing_refresh_interval) {
        setInterval(locationSettings.sharing_refresh_interval * 1000);
      }

      if (
        status !== 'granted' ||
        !token ||
        (locationSettings && locationSettings.sharing === 0) ||
        !isServicesEnabled
      ) {
        setShowNomads(false);
        storage.set('showNomads', false);
        await stopBackgroundLocationUpdates();
        return;
      }

      const bgStatus = await Location.getBackgroundPermissionsAsync();
      if (bgStatus.status !== 'granted') {
        const { status } = await Location.requestBackgroundPermissionsAsync();
        if (status === Location.PermissionStatus.GRANTED) {
          await startBackgroundLocationUpdates();
        } else {
          await stopBackgroundLocationUpdates();
        }
      } else {
        // await startBackgroundLocationUpdates();
        await restartBackgroundLocationUpdates();
      }

      try {
        let currentLocation = await Location.getCurrentPositionAsync({
          accuracy: Location.Accuracy.Balanced
        });
        setLocation(currentLocation.coords);

        if (locationSettings && locationSettings.sharing === 1 && token) {
          updateLocation({
            token,
            lat: currentLocation.coords.latitude,
            lng: currentLocation.coords.longitude
          });

          showNomads && refetchUsersLocation();
        }
      } catch (error) {
        console.error('Error fetching user location:', error);
      }
    })();
  }, [locationSettings]);

  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 });
  }, []);

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

  const mapRef = useRef<MapLibreRN.MapViewRef>(null);
  const cameraRef = useRef<MapLibreRN.CameraRef>(null);
  const shapeSourceRef = useRef<MapLibreRN.ShapeSourceRef>(null);

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

  const handlePress = () => {
    if (isExpanded) {
      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 loadInitialRegion = () => {
    try {
      const savedInitialRegion = storage.get('initialRegion', StoreType.STRING) as string;
      if (savedInitialRegion) {
        const region = JSON.parse(savedInitialRegion);
        setInitialRegion(region);
      }
    } catch (e) {
      console.error('Failed to load saved initial region:', e);
    }
  };

  useEffect(() => {
    loadInitialRegion();
  }, []);

  useEffect(() => {
    if (initialRegion && !route.params?.id) {
      const timeoutId = setTimeout(() => {
        if (cameraRef.current) {
          cameraRef.current.setCamera({
            centerCoordinate: [initialRegion.longitude, initialRegion.latitude],
            zoomLevel: Math.log2(360 / initialRegion.latitudeDelta),
            animationDuration: 500
          });
        } else {
          console.warn('Camera ref is not available.');
        }
      }, 500);

      return () => clearTimeout(timeoutId);
    }
  }, [initialRegion]);

  const handleMapChange = async () => {
    if (!mapRef.current) return;
    if (hideTimer.current) clearTimeout(hideTimer.current);

    setIsZooming(true);

    const currentZoom = await mapRef.current.getZoom();
    const currentCenter = await mapRef.current.getCenter();

    setZoom(currentZoom);
    setCenter(currentCenter);
  };

  const onMapPress = async (event: any) => {
    if (!mapRef.current) return;
    if (selectedMarker || selectedUser) {
      closeCallout();
      return;
    }
    if (type === 'blank') return;
    try {
      const { screenPointX, screenPointY } = event.properties;

      const { features } = await mapRef.current.queryRenderedFeaturesAtPoint(
        [screenPointX, screenPointY],
        undefined,
        ['regions', 'countries', 'dare']
      );

      if (features?.length) {
        const region = features[0];
        if (selectedRegion === region.properties?.id) return;

        let db = type === 'regions' ? db1 : type === 'countries' ? db3 : db2;
        let tableName = type === 'dare' ? 'places' : type;
        let foundRegion = region.properties?.id;

        setSelectedRegion(region.properties?.id);

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

        if (tableName === 'regions') {
          token
            ? await mutateUserData(
                { region_id: +foundRegion, token: String(token) },
                {
                  onSuccess: (data) => {
                    setUserData({ type: 'nm', id: +foundRegion, ...data });
                  }
                }
              )
            : setUserData({ type: 'nm', id: +foundRegion });
          if (regionsList && regionsList.data) {
            const region = regionsList.data.find((region) => region.id === +foundRegion);
            if (region) {
              const bounds = turf.bbox(region.bbox);
              cameraRef.current?.fitBounds(
                [bounds[2], bounds[3]],
                [bounds[0], bounds[1]],
                [10, 10, 50, 10],
                1000
              );
            }
          }
        } else if (tableName === 'countries') {
          token
            ? await mutateCountriesData(
                { id: +foundRegion, token },
                {
                  onSuccess: (data) => {
                    setUserData({ type: 'countries', id: +foundRegion, ...data.data });
                  }
                }
              )
            : setUserData({ type: 'countries', id: +foundRegion });
          if (countriesList && countriesList.data) {
            const region = countriesList.data.find((region) => region.id === +foundRegion);
            if (region) {
              const bounds = turf.bbox(region.bbox);
              cameraRef.current?.fitBounds(
                [bounds[2], bounds[3]],
                [bounds[0], bounds[1]],
                [10, 10, 50, 10],
                1000
              );
            }
          }
        } else {
          token
            ? await mutateUserDataDare(
                { dare_id: +foundRegion, token: String(token) },
                {
                  onSuccess: (data) => {
                    setUserData({ type: 'dare', id: +foundRegion, ...data });
                  }
                }
              )
            : setUserData({ type: 'dare', id: +foundRegion });
          if (dareList && dareList.data) {
            const region = dareList.data.find((region) => region.id === +foundRegion);
            if (region) {
              const bounds = turf.bbox(region.bbox);
              cameraRef.current?.fitBounds(
                [bounds[2], bounds[3]],
                [bounds[0], bounds[1]],
                [10, 10, 50, 10],
                1000
              );
            }
          }
        }
      } else {
        handleClosePopup();
      }
    } catch (error) {
      console.error('Error onMapPress features:', error);
    }
  };

  const handleRegionDidChange = async (feature: GeoJSON.Feature<GeoJSON.Point, any>) => {
    hideTimer.current = setTimeout(() => {
      setIsZooming(false);
    }, 2000);
    if (!feature) return;
    const { zoomLevel } = feature.properties;
    const { coordinates } = feature.geometry;
    if (!zoomLevel || !coordinates) return;

    const latitudeDelta = 360 / 2 ** zoomLevel;
    const longitudeDelta = latitudeDelta;

    const region = {
      latitude: coordinates[1],
      longitude: coordinates[0],
      latitudeDelta,
      longitudeDelta
    };

    storage.set('initialRegion', JSON.stringify(region));
  };

  const handleClosePopup = async () => {
    setSelectedRegion(null);
    setRegionPopupVisible(false);
    setRegionData(null);
  };

  const handleGetLocation = async () => {
    setIsLocationLoading(true);
    try {
      let { status, canAskAgain } = await Location.getForegroundPermissionsAsync();
      const isServicesEnabled = await Location.hasServicesEnabledAsync();

      if (status === 'granted' && isServicesEnabled) {
        const bgStatus = await Location.getBackgroundPermissionsAsync();
        if (bgStatus.status !== 'granted') {
          const { status } = await Location.requestBackgroundPermissionsAsync();
          if (status === Location.PermissionStatus.GRANTED) {
            await startBackgroundLocationUpdates();
          } else {
            await stopBackgroundLocationUpdates();
          }
        } else {
          await startBackgroundLocationUpdates();
        }

        await getLocation();
      } else if (!canAskAgain || !isServicesEnabled) {
        setOpenSettingsVisible(true);
      } else {
        setAskLocationVisible(true);
      }
    } finally {
      setIsLocationLoading(false);
    }
  };

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

      if (currentLocation.coords) {
        cameraRef.current?.flyTo(
          [currentLocation.coords.longitude, currentLocation.coords.latitude],
          1000
        );
      }

      if (locationSettings && locationSettings.sharing === 1 && token) {
        updateLocation({
          token,
          lat: currentLocation.coords.latitude,
          lng: currentLocation.coords.longitude
        });

        showNomads && refetchUsersLocation();
      }

      handleClosePopup();
    } catch (error) {
      console.error('Error fetching user location:', error);
    }
  };

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

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

  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);
  };

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

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

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

  const handleRegionData = async (regionData: any, avatars: string[]) => {
    if (!regionData) {
      await refreshDatabases();
    }
    setRegionData(regionData);
    setUserAvatars(avatars);
  };

  const handleFindRegion = async (id: number, type: 'regions' | 'countries' | 'places') => {
    setType(type === 'places' ? 'dare' : type);
    if (!db1 || !db2 || !db3) {
      return;
    }
    const db = type === 'regions' ? db1 : type === 'countries' ? db3 : db2;

    if (id) {
      setSelectedRegion(id);

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

      if (type === 'regions') {
        token
          ? await mutateUserData(
              { region_id: id, token: String(token) },
              {
                onSuccess: (data) => {
                  setUserData({ type: 'nm', id, ...data });
                }
              }
            )
          : setUserData({ type: 'nm', id });

        if (regionsList && regionsList.data) {
          const region = regionsList.data.find((region) => region.id === +id);
          if (region) {
            const bounds = turf.bbox(region.bbox);
            cameraRef.current?.fitBounds(
              [bounds[2], bounds[3]],
              [bounds[0], bounds[1]],
              [10, 10, 50, 10],
              1000
            );
          }
        }
      } else if (type === 'countries') {
        token
          ? await mutateCountriesData(
              { id, token },
              {
                onSuccess: (data) => {
                  setUserData({ type: 'countries', id, ...data.data });
                }
              }
            )
          : setUserData({ type: 'countries', id });

        if (countriesList && countriesList.data) {
          const region = countriesList.data.find((region) => region.id === +id);
          if (region) {
            const bounds = turf.bbox(region.bbox);
            cameraRef.current?.fitBounds(
              [bounds[2], bounds[3]],
              [bounds[0], bounds[1]],
              [10, 10, 50, 10],
              1000
            );
          }
        }
      } else {
        token
          ? await mutateUserDataDare(
              { dare_id: +id, token: String(token) },
              {
                onSuccess: (data) => {
                  setUserData({ type: 'dare', id: +id, ...data });
                }
              }
            )
          : setUserData({ type: 'dare', id: +id });

        if (dareList && dareList.data) {
          const region = dareList.data.find((region) => region.id === +id);
          if (region) {
            const bounds = turf.bbox(region.bbox);
            cameraRef.current?.fitBounds(
              [bounds[2], bounds[3]],
              [bounds[0], bounds[1]],
              [10, 10, 50, 10],
              1000
            );
          }
        }
      }
    } else {
      handleClosePopup();
    }
  };

  const handleMarkerPress = async (event: any) => {
    const { features } = event;
    if (features?.length) {
      const selectedFeature = features[0];
      const { coordinates } = selectedFeature.geometry;
      const visited = seriesVisited.includes(selectedFeature.properties.id) ? 1 : 0;
      const icon = images[selectedFeature.properties.series_id];

      const { name, description, series_name, series_id, id } = selectedFeature.properties;

      if (coordinates) {
        setSelectedMarker({
          coordinates,
          name,
          icon,
          description,
          series_name,
          visited,
          series_id,
          id
        });
        setSelectedUser(null);
      }
    }
  };

  const closeCallout = () => {
    setSelectedMarker(null);
    setSelectedUser(null);
  };

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

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

      try {
        updateSeriesItem(itemData);
        if (item.visited === 1) {
          setSeriesVisited((current) => current.filter((id) => id !== item.id));
          setSelectedMarker((current: any) => ({ ...current, visited: 0 }));
        } else {
          setSeriesVisited((current) => [...current, item.id]);
          setSelectedMarker((current: any) => ({ ...current, visited: 1 }));
        }
      } catch (error) {
        console.error('Failed to update series state', error);
      }
    },
    [token, updateSeriesItem]
  );

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

  const handleUserPress = (event: any) => {
    const selectedFeature = event.features[0];
    const { coordinates } = selectedFeature.geometry;
    const { avatar, first_name, last_name, flag, id, last_seen } = selectedFeature.properties;
    if (selectedFeature) {
      setSelectedUser({
        coordinates,
        avatar: avatar ? { uri: API_HOST + avatar } : logo,
        first_name,
        last_name,
        flag: { uri: API_HOST + flag },
        id,
        last_seen
      });
      setSelectedMarker(null);
    }
  };

  return (
    <SafeAreaView style={{ height: '100%' }}>
      <StatusBar translucent backgroundColor="transparent" />

      <MapLibreRN.MapView
        ref={mapRef}
        style={styles.map}
        mapStyle={VECTOR_MAP_HOST + '/nomadmania-maps.json'}
        rotateEnabled={false}
        attributionEnabled={false}
        onPress={onMapPress}
        onRegionDidChange={handleRegionDidChange}
        onRegionIsChanging={handleMapChange}
        onRegionWillChange={_.debounce(handleMapChange, 200)}
      >
        <MapLibreRN.Images
          images={images}
          onImageMissing={(image) => {
            if (processedImages.current.has(image)) {
              return;
            }

            processedImages.current.add(image);
            setImages((prevImages: any) => ({
              ...prevImages,
              [image]: defaultSeriesIcon
            }));
          }}
        >
          <View />
        </MapLibreRN.Images>

        {markerCoords && (
          <MapLibreRN.PointAnnotation id="marker" coordinate={markerCoords}>
            <View
              style={{
                height: 24,
                width: 24,
                backgroundColor: Colors.ORANGE,
                borderRadius: 12,
                borderColor: Colors.WHITE,
                borderWidth: 2
              }}
            />
          </MapLibreRN.PointAnnotation>
        )}

        {type === 'regions' && (
          <>
            <MapLibreRN.LineLayer
              id="nm-regions-line-layer"
              sourceID={regions.source}
              sourceLayerID={regions['source-layer']}
              filter={regions.filter as any}
              maxZoomLevel={regions.maxzoom}
              style={{
                lineColor: 'rgba(14, 80, 109, 1)',
                lineWidth: ['interpolate', ['linear'], ['zoom'], 0, 0.2, 4, 1, 5, 1.5, 12, 3],
                lineWidthTransition: { duration: 300, delay: 0 }
              }}
              belowLayerID="waterway-name"
            />
            <MapLibreRN.FillLayer
              id={regions.id}
              sourceID={regions.source}
              sourceLayerID={regions['source-layer']}
              filter={regions.filter as any}
              style={regions.style}
              maxZoomLevel={regions.maxzoom}
              belowLayerID={regions_visited.id}
            />
            <MapLibreRN.FillLayer
              id={regions_visited.id}
              sourceID={regions_visited.source}
              sourceLayerID={regions_visited['source-layer']}
              filter={regionsVisitedFilter as any}
              style={regions_visited.style}
              maxZoomLevel={regions_visited.maxzoom}
              belowLayerID="waterway-name"
            />
          </>
        )}
        {type === 'countries' && (
          <>
            <MapLibreRN.LineLayer
              id="countries-line-layer"
              sourceID={countries.source}
              sourceLayerID={countries['source-layer']}
              filter={countries.filter as any}
              maxZoomLevel={countries.maxzoom}
              style={{
                lineColor: 'rgba(14, 80, 109, 1)',
                lineWidth: ['interpolate', ['linear'], ['zoom'], 0, 0.2, 4, 1, 5, 1.5, 12, 3],
                lineWidthTransition: { duration: 300, delay: 0 }
              }}
              belowLayerID="waterway-name"
            />
            <MapLibreRN.FillLayer
              id={countries.id}
              sourceID={countries.source}
              sourceLayerID={countries['source-layer']}
              filter={countries.filter as any}
              style={countries.style}
              maxZoomLevel={countries.maxzoom}
              belowLayerID={countries_visited.id}
            />
            <MapLibreRN.FillLayer
              id={countries_visited.id}
              sourceID={countries_visited.source}
              sourceLayerID={countries_visited['source-layer']}
              filter={countriesVisitedFilter as any}
              style={countries_visited.style}
              maxZoomLevel={countries_visited.maxzoom}
              belowLayerID="waterway-name"
            />
          </>
        )}
        {type === 'dare' && (
          <>
            <MapLibreRN.FillLayer
              id={dare.id}
              sourceID={dare.source}
              sourceLayerID={dare['source-layer']}
              filter={dare.filter as any}
              style={dare.style}
              maxZoomLevel={dare.maxzoom}
              belowLayerID={dare_visited.id}
            />
            <MapLibreRN.FillLayer
              id={dare_visited.id}
              sourceID={dare_visited.source}
              sourceLayerID={dare_visited['source-layer']}
              filter={dareVisitedFilter as any}
              style={dare_visited.style}
              maxZoomLevel={dare_visited.maxzoom}
              belowLayerID="waterway-name"
            />
          </>
        )}
        {selectedRegion && type && (
          <>
            <MapLibreRN.FillLayer
              id={selected_region.id}
              sourceID={type}
              sourceLayerID={type}
              filter={['==', 'id', selectedRegion]}
              style={selected_region.style}
              maxZoomLevel={selected_region.maxzoom}
              belowLayerID="waterway-name"
            />
            <MapLibreRN.LineLayer
              id={selected_region_outline.id}
              sourceID={type}
              sourceLayerID={type}
              filter={['==', 'id', selectedRegion]}
              style={selected_region_outline.style as any}
              maxZoomLevel={selected_region_outline.maxzoom}
              belowLayerID="waterway-name"
            />
          </>
        )}

        <MapLibreRN.VectorSource
          id="nomadmania_series"
          tileUrlTemplates={[VECTOR_MAP_HOST + '/tiles/series/{z}/{x}/{y}.pbf']}
          onPress={handleMarkerPress}
        >
          {seriesFilter.status !== 1 && Object.keys(images).length > 0 ? (
            <MapLibreRN.SymbolLayer
              id={series_layer.id}
              sourceID={series_layer.source}
              sourceLayerID={series_layer['source-layer']}
              aboveLayerID={Platform.OS === 'android' ? 'waterway-name' : undefined}
              filter={seriesNotVisitedFilter as any}
              minZoomLevel={series_layer.minzoom}
              maxZoomLevel={series_layer.maxzoom}
              style={{
                symbolSpacing: 1,
                iconImage: ['get', 'series_id'],
                iconSize: 0.51,
                iconAllowOverlap: true,
                iconIgnorePlacement: true,
                visibility: 'visible',
                iconColor: '#666',
                iconOpacity: 1,
                iconHaloColor: '#ffffff',
                iconHaloWidth: 1,
                iconHaloBlur: 0.5
              }}
            />
          ) : (
            <></>
          )}

          {seriesFilter.status !== 0 && Object.keys(images).length > 0 ? (
            <MapLibreRN.SymbolLayer
              id={series_visited.id}
              sourceID={series_visited.source}
              sourceLayerID={series_visited['source-layer']}
              aboveLayerID={Platform.OS === 'android' ? 'waterway-name' : undefined}
              filter={seriesVisitedFilter as any}
              minZoomLevel={series_visited.minzoom}
              maxZoomLevel={series_visited.maxzoom}
              style={{
                symbolSpacing: 1,
                iconImage: '{series_id}v',
                iconSize: 0.51,
                iconAllowOverlap: true,
                iconIgnorePlacement: true,
                visibility: 'visible',
                iconColor: '#666',
                iconOpacity: 1,
                iconHaloColor: '#ffffff',
                iconHaloWidth: 1,
                iconHaloBlur: 0.5
              }}
            />
          ) : (
            <></>
          )}
        </MapLibreRN.VectorSource>

        {nomads && showNomads && (
          <MapLibreRN.ShapeSource
            ref={shapeSourceRef}
            tolerance={20}
            id="nomads"
            shape={nomads}
            onPress={async (event) => {
              const feature = event.features[0];
              const isCluster = feature.properties?.cluster;

              if (isCluster) {
                const clusterCoordinates = (feature.geometry as GeoJSON.Point).coordinates;

                const zoom = await shapeSourceRef.current?.getClusterExpansionZoom(
                  feature as GeoJSON.Feature<GeoJSON.Geometry>
                );
                const newZoom = zoom ?? 2;

                cameraRef.current?.setCamera({
                  centerCoordinate: clusterCoordinates,
                  zoomLevel: newZoom,
                  animationDuration: 500,
                  animationMode: 'flyTo'
                });
                return;
              } else {
                handleUserPress(event);
              }
            }}
            cluster={true}
            clusterRadius={50}
          >
            <MapLibreRN.SymbolLayer
              id="nomads_circle"
              filter={['has', 'point_count']}
              aboveLayerID={Platform.OS === 'android' ? 'place-continent' : undefined}
              style={{
                iconImage: clusteredUsersIcon,
                iconSize: [
                  'interpolate',
                  ['linear'],
                  ['get', 'point_count'],
                  0,
                  0.33,
                  10,
                  0.35,
                  20,
                  0.37,
                  50,
                  0.39,
                  75,
                  0.41,
                  100,
                  0.43
                ],
                iconAllowOverlap: true
              }}
            ></MapLibreRN.SymbolLayer>
            <MapLibreRN.SymbolLayer
              id="nomads_count"
              filter={['has', 'point_count']}
              aboveLayerID={Platform.OS === 'android' ? 'nomads_circle' : undefined}
              style={{
                textField: [
                  'case',
                  ['<', ['get', 'point_count'], 1000],
                  ['get', 'point_count'],
                  ['concat', ['/', ['round', ['/', ['get', 'point_count'], 100]], 10], 'k']
                ],
                textFont: ['Noto Sans Bold'],
                textSize: [
                  'interpolate',
                  ['linear'],
                  ['get', 'point_count'],
                  0,
                  13.5,
                  20,
                  14,
                  75,
                  15
                ],
                textColor: '#FFFFFF',
                textAnchor: 'center',
                textOffset: [
                  'interpolate',
                  ['linear'],
                  ['get', 'point_count'],
                  0,
                  ['literal', [0, 0.85]],
                  20,
                  ['literal', [0, 0.92]],
                  75,
                  ['literal', [0, 1]]
                ],
                textAllowOverlap: true
              }}
            />
            <MapLibreRN.SymbolLayer
              id="nomads_symbol"
              filter={['!', ['has', 'point_count']]}
              aboveLayerID={Platform.OS === 'android' ? 'place-continent' : undefined}
              style={{
                iconImage: defaultUserAvatar,
                iconSize: [
                  'interpolate',
                  ['linear'],
                  ['zoom'],
                  0,
                  0.24,
                  5,
                  0.28,
                  10,
                  0.33,
                  15,
                  0.38,
                  20,
                  0.42
                ],
                iconAllowOverlap: true
              }}
            ></MapLibreRN.SymbolLayer>
          </MapLibreRN.ShapeSource>
        )}

        {selectedUser && <UserItem marker={selectedUser} />}

        {selectedMarker && (
          <MarkerItem marker={selectedMarker} toggleSeries={toggleSeries} token={token} />
        )}
        <MapLibreRN.Camera ref={cameraRef} />
        {location && (
          <MapLibreRN.UserLocation
            animated={true}
            showsUserHeadingIndicator={true}
            onPress={async () => {
              const currentZoom = await mapRef.current?.getZoom();
              const newZoom = (currentZoom || 0) + 2;

              cameraRef.current?.setCamera({
                centerCoordinate: [location.longitude, location.latitude],
                zoomLevel: newZoom,
                animationDuration: 500,
                animationMode: 'flyTo'
              });
            }}
          >
            {/* to do custom user location */}
          </MapLibreRN.UserLocation>
        )}
      </MapLibreRN.MapView>

      {center ? (
        <ScaleBar
          zoom={zoom}
          latitude={center[1]}
          isVisible={isZooming}
          bottom={tabBarHeight + 80}
        />
      ) : null}

      {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,
              { bottom: tabBarHeight + 20 }
            ]}
          >
            {isLocationLoading ? (
              <ActivityIndicator size="small" color={Colors.DARK_BLUE} />
            ) : (
              <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);

              const updatedIds = regionsVisited.includes(id)
                ? regionsVisited.filter((visitedId) => visitedId !== id)
                : [...regionsVisited, id];
              setRegionsVisited(updatedIds);
              refetchVisitedCountries();
            }}
            updateDare={(id, visits) => {
              if (!token) {
                setIsWarningModalVisible(true);
                return;
              }
              handleUpdateDare(id, visits);

              const updatedIds = dareVisited.includes(id)
                ? dareVisited.filter((visitedId) => visitedId !== id)
                : [...dareVisited, id];
              setDareVisited(updatedIds);
            }}
            disabled={!token || !isConnected}
            updateSlow={(id, v, s11, s31, s101) => {
              if (!token) {
                setIsWarningModalVisible(true);
                return;
              }
              handleUpdateSlow(id, v, s11, s31, s101);

              const updatedIds = countriesVisited.includes(id)
                ? countriesVisited.filter((visitedId) => visitedId !== id)
                : [...countriesVisited, id];
              setCountriesVisited(updatedIds);
            }}
            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 + '?v=' + avatarVersion
                    }}
                  />
                ) : (
                  <AvatarWithInitials
                    text={`${userInfoData?.first_name ? userInfoData?.first_name[0] : ''}${userInfoData?.last_name ? 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>

          <View style={[styles.tabs, { bottom: tabBarHeight + 20 }]}>
            <ScrollView
              horizontal
              showsHorizontalScrollIndicator={false}
              contentContainerStyle={{
                paddingHorizontal: 12,
                paddingTop: 6,
                gap: isSmallScreen ? 8 : 12,
                flexDirection: 'row'
              }}
            >
              <MapButton
                onPress={() => {
                  try {
                    setIsFilterVisible('regions');
                    closeCallout();
                  } catch (error) {
                    console.error('Error opening filter:', error);
                  }
                }}
                icon={TravelsIcon}
                text="Travels"
                active={type !== 'blank'}
              />
              <MapButton
                onPress={() => {
                  try {
                    setIsFilterVisible('series');
                    closeCallout();
                  } catch (error) {
                    console.error('Error opening filter:', error);
                  }
                }}
                icon={SeriesIcon}
                text="Series"
                active={seriesFilter.visible}
              />
              {token ? (
                <MapButton
                  onPress={() => {
                    try {
                      setIsFilterVisible('nomads');
                      closeCallout();
                    } catch (error) {
                      console.error('Error opening filter:', error);
                    }
                  }}
                  icon={NomadsIcon}
                  text="Nomads"
                  active={showNomads}
                >
                  {usersOnMapCount && usersOnMapCount?.count > 0 ? (
                    <MessagesDot
                      messagesCount={usersOnMapCount.count}
                      fullNumber={true}
                      right={-10}
                      top={-8}
                    />
                  ) : null}
                </MapButton>
              ) : null}
            </ScrollView>
          </View>

          <TouchableOpacity
            onPress={handleGetLocation}
            style={[
              styles.cornerButton,
              styles.bottomButton,
              styles.bottomRightButton,
              { bottom: tabBarHeight + 20 }
            ]}
          >
            {isLocationLoading ? (
              <ActivityIndicator size="small" color={Colors.DARK_BLUE} />
            ) : (
              <LocationIcon />
            )}
          </TouchableOpacity>
        </>
      )}

      <SearchModal
        searchVisible={searchVisible}
        handleCloseModal={handleCloseModal}
        handleFindRegion={handleFindRegion}
        index={index}
        searchData={searchData}
        setIndex={setIndex}
        token={token}
      />
      <WarningModal
        type={'unauthorized'}
        isVisible={isWarningModalVisible}
        onClose={() => setIsWarningModalVisible(false)}
      />
      <EditNmModal
        isVisible={isEditModalVisible}
        onClose={() => setIsEditModalVisible(false)}
        modalState={modalState}
        updateModalState={handleModalStateChange}
        updateNM={handleUpdateNM}
      />
      <FilterModal
        isFilterVisible={isFilterVisible}
        setIsFilterVisible={setIsFilterVisible}
        tilesTypes={tilesTypes}
        tilesType={tilesType}
        setTilesType={setTilesType}
        setType={setType}
        userId={userId ? +userId : 0}
        setRegionsFilter={setRegionsFilter}
        setSeriesFilter={setSeriesFilter}
        setShowNomads={setShowNomads}
        showNomads={showNomads}
        isPublicView={false}
        isLogged={token ? true : false}
        usersOnMapCount={token && usersOnMapCount?.count ? usersOnMapCount.count : null}
        isConnected={isConnected}
      />
      <EditModal
        isVisible={isEditSlowModalVisible}
        onClose={() => setIsEditSlowModalVisible(false)}
        item={{ ...userData, country_id: regionData?.id }}
        updateSlow={(id, v, s11, s31, s101) => handleUpdateSlow(id, v, s11, s31, s101)}
      />
      <WarningModal
        type={'success'}
        isVisible={askLocationVisible}
        onClose={() => setAskLocationVisible(false)}
        action={handleAcceptPermission}
        message="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."
      />
      <WarningModal
        type={'success'}
        isVisible={openSettingsVisible}
        onClose={() => setOpenSettingsVisible(false)}
        action={async () => {
          const isServicesEnabled = await Location.hasServicesEnabledAsync();

          if (!isServicesEnabled) {
            Platform.OS === 'ios'
              ? Linking.openURL('app-settings:')
              : Linking.sendIntent('android.settings.LOCATION_SOURCE_SETTINGS');
          } else {
            Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings();
          }
        }}
        message="NomadMania app needs location permissions to function properly. Open settings?"
      />
    </SafeAreaView>
  );
};

export default MapScreen;