import {
  Platform,
  TouchableOpacity,
  Image,
  Linking,
  TextInput,
  Dimensions,
  StatusBar,
  ActivityIndicator,
  ScrollView,
  View,
  Text
} from 'react-native';
import React, { FC, useCallback, useEffect, useRef, useState } from 'react';
import * as Location from 'expo-location';
import Animated, {
  Easing,
  useSharedValue,
  useAnimatedStyle,
  withTiming
} from 'react-native-reanimated';
import * as turf from '@turf/turf';

import { styles } from './styles';
import { API_HOST, VECTOR_MAP_HOST } from 'src/constants';
import { CommonActions, NavigationProp, useFocusEffect } from '@react-navigation/native';
import { AvatarWithInitials, LocationPopup, WarningModal } from 'src/components';
import { Colors } from 'src/theme';

import CloseSvg from 'assets/icons/close.svg';
import LocationIcon from 'assets/icons/location.svg';
import SearchIcon from 'assets/icons/search.svg';

import FilterModal from '../../MapScreen/FilterModal';
import SearchModal from '../../MapScreen/UniversalSearch';
import { useGetUniversalSearch } from '@api/search';
import { storage, StoreType } from 'src/storage';
import { NAVIGATION_PAGES } from 'src/types';
import { SafeAreaView } from 'react-native-safe-area-context';
import * as MapLibreRN from '@maplibre/maplibre-react-native';
import {
  usePostGetVisitedCountriesIdsQuery,
  usePostGetVisitedDareIdsQuery,
  usePostGetVisitedRegionsIdsQuery
} from '@api/maps';
import moment from 'moment';

import TravelsIcon from 'assets/icons/bottom-navigation/globe-solid.svg';
import MapButton from 'src/components/MapButton';
import ScaleBar from 'src/components/ScaleBar';
import _ from 'lodash';
import { SQLiteDatabase } from 'expo-sqlite';
import { getData } from 'src/modules/map/regionData';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
import {
  getCountriesDatabase,
  getFirstDatabase,
  getSecondDatabase,
  refreshDatabases
} from 'src/db';
import { fetchUserData, fetchUserDataDare, useGetListRegionsQuery } from '@api/regions';
import { fetchCountryUserData, useGetListCountriesQuery } from '@api/countries';
import { useRegion } from 'src/contexts/RegionContext';
import { useGetListDareQuery } from '@api/myDARE';
import { useConnection } from 'src/contexts/ConnectionContext';
import RegionPopup from 'src/components/RegionPopup';
import { point } from '@turf/turf';
import { booleanPointInPolygon } from '@turf/turf';
import { area } from '@turf/turf';
const defaultUserAvatar = require('assets/icon-user-share-location-solid.png');

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

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

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

let dare_visited = {
  id: 'dare_visited',
  type: 'fill',
  source: 'dare',
  'source-layer': 'dare',
  style: {
    fillColor: 'rgba(255, 126, 0, 1)',
    fillOpacity: 0.5,
    fillOutlineColor: 'rgba(255, 126, 0, 1)'
  },
  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, 1)'
  },
  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
};

type Props = {
  navigation: NavigationProp<any>;
  route: any;
};

