import React, { useCallback, useEffect, useState } from 'react';
import {
  View,
  Linking,
  Text,
  Switch,
  Platform,
  TouchableOpacity,
  AppState,
  StyleSheet
} from 'react-native';
import * as Location from 'expo-location';

import { Header, PageWrapper, WarningModal } from 'src/components';
import { styles } from 'src/components/MenuButton/style';
import { StoreType, storage } from 'src/storage';
import { Colors } from 'src/theme';

import UsersIcon from 'assets/icons/bottom-navigation/travellers.svg';
import { useFocusEffect } from '@react-navigation/native';
import {
  usePostGetSettingsQuery,
  usePostSetSettingsMutation,
  usePostSetSettingsRegionsMutation,
  usePostUpdateLocationMutation
} from '@api/location';
import LocationIcon from 'assets/icons/location.svg';
import {
  startBackgroundLocationUpdates,
  stopBackgroundLocationUpdates
} from 'src/utils/backgroundLocation';

const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
  const token = storage.get('token', StoreType.STRING) as string;
  const { data: locationSettings, refetch } = usePostGetSettingsQuery(token, !!token);
  const { mutateAsync: setSettings } = usePostSetSettingsMutation();
  const { mutateAsync: setSettingsRegions } = usePostSetSettingsRegionsMutation();

  const { mutateAsync: updateLocation } = usePostUpdateLocationMutation();

  const [initialPermissionStatus, setInitialPermissionStatus] = useState<
    'granted' | 'denied' | 'undetermined' | null
  >(null);
  const [isSharingWithEveryone, setIsSharingWithEveryone] = useState(false);
  const [canMarkRegions, setCanMarkRegions] = useState(false);
  const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
  const [openSettingsVisible, setOpenSettingsVisible] = useState<boolean>(false);
  const [openSettingsBackgroundVisible, setOpenSettingsBackgroundVisible] =
    useState<boolean>(false);

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

        setIsSharingWithEveryone(
          locationSettings.sharing !== 0 && status === 'granted' && isServicesEnabled
        );
        setCanMarkRegions(
          locationSettings.sharing_regions !== 0 && status === 'granted' && isServicesEnabled
        );
      }
    };

    syncSettings();
  }, [locationSettings]);

  useEffect(() => {
    const subscription = AppState.addEventListener('change', async (nextAppState) => {
      if (nextAppState === 'active' && initialPermissionStatus !== null) {
        const currentStatus = await checkLocationPermissions();

        if (initialPermissionStatus !== 'granted' && currentStatus === 'granted') {
          setInitialPermissionStatus(currentStatus);
        } else if (
          currentStatus !== 'granted' &&
          (isSharingWithEveryone || canMarkRegions || initialPermissionStatus === 'granted')
        ) {
          setSettings({ token, sharing: 0 });
          setSettingsRegions({ token, sharing: 0 });

          storage.set('showNomads', false);
          setIsSharingWithEveryone(false);
          setCanMarkRegions(false);
          await stopBackgroundLocationUpdates();
        }
      }
    });

    return () => {
      subscription.remove();
    };
  }, [initialPermissionStatus]);

  useEffect(() => {
    const getInitialPermissionsStatus = async () => {
      const status = await checkLocationPermissions();
      const isServicesEnabled = await Location.hasServicesEnabledAsync();

      if (
        (status !== 'granted' && (isSharingWithEveryone || canMarkRegions)) ||
        !isServicesEnabled
      ) {
        setSettings({ token, sharing: 0 });
        setSettingsRegions({ token, sharing: 0 });

        storage.set('showNomads', false);
        setIsSharingWithEveryone(false);
        setCanMarkRegions(false);
        await stopBackgroundLocationUpdates();
      }
      setInitialPermissionStatus(status);
    };

    getInitialPermissionsStatus();
  }, []);

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

  const refetchData = async () => {
    await refetch();
  };

  const checkLocationPermissions = async () => {
    let { status } = await Location.getForegroundPermissionsAsync();
    return status;
  };

  const toggleSettingsSwitch = async () => {
    if (!isSharingWithEveryone) {
      handleGetLocation(true);
    } else {
      setSettings({ token, sharing: 0 });
      storage.set('showNomads', false);
      setIsSharingWithEveryone(false);
    }
  };

  const toggleRegionSettingsSwitch = async () => {
    if (!canMarkRegions) {
      handleGetLocation(false);
    } else {
      setSettingsRegions({ token, sharing: 0 });

      setCanMarkRegions(false);
    }
  };

  const requestBackgroundPermissionSafe = async () => {
    await new Promise((resolve) => setTimeout(resolve, 300));
    return await Location.requestBackgroundPermissionsAsync();
  };

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

    if (status === 'granted' && isServicesEnabled) {
      getLocationToggle(isSettings);
      const bgStatus = await Location.getBackgroundPermissionsAsync();
      if (bgStatus.status !== 'granted') {
        // const { status } = await requestBackgroundPermissionSafe();
        // if (status === Location.PermissionStatus.GRANTED) {
        //   await startBackgroundLocationUpdates();
        // } else {
          await stopBackgroundLocationUpdates();
          // setOpenSettingsBackgroundVisible(true);
        // }
      } else {
        // await startBackgroundLocationUpdates();
      }
    } else if (!canAskAgain || !isServicesEnabled) {
      setOpenSettingsVisible(true);
    } else {
      setAskLocationVisible(true);
    }
  };

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

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

  const getLocationToggle = async (isSettings: boolean) => {
    if (isSettings) {
      setSettings({ token, sharing: 1 });
      setIsSharingWithEveryone(true);
    } else {
      setSettingsRegions({ token, sharing: 1 });
      setCanMarkRegions(true);
    }

    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();
      const bgStatus = await Location.getBackgroundPermissionsAsync();
      if (bgStatus.status !== 'granted') {
        // const { status } = await requestBackgroundPermissionSafe();
        // if (status === Location.PermissionStatus.GRANTED) {
        //   await startBackgroundLocationUpdates();
        // } else {
          await stopBackgroundLocationUpdates();
          // setOpenSettingsBackgroundVisible(true);
        // }
      } else {
        // await startBackgroundLocationUpdates();
      }
    } else if (!canAskAgain || !isServicesEnabled) {
      setOpenSettingsVisible(true);
    }
  };

  return (
    <PageWrapper>
      <Header label="Location sharing" />
      <View style={textStyles.container}>
        <Text style={textStyles.text}>The location is shared with 1 km radius precision.</Text>
      </View>
      <TouchableOpacity
        style={[
          styles.alignStyle,
          styles.buttonWrapper,
          {
            justifyContent: 'space-between'
          }
        ]}
        onPress={toggleSettingsSwitch}
      >
        <View style={styles.alignStyle}>
          <UsersIcon fill={Colors.DARK_BLUE} width={20} height={20} />
          <Text style={styles.buttonLabel}>Share location to see others</Text>
        </View>
        <View>
          <Switch
            trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
            thumbColor={Colors.WHITE}
            onValueChange={toggleSettingsSwitch}
            value={isSharingWithEveryone}
            style={{ transform: 'scale(0.8)' }}
          />
        </View>
      </TouchableOpacity>

      {/* <TouchableOpacity
        style={[
          styles.alignStyle,
          styles.buttonWrapper,
          {
            justifyContent: 'space-between',
            height: undefined,
            paddingVertical: 8
          }
        ]}
        onPress={toggleRegionSettingsSwitch}
      >
        <View style={[styles.alignStyle, { flex: 1 }]}>
          <UsersIcon fill={Colors.DARK_BLUE} width={20} height={20} />
          <Text style={[styles.buttonLabel, { flex: 1 }]}>
            Share location to automatically mark a region or DARE place as visited
          </Text>
        </View>
        <View>
          <Switch
            trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
            thumbColor={Colors.WHITE}
            onValueChange={toggleRegionSettingsSwitch}
            value={canMarkRegions}
            style={{ transform: 'scale(0.8)' }}
          />
        </View>
      </TouchableOpacity> */}

      <View style={{ marginVertical: 12, gap: 6 }}>
        <Text style={[textStyles.text, textStyles.boldText]}>
          At NomadMania, we respect your privacy.
        </Text>
        <Text style={[textStyles.text]}>
          If you choose to share your location, it can be used to:
        </Text>
        <View style={[textStyles.bulletItem]}>
          <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
          <Text style={[textStyles.text, { flex: 1 }]}>
            show your current location to other users who also share theirs
          </Text>
        </View>
        {/* <View style={textStyles.bulletItem}>
          <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
          <Text style={[textStyles.text, { flex: 1 }]}>
            automatically mark regions (and DARE places) as visited in the Regions section as well
            as in the Trips section
          </Text>
        </View> */}

        <Text style={[textStyles.text, { marginTop: 6 }]}>
          You can choose how you want to share your location:
        </Text>
        <View style={[textStyles.bulletItem]}>
          <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
          <Text style={[textStyles.text, { flex: 1 }]}>
            <Text style={textStyles.boldText}>Only when the app is open</Text> – Your location
            updates only when you open the app. This uses less battery but may be less accurate.
          </Text>
        </View>
        {/* <View style={textStyles.bulletItem}>
          <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
          <Text style={[textStyles.text, { flex: 1 }]}>
            <Text style={textStyles.boldText}>In the background</Text> – Your location stays up to
            date even when the app is closed. Other users see your latest location, and visited
            regions and DARE places are marked automatically.
          </Text>
        </View> */}
        <Text style={[textStyles.text]}>
          You’re always in control, and you can change these settings anytime in the app{' '}
          <Text
            style={{ color: Colors.ORANGE }}
            onPress={() =>
              Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings()
            }
          >
            Settings
          </Text>{' '}
          section.
        </Text>
      </View>

      <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 || openSettingsBackgroundVisible}
        onClose={() => {
          setOpenSettingsVisible(false);
          setOpenSettingsBackgroundVisible(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={
          openSettingsBackgroundVisible
            ? "NomadMania app needs background location access to update your location automatically. Please select 'Always' in location permissions. Open settings?"
            : 'NomadMania app needs location permissions to function properly. Open settings?'
        }
      />
    </PageWrapper>
  );
};

const textStyles = StyleSheet.create({
  container: { flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', marginBottom: 12 },
  textWithIcon: { lineHeight: 26, fontSize: 12, color: Colors.DARK_BLUE, fontStyle: 'italic' },
  text: { fontSize: 12, color: Colors.DARK_BLUE, fontStyle: 'italic' },
  icon: {
    backgroundColor: Colors.WHITE,
    width: 26,
    height: 26,
    borderRadius: 13,
    alignItems: 'center',
    justifyContent: 'center',
    shadowColor: 'rgba(0, 0, 0, 0.2)',
    shadowOffset: { width: 0, height: 2 },
    shadowRadius: 4,
    shadowOpacity: 1,
    elevation: 8
  },
  boldText: {
    fontWeight: '700'
  },
  bulletItem: {
    flexDirection: 'row',
    alignItems: 'center',
    width: '100%'
  },
  bulletIcon: {
    fontSize: 12,
    fontWeight: '700',
    marginHorizontal: 6,
    alignSelf: 'flex-start'
  }
});

export default LocationSharingScreen;
