import React, { 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,
  usePostUpdateLocationMutation
} from '@api/location';
import LocationIcon from 'assets/icons/location.svg';

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: updateLocation } = usePostUpdateLocationMutation();

  const [initialPermissionStatus, setInitialPermissionStatus] = useState<
    'granted' | 'denied' | 'undetermined' | null
  >(null);
  const [isSharingWithEveryone, setIsSharingWithEveryone] = useState(false);
  const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
  const [openSettingsVisible, setOpenSettingsVisible] = 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
        );
      }
    };

    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 || initialPermissionStatus === 'granted')
        ) {
          setSettings({ token, sharing: 0 });
          storage.set('showNomads', false);
          setIsSharingWithEveryone(false);
        }
      }
    });

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

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

      if ((status !== 'granted' && isSharingWithEveryone) || !isServicesEnabled) {
        setSettings({ token, sharing: 0 });
        storage.set('showNomads', false);
        setIsSharingWithEveryone(false);
      }
      setInitialPermissionStatus(status);
    };

    getInitialPermissionsStatus();
  }, []);

  useFocusEffect(() => {
    refetchData();
  });

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

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

  const toggleSettingsSwitch = async () => {
    if (!isSharingWithEveryone) {
      handleGetLocation();
    } else {
      setSettings({ token, sharing: 0 });
      storage.set('showNomads', false);
      setIsSharingWithEveryone(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 () => {
    let currentLocation = await Location.getCurrentPositionAsync({
      accuracy: Location.Accuracy.Balanced
    });
    setSettings({ token, sharing: 1 });
    setIsSharingWithEveryone(true);
    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);
    }
  };

  return (
    <PageWrapper>
      <Header label="Location sharing" />
      <View style={textStyles.container}>
        <Text style={textStyles.textWithIcon}>
          Your location is shared each time you press the{'  '}
          <View style={textStyles.icon}>
            <LocationIcon width={12} height={12} />
          </View>
          {'  '}
          button.
        </Text>
        <Text style={textStyles.text}>Your location is shared with ~250m 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 with everyone</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>

      <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?"
      />
    </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
  }
});

export default LocationSharingScreen;