const UsersMapScreen: FC<Props> = ({ navigation, route }) => {
  const token = storage.get('token', StoreType.STRING) as string;
  const userId = route.params?.userId;
  const data = route.params?.data;
  const tabBarHeight = useBottomTabBarHeight();

  const [regionsVisitedFilter, setRegionsVisitedFilter] = useState(generateFilter([]));
  const [countriesVisitedFilter, setCountriesVisitedFilter] = useState(generateFilter([]));
  const [dareVisitedFilter, setDareVisitedFilter] = useState(generateFilter([]));

  const [regionsFilter, setRegionsFilter] = useState<any>({
    visitedLabel: 'by',
    year: moment().year()
  });

  const mapRef = useRef<MapLibreRN.MapViewRef>(null);
  const cameraRef = useRef<MapLibreRN.CameraRef>(null);
  const animationTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const isAnimatingRef = useRef(false);
  const [renderCamera, setRenderCamera] = useState(Platform.OS === 'ios');

  const [isFilterVisible, setIsFilterVisible] = useState<string | null>(null);
  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('regions');
  const [location, setLocation] = useState<Location.LocationObjectCoords | null>(null);
  const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
  const [openSettingsVisible, setOpenSettingsVisible] = useState<boolean>(false);
  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;
  const [search, setSearch] = useState('');
  const [searchInput, setSearchInput] = useState('');
  const { data: searchData } = useGetUniversalSearch(search, search.length > 0);
  const [isLocationLoading, setIsLocationLoading] = useState(false);

  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 { data: visitedRegionIds } = usePostGetVisitedRegionsIdsQuery(
    token,
    regionsFilter.visitedLabel,
    regionsFilter.year,
    +userId,
    type === 'regions' && !!userId
  );
  const { data: visitedCountryIds } = usePostGetVisitedCountriesIdsQuery(
    token,
    regionsFilter.visitedLabel,
    regionsFilter.year,
    +userId,
    type === 'countries' && !!userId
  );
  const { data: visitedDareIds } = usePostGetVisitedDareIdsQuery(
    token,
    +userId,
    type === 'dare' && !!userId
  );

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

  const { mutateAsync: mutateUserData } = fetchUserData();
  const { mutateAsync: mutateUserDataDare } = fetchUserDataDare();
  const { mutateAsync: mutateCountriesData } = fetchCountryUserData();
  const { data: regionsList } = useGetListRegionsQuery(isConnected);
  const { data: countriesList } = useGetListCountriesQuery(isConnected);
  const { data: dareList } = useGetListDareQuery(isConnected);

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

  const [selectedRegion, setSelectedRegion] = useState<number | null>(null);
  const [db1, setDb1] = useState<SQLiteDatabase | null>(null);
  const [db2, setDb2] = useState<SQLiteDatabase | null>(null);
  const [db3, setDb3] = useState<SQLiteDatabase | null>(null);
  const [regionData, setRegionData] = useState<any | null>(null);
  const [userAvatars, setUserAvatars] = useState<string[]>([]);
  const [isWarningModalVisible, setIsWarningModalVisible] = useState<boolean>(false);

  const [regionPopupVisible, setRegionPopupVisible] = useState<boolean | null>(false);

  const cameraController = {
    flyTo: useCallback((coordinates: number[], duration: number = 1000) => {
      isAnimatingRef.current = true;
      if (animationTimeoutRef.current) {
        clearTimeout(animationTimeoutRef.current);
      }
      if (Platform.OS === 'android') {
        setRenderCamera(true);
        requestAnimationFrame(() => {
          cameraRef.current?.flyTo(coordinates, duration);
        });
        animationTimeoutRef.current = setTimeout(() => {
          isAnimatingRef.current = false;
          setRenderCamera(false);
        }, duration + 200);
      } else {
        cameraRef.current?.flyTo(coordinates, duration);
        animationTimeoutRef.current = setTimeout(() => {
          isAnimatingRef.current = false;
        }, duration + 100);
      }
    }, []),
    setCamera: useCallback((config: any) => {
      isAnimatingRef.current = true;
      if (animationTimeoutRef.current) {
        clearTimeout(animationTimeoutRef.current);
      }
      if (Platform.OS === 'android') {
        setRenderCamera(true);
        requestAnimationFrame(() => {
          cameraRef.current?.setCamera(config);
        });
        animationTimeoutRef.current = setTimeout(
          () => {
            isAnimatingRef.current = false;
            setRenderCamera(false);
          },
          (config.animationDuration ?? 1000) + 200
        );
      } else {
        cameraRef.current?.setCamera(config);
        animationTimeoutRef.current = setTimeout(
          () => {
            isAnimatingRef.current = false;
          },
          (config.animationDuration ?? 1000) + 100
        );
      }
    }, []),

    fitBounds: useCallback((ne: number[], sw: number[], padding: number[], duration: number) => {
      isAnimatingRef.current = true;

      if (animationTimeoutRef.current) {
        clearTimeout(animationTimeoutRef.current);
      }

      if (Platform.OS === 'android') {
        setRenderCamera(true);

        requestAnimationFrame(() => {
          cameraRef.current?.fitBounds(ne, sw, padding, duration);
        });

        animationTimeoutRef.current = setTimeout(() => {
          isAnimatingRef.current = false;
          setRenderCamera(false);
        }, duration + 200);
      } else {
        cameraRef.current?.fitBounds(ne, sw, padding, duration);

        animationTimeoutRef.current = setTimeout(() => {
          isAnimatingRef.current = false;
        }, duration + 100);
      }
    }, [])
  };

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

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

  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(() => {
    if (visitedRegionIds) {
      setRegionsVisitedFilter(generateFilter(visitedRegionIds.ids));
    } else {
      setRegionsVisitedFilter(['==', 'id', -1]);
    }
  }, [visitedRegionIds]);

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

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

  useEffect(() => {
    if (
      data.location_sharing &&
      data.location_last_seen_location?.lng &&
      data.location_last_seen_location?.lat &&
      cameraRef.current
    ) {
      cameraController.flyTo(
        [data.location_last_seen_location.lng, data.location_last_seen_location.lat],
        1000
      );
    }
  }, [data, cameraRef.current]);

  useEffect(() => {
    return () => {
      if (animationTimeoutRef.current) {
        clearTimeout(animationTimeoutRef.current);
      }
    };
  }, []);

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

    setIsZooming(true);

    const currentZoom = await mapRef.current.getZoom();
    setZoom(currentZoom);

    if (mapRef.current) {
      const currentCenter = await mapRef.current?.getCenter();
      setCenter(currentCenter);
    }
  };

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

      if (status === 'granted' && isServicesEnabled) {
        await getLocation();
      } else if (!canAskAgain || !isServicesEnabled) {
        setOpenSettingsVisible(true);
      } else {
        setAskLocationVisible(true);
      }
    } finally {
      setIsLocationLoading(false);
    }
  };

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

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

  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 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 handleGoBack = () => {
    navigation.goBack();
  };

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

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

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

  const handleOpenEditModal = () => {
    // navigation.navigate(NAVIGATION_PAGES.EDIT_NM_DATA, { regionId: regionData?.id });
    navigation.navigate(NAVIGATION_PAGES.TRIPS_2025, {
      region: { id: regionData?.id, name: regionData?.name }
    });
  };

  const handleOpenEditSlowModal = () => {};

  const handleFindRegion = async (id: number, type: string) => {
    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);
            cameraController.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);
            cameraController.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);
            cameraController.fitBounds(
              [bounds[2], bounds[3]],
              [bounds[0], bounds[1]],
              [10, 10, 50, 10],
              1000
            );
          }
        }
      }
    } else {
      handleClosePopup();
    }
  };

  const onMapPress = async (event: any) => {
    if (!mapRef.current) return;
    if (type === 'blank') return;
    try {
      const { screenPointX, screenPointY } = event.properties;
      const [lng, lat] = event.geometry?.coordinates;

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

      if (features?.length) {
        let region = features[0];

        try {
          if (typeof lng === 'number' && typeof lat === 'number') {
            const p = point([lng, lat]);

            const inside = features
              .filter(
                (f) => f?.geometry?.type === 'Polygon' || f?.geometry?.type === 'MultiPolygon'
              )
              .filter((f) => booleanPointInPolygon(p, f as any));

            const best = inside.slice().sort((a, b) => area(a as any) - area(b as any))[0];

            if (best) {
              region = best;
            }
          }
        } catch (e) {
          console.warn('region detection failed', e);
        }
        
        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);

        if (region.properties?.alt_id) {
          setSelectedRegion(region.properties?.alt_id);
          db = db1;
          tableName = 'regions';
        }

        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);
              cameraController.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);
              cameraController.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);
              cameraController.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 locationFeature: GeoJSON.Feature<GeoJSON.Point> = {
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [data.location_last_seen_location?.lng, data.location_last_seen_location?.lat]
    },
    properties: {}
  };

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

      <MapLibreRN.MapView
        ref={mapRef}
        style={styles.map}
        mapStyle={VECTOR_MAP_HOST + '/nomadmania-maps2025.json'}
        rotateEnabled={false}
        attributionEnabled={false}
        onPress={onMapPress}
        onRegionDidChange={() => {
          hideTimer.current = setTimeout(() => {
            setIsZooming(false);
          }, 2000);
        }}
        onRegionWillChange={_.debounce(handleMapChange, 200)}
      >
        <>
          <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 },
              visibility: type === 'regions' ? 'visible' : 'none'
            }}
            belowLayerID="waterway-name"
          />
          <MapLibreRN.FillLayer
            id={regions.id}
            sourceID={regions.source}
            sourceLayerID={regions['source-layer']}
            filter={regions.filter as any}
            style={{
              ...regions.style,
              visibility: type === 'regions' ? 'visible' : 'none'
            }}
            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,
              visibility: type === 'regions' ? 'visible' : 'none'
            }}
            maxZoomLevel={regions_visited.maxzoom}
            belowLayerID="waterway-name"
          />
        </>

        <>
          <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 },
              visibility: type === 'countries' ? 'visible' : 'none'
            }}
            belowLayerID="waterway-name"
          />
          <MapLibreRN.FillLayer
            id={countries.id}
            sourceID={countries.source}
            sourceLayerID={countries['source-layer']}
            filter={countries.filter as any}
            style={{
              ...countries.style,
              visibility: type === 'countries' ? 'visible' : 'none'
            }}
            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,
              visibility: type === 'countries' ? 'visible' : 'none'
            }}
            maxZoomLevel={countries_visited.maxzoom}
            belowLayerID="waterway-name"
          />
        </>

        <>
          <MapLibreRN.FillLayer
            id={dare.id}
            sourceID={dare.source}
            sourceLayerID={dare['source-layer']}
            filter={dare.filter as any}
            style={{
              ...dare.style,
              visibility: type === 'dare' ? 'visible' : 'none'
            }}
            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,
              visibility: type === 'dare' ? 'visible' : 'none'
            }}
            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"
            />
          </>
        )}

        {data.location_sharing && data.location_last_seen_location && data.own_profile !== 1 && (
          <MapLibreRN.ShapeSource id="user_location" shape={locationFeature}>
            <MapLibreRN.SymbolLayer
              id="user_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.ShapeSource>
        )}

        {(Platform.OS === 'ios' || renderCamera) && <MapLibreRN.Camera ref={cameraRef} />}
        {location && (
          <MapLibreRN.UserLocation
            animated={true}
            showsUserHeadingIndicator={true}
          ></MapLibreRN.UserLocation>
        )}
      </MapLibreRN.MapView>

      {center ? (
        <ScaleBar zoom={zoom} latitude={center[1]} isVisible={isZooming} bottom={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);
            }}
            updateDare={(id, visits) => {
              if (!token) {
                setIsWarningModalVisible(true);
                return;
              }
              handleUpdateDare(id, visits);
            }}
            disabled={!token || !isConnected}
            updateSlow={(id, v, s11, s31, s101) => {
              if (!token) {
                setIsWarningModalVisible(true);
                return;
              }
              handleUpdateSlow(id, v, s11, s31, s101);
            }}
            openEditSlowModal={handleOpenEditSlowModal}
          />
        </>
      ) : (
        <>
          {!isExpanded ? (
            <TouchableOpacity
              style={[styles.cornerButton, styles.topRightButton]}
              onPress={handleGoBack}
            >
              {data.user_data.avatar ? (
                <Image
                  style={styles.avatar}
                  source={{ uri: API_HOST + '/img/avatars/' + data.user_data.avatar }}
                />
              ) : (
                <AvatarWithInitials
                  text={`${data.user_data.first_name[0] ?? ''}${data.user_data.last_name[0] ?? ''}`}
                  flag={API_HOST + '/img/flags_new/' + data.user_data.flag1}
                  size={48}
                  borderColor={Colors.WHITE}
                />
              )}
            </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={{ marginLeft: 12, gap: 12, flexDirection: 'row' }}
            >
              <MapButton
                onPress={() => {
                  setIsFilterVisible('regions');
                }}
                icon={TravelsIcon}
                text={
                  tilesType.value === 0 || tilesType.value === 1
                    ? token
                      ? `${tilesType.value === 0 ? 'NM' : 'UN'} ${regionsFilter.visitedLabel} ${regionsFilter.year}`
                      : `${tilesType.value === 0 ? 'NM' : 'UN'}`
                    : tilesType.value === 2
                      ? 'DARE'
                      : 'Travels'
                }
                active={true}
              />
            </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>
        </>
      )}

      <FilterModal
        isFilterVisible={isFilterVisible}
        setIsFilterVisible={setIsFilterVisible}
        tilesTypes={tilesTypes}
        tilesType={tilesType}
        setTilesType={setTilesType}
        setType={setType}
        userId={userId}
        setRegionsFilter={setRegionsFilter}
        isPublicView={true}
        isLogged={true}
      />
      <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={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();
          }
        }}
        modalText="NomadMania app needs location permissions to function properly. Open settings?"
      />
      <SearchModal
        searchVisible={searchVisible}
        handleCloseModal={handleCloseModal}
        handleFindRegion={handleFindRegion}
        index={index}
        searchData={searchData}
        setIndex={setIndex}
        token={token}
      />

      <WarningModal
        type={'unauthorized'}
        isVisible={isWarningModalVisible}
        onClose={() => setIsWarningModalVisible(false)}
      />
    </SafeAreaView>
  );
};

export default UsersMapScreen;
