import React, { useEffect, useState } from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  Image,
  Switch,
  Dimensions,
  Platform,
  Linking
} from 'react-native';
import ReactModal from 'react-native-modal';
import { Colors } from 'src/theme';
import { ModalStyles } from '../../TravellersScreen/Components/styles';
import { Dropdown, MultiSelect } from 'react-native-searchable-dropdown-kj';
import { Button, WarningModal } from 'src/components';
import { ButtonVariants } from 'src/types/components';
import { styles } from './styles';
import { TabBar, TabView } from 'react-native-tab-view';
import { usePostGetMapYearsQuery } from '@api/user';
import { API_HOST } from 'src/constants';
import CheckSvg from 'assets/icons/mark.svg';
import { useGetListQuery } from '@api/series';
import { RadioButton } from 'react-native-paper';
import { storage, StoreType } from 'src/storage';
import moment from 'moment';
import {
  usePostGetSettingsQuery,
  usePostIsFeatureActiveQuery,
  usePostSetSettingsMutation,
  usePostUpdateLocationMutation
} from '@api/location';
import * as Location from 'expo-location';

import SharingIcon from 'assets/icons/location-sharing.svg';
import UsersIcon from 'assets/icons/bottom-navigation/travellers.svg';
import LocationIcon from 'assets/icons/location.svg';

const FilterModal = ({
  isFilterVisible,
  setIsFilterVisible,
  tilesTypes,
  tilesType,
  setTilesType,
  setType,
  userId,
  setRegionsFilter,
  setSeriesFilter,
  isPublicView,
  isLogged = true,
  showNomads,
  setShowNomads
}: {
  isFilterVisible: boolean;
  setIsFilterVisible: (isVisible: boolean) => void;
  tilesTypes: any[];
  tilesType: any;
  setTilesType: (item: any) => void;
  setType: (type: any) => void;
  userId: number;
  setRegionsFilter: (data: { visitedLabel: 'in' | 'by'; year: number }) => void;
  setSeriesFilter?: (filter: any) => void;
  isPublicView: boolean;
  isLogged: boolean;
  showNomads?: boolean;
  setShowNomads?: (showNomads: boolean) => void;
}) => {
  const token = storage.get('token', StoreType.STRING) as string;
  const { data: locationSettings } = usePostGetSettingsQuery(token, isLogged && !isPublicView);
  const { mutateAsync: setSettings } = usePostSetSettingsMutation();
  const { mutateAsync: updateLocation } = usePostUpdateLocationMutation();
  const [index, setIndex] = useState(0);
  const [selectedYear, setSelectedYear] = useState<{ label: string; value: number } | null>(null);
  const [allYears, setAllYears] = useState<{ label: string; value: number }[]>([]);
  const [selectedVisible, setSelectedVisible] = useState({ label: 'visited by', value: 0 });
  const visibleTypes = [
    { label: 'visited by', value: 0 },
    { label: 'visited in', value: 1 }
  ];
  const { data: isFeatureActive } = usePostIsFeatureActiveQuery(token, !!token);
  const [routes, setRoutes] = useState([
    { key: 'regions', title: 'Travels' },
    { key: 'series', title: 'Series' }
  ]);
  const { data } = usePostGetMapYearsQuery(token as string, userId, isLogged ? true : false);
  const { data: seriesList } = useGetListQuery(true);
  const [series, setSeries] = useState<{ label: string; value: number }[]>([]);
  const [selectedSeries, setSelectedSeries] = useState<number[]>([]);
  const [seriesVisible, setSeriesVisible] = useState(true);
  const [selectedSeriesFilter, setSelectedSeriesFilter] = useState(-1);
  const savedFilterSettings = !isPublicView
    ? (storage.get('filterSettings', StoreType.STRING) as string)
    : null;

  const [isSharing, setIsSharing] = useState(false);
  const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
  const [openSettingsVisible, setOpenSettingsVisible] = useState<boolean>(false);

  useEffect(() => {
    if (isFeatureActive && isFeatureActive.active) {
      setRoutes([
        { key: 'regions', title: 'Travels' },
        { key: 'series', title: 'Series' },
        { key: 'nomads', title: 'Nomads' }
      ]);
    }
  }, [isFeatureActive]);

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

        setIsSharing(locationSettings.sharing !== 0 && status === 'granted' && isServicesEnabled);
      }
    };

    syncSettings();
  }, [locationSettings]);

  useEffect(() => {
    const loadFilterSettings = () => {
      try {
        if (savedFilterSettings) {
          const filterSettings = JSON.parse(savedFilterSettings);
          setTilesType(filterSettings.tilesType);
          setSelectedYear(filterSettings.selectedYear);
          setSelectedVisible(filterSettings.selectedVisible);
          setSelectedSeries(filterSettings.seriesFilter.groups);
          setSeriesVisible(filterSettings.seriesFilter.visible);
          setSelectedSeriesFilter(filterSettings.seriesFilter.status);
        }
      } catch (error) {
        console.error('Failed to load filter settings', error);
      }
    };

    if (!isPublicView && isLogged) {
      loadFilterSettings();
    }
  }, [savedFilterSettings]);

  const saveFilterSettings = async () => {
    if (isLogged && !isPublicView) {
      try {
        const filterSettings = {
          type: tilesType.value === 2 ? 'dare' : tilesType.value === 1 ? 'countries' : 'regions',
          tilesType,
          selectedYear,
          selectedVisible,
          seriesFilter: {
            visible: seriesVisible,
            groups: selectedSeries,
            applied: true,
            status: selectedSeriesFilter
          }
        };
        storage.set('filterSettings', JSON.stringify(filterSettings));
      } catch (error) {
        console.error('Failed to save filter settings', error);
      }
    }
  };

  useEffect(() => {
    if (data && data.data && data.data.map_years) {
      const years = data.data.map_years.filter((year) => year > 1900);
      const formattedYears = years
        .map((year) => ({ label: year.toString(), value: year }))
        .reverse();
      setAllYears(formattedYears);
      formattedYears.length && !savedFilterSettings && setSelectedYear(formattedYears[0]);
    }
  }, [data, savedFilterSettings]);

  useEffect(() => {
    if (seriesList?.data) {
      setSeries([
        ...seriesList.data.map((item) => ({
          label: item.name,
          value: item.id,
          icon: item.icon
        }))
      ]);
      !savedFilterSettings && setSelectedSeries(seriesList.data.map((item) => item.id));
    }
  }, [seriesList]);

  if (!data && isLogged) return;

  const handleApplyFilter = () => {
    if (!isLogged) {
      return;
    }

    if (selectedVisible.value === 0) {
      if (tilesType.value === 0) {
        setRegionsFilter({
          visitedLabel: 'by',
          year: selectedYear && selectedYear.value ? selectedYear.value : moment().year()
        });
      } else if (tilesType.value === 1) {
        setRegionsFilter({
          visitedLabel: 'by',
          year: selectedYear && selectedYear.value ? selectedYear.value : moment().year()
        });
      }
    } else {
      if (tilesType.value === 0) {
        setRegionsFilter({
          visitedLabel: 'in',
          year: selectedYear && selectedYear.value ? selectedYear.value : moment().year()
        });
      } else if (tilesType.value === 1) {
        setRegionsFilter({
          visitedLabel: 'in',
          year: selectedYear && selectedYear.value ? selectedYear.value : moment().year()
        });
      }
    }
  };

  const handleCloseFilter = () => {
    setIndex(0);
    setIsFilterVisible(false);
  };

  const renderRegions = () => {
    return (
      <View style={styles.sceneContainer}>
        <View style={styles.optionsContainer}>
          <View style={styles.rowWrapper}>
            <View style={[styles.dropdownWrapper, {}]}>
              <Dropdown
                style={[ModalStyles.dropdown, { width: '100%' }]}
                placeholderStyle={ModalStyles.placeholderStyle}
                selectedTextStyle={ModalStyles.selectedTextStyle}
                containerStyle={ModalStyles.dropdownContent}
                data={tilesTypes}
                labelField="label"
                valueField="value"
                value={tilesType?.label}
                placeholder={tilesType?.label}
                onChange={(item) => {
                  setTilesType(item);
                }}
              />
            </View>
          </View>

          {tilesType.value !== 2 && allYears.length && isLogged ? (
            <View style={styles.rowWrapper}>
              <View style={styles.dropdownWrapper}>
                <Dropdown
                  style={[ModalStyles.dropdown, { width: '100%' }]}
                  placeholderStyle={ModalStyles.placeholderStyle}
                  selectedTextStyle={ModalStyles.selectedTextStyle}
                  containerStyle={ModalStyles.dropdownContent}
                  data={visibleTypes}
                  labelField="label"
                  valueField="value"
                  value={selectedVisible?.label}
                  placeholder={selectedVisible?.label}
                  onChange={(item) => {
                    setSelectedVisible(item);
                  }}
                />
              </View>
              <View style={styles.dropdownWrapper}>
                <Dropdown
                  style={[ModalStyles.dropdown, { width: '100%' }]}
                  placeholderStyle={ModalStyles.placeholderStyle}
                  selectedTextStyle={ModalStyles.selectedTextStyle}
                  containerStyle={ModalStyles.dropdownContent}
                  data={allYears}
                  labelField="label"
                  valueField="value"
                  value={selectedYear?.label}
                  placeholder={selectedYear?.label}
                  dropdownPosition="top"
                  onChange={(item) => {
                    setSelectedYear(item);
                  }}
                />
              </View>
            </View>
          ) : null}
        </View>
        <View style={{ gap: 16 }}>
          <Button
            children="Filter"
            onPress={() => {
              saveFilterSettings();
              handleApplyFilter();
              setType(
                tilesType.value === 2 ? 'dare' : tilesType.value === 1 ? 'countries' : 'regions'
              );
              handleCloseFilter();
            }}
          />
          <Button
            children="Clear"
            onPress={() => {
              setTilesType({ label: 'NM regions', value: 0 });
              setSelectedYear(allYears[0]);
              setSelectedVisible({ label: 'visited by', value: 0 });
              setRegionsFilter({ visitedLabel: 'by', year: moment().year() });
              setType('regions');
              if (!isPublicView && isLogged) {
                storage.set(
                  'filterSettings',
                  JSON.stringify({
                    type: 'regions',
                    tilesType: { label: 'NM regions', value: 0 },
                    selectedYear: allYears[0],
                    selectedVisible: { label: 'visited by', value: 0 },
                    seriesFilter: {
                      visible: seriesVisible,
                      groups: selectedSeries,
                      status: selectedSeriesFilter,
                      applied: true
                    }
                  })
                );
              }
            }}
            variant={ButtonVariants.OPACITY}
            containerStyles={styles.closeBtn}
            textStyles={{ color: Colors.DARK_BLUE }}
          />
        </View>
      </View>
    );
  };

  const renderSeries = () => {
    return (
      <View style={styles.sceneContainer}>
        <View style={styles.optionsContainer}>
          <View style={[styles.row, { gap: 8 }]}>
            <Switch
              trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
              thumbColor={Colors.WHITE}
              onValueChange={setSeriesVisible}
              value={seriesVisible}
              style={{ transform: 'scale(0.8)' }}
            />
            <Text style={styles.textBold}>Show series</Text>
          </View>

          {isLogged ? (
            <View style={[styles.row, { justifyContent: 'space-between' }]}>
              <TouchableOpacity style={styles.row} onPress={() => setSelectedSeriesFilter(-1)}>
                <RadioButton.Android
                  value="all"
                  status={selectedSeriesFilter === -1 ? 'checked' : 'unchecked'}
                  onPress={() => setSelectedSeriesFilter(-1)}
                  color={Colors.DARK_BLUE}
                />
                <Text style={styles.textBold}>All items</Text>
              </TouchableOpacity>

              <TouchableOpacity style={styles.row} onPress={() => setSelectedSeriesFilter(1)}>
                <RadioButton.Android
                  value="visited"
                  status={selectedSeriesFilter === 1 ? 'checked' : 'unchecked'}
                  onPress={() => setSelectedSeriesFilter(1)}
                  color={Colors.DARK_BLUE}
                />
                <Text style={styles.textBold}>Visited</Text>
              </TouchableOpacity>

              <TouchableOpacity style={styles.row} onPress={() => setSelectedSeriesFilter(0)}>
                <RadioButton.Android
                  value="not-visited"
                  status={selectedSeriesFilter === 0 ? 'checked' : 'unchecked'}
                  onPress={() => setSelectedSeriesFilter(0)}
                  color={Colors.DARK_BLUE}
                />
                <Text style={styles.textBold}>Not visited</Text>
              </TouchableOpacity>
            </View>
          ) : null}

          <MultiSelect
            style={[ModalStyles.dropdown, { width: '100%' }]}
            placeholderStyle={[ModalStyles.placeholderStyle]}
            selectedTextStyle={ModalStyles.selectedTextStyle}
            containerStyle={[ModalStyles.dropdownContent, {}]}
            data={[
              { label: 'Select all', value: 'all' },
              { label: 'Select none', value: 'none' },
              ...series
            ]}
            labelField="label"
            valueField="value"
            value={selectedSeries}
            placeholder="Select series"
            dropdownPosition="top"
            activeColor="#E7E7E7"
            search={true}
            searchPlaceholder="Search"
            inputSearchStyle={ModalStyles.search}
            searchQuery={(keyword, item) =>
              item.toLowerCase().includes(keyword.toLowerCase()) &&
              item !== 'Select all' &&
              item !== 'Select none'
            }
            flatListProps={{ initialNumToRender: 30, maxToRenderPerBatch: 10 }}
            onChange={(item) => {
              if (item.includes('all')) {
                setSelectedSeries(series.map((item) => item.value));
              } else if (item.includes('none')) {
                setSelectedSeries([]);
              } else {
                setSelectedSeries(item);
              }
            }}
            renderItem={(item) => (
              <View style={styles.multiOption}>
                <View style={[styles.row, { gap: 8, flex: 1 }]}>
                  <Image source={{ uri: API_HOST + item.icon }} width={20} height={20} />
                  <Text style={styles.optionText}>{item.label}</Text>
                </View>

                {selectedSeries.includes(item.value) && (
                  <CheckSvg fill={Colors.DARK_BLUE} height={8} />
                )}
              </View>
            )}
            renderSelectedItem={(item, unSelect) => {
              return null;
            }}
          />
        </View>
        <View style={{ gap: 16 }}>
          <Button
            children="Filter"
            onPress={() => {
              setSeriesFilter &&
                setSeriesFilter({
                  visible: seriesVisible,
                  groups: selectedSeries,
                  applied: true,
                  status: selectedSeriesFilter
                });
              saveFilterSettings();
              handleCloseFilter();
            }}
          />
          <Button
            children="Clear"
            onPress={() => {
              setSelectedSeries(series?.map((item) => item.value));
              setSelectedSeriesFilter(-1);
              setSeriesVisible(true);
              setSeriesFilter &&
                setSeriesFilter({ visible: true, groups: [], applied: false, status: -1 });
              if (!isPublicView && isLogged) {
                storage.set(
                  'filterSettings',
                  JSON.stringify({
                    type: tilesType.value,
                    tilesType,
                    selectedYear,
                    selectedVisible,
                    seriesFilter: {
                      visible: true,
                      groups: series?.map((item) => item.value),
                      status: -1,
                      applied: false
                    }
                  })
                );
              }
            }}
            variant={ButtonVariants.OPACITY}
            containerStyles={styles.closeBtn}
            textStyles={{ color: Colors.DARK_BLUE }}
          />
        </View>
      </View>
    );
  };

  const toggleSettingsSwitch = async () => {
    if (!isSharing) {
      handleGetLocation();
    } else {
      setIsSharing(false);
      setSettings({ token, sharing: 0 });
      setShowNomads && setShowNomads(false);
      storage.set('showNomads', false);
    }
  };

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

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

  const getLocation = async () => {
    setIsSharing(true);
    setSettings(
      { token, sharing: 1 },
      {
        onSuccess: async () => {
          let currentLocation = await Location.getCurrentPositionAsync({
            accuracy: Location.Accuracy.Balanced
          });

          updateLocation({
            token,
            lat: currentLocation.coords.latitude,
            lng: currentLocation.coords.longitude
          });
        }
      }
    );
  };

  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 toggleNomadsSwitch = () => {
    setShowNomads && setShowNomads(!showNomads);
    storage.set('showNomads', !showNomads);
  };

  const renderNomads = () => {
    return (
      <View style={[styles.sceneContainer, { flex: 0 }]}>
        <View style={styles.textContainer}>
          <Text style={styles.textWithIcon}>
            Your location is shared each time you press the{'  '}
            <View style={styles.icon}>
              <LocationIcon width={12} height={12} />
            </View>
            {'  '}
            button.
          </Text>
          <Text style={styles.text}>Your location is shared with ~250m radius precision.</Text>
        </View>
        <TouchableOpacity
          style={[
            styles.alignStyle,
            styles.buttonWrapper,
            {
              justifyContent: 'space-between'
            }
          ]}
          onPress={toggleNomadsSwitch}
          disabled={!isSharing}
        >
          <View style={styles.alignStyle}>
            <UsersIcon
              fill={isSharing ? Colors.DARK_BLUE : Colors.LIGHT_GRAY}
              width={20}
              height={20}
            />
            <Text style={[styles.buttonLabel, !isSharing ? { color: Colors.LIGHT_GRAY } : {}]}>
              Show nomads
            </Text>
          </View>
          <View>
            <Switch
              trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
              thumbColor={Colors.WHITE}
              onValueChange={toggleNomadsSwitch}
              value={showNomads}
              style={{ transform: 'scale(0.8)' }}
              disabled={!isSharing}
            />
          </View>
        </TouchableOpacity>

        <TouchableOpacity
          style={[
            styles.alignStyle,
            styles.buttonWrapper,
            {
              justifyContent: 'space-between'
            }
          ]}
          onPress={toggleSettingsSwitch}
        >
          <View style={styles.alignStyle}>
            <SharingIcon fill={Colors.DARK_BLUE} width={20} height={20} />
            <Text style={styles.buttonLabel}>Share location</Text>
          </View>
          <View>
            <Switch
              trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
              thumbColor={Colors.WHITE}
              onValueChange={toggleSettingsSwitch}
              value={isSharing}
              style={{ transform: 'scale(0.8)' }}
            />
          </View>
        </TouchableOpacity>
        <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?"
        />
      </View>
    );
  };

  const renderScene = ({ route }: { route: any }) => {
    switch (route.key) {
      case 'regions':
        return renderRegions();
      case 'series':
        return renderSeries();
      case 'nomads':
        return renderNomads();
      default:
        return null;
    }
  };

  const isSmallScreen = Dimensions.get('window').width < 383;

  return (
    <ReactModal
      isVisible={isFilterVisible}
      onBackdropPress={handleCloseFilter}
      onBackButtonPress={handleCloseFilter}
      style={styles.modal}
      statusBarTranslucent={true}
      presentationStyle="overFullScreen"
    >
      <View style={[styles.modalContainer, { height: 400 }]}>
        <TabView
          navigationState={{ index, routes }}
          renderScene={renderScene}
          onIndexChange={setIndex}
          lazy={true}
          swipeEnabled={!isPublicView}
          renderTabBar={(props) =>
            !isPublicView ? (
              <TabBar
                {...props}
                indicatorStyle={{ backgroundColor: Colors.DARK_BLUE }}
                style={styles.tabBar}
                tabStyle={styles.tabStyle}
                pressColor={'transparent'}
                renderLabel={({ route, focused }) => (
                  <Text
                    style={[
                      styles.tabLabel,
                      {
                        color: Colors.DARK_BLUE,
                        opacity: focused ? 1 : 0.4,
                        fontSize: isSmallScreen ? 13 : 14
                      }
                    ]}
                  >
                    {route.title}
                  </Text>
                )}
              />
            ) : null
          }
        />
      </View>
    </ReactModal>
  );
};

export default FilterModal;
