import React, { useEffect, useState } from 'react';
import { View, Linking, Text, Switch, Platform, TouchableOpacity, AppState } from 'react-native';
import * as Notifications from 'expo-notifications';

import { Header, Loading, MenuButton, PageWrapper, WarningModal } from 'src/components';
import { usePushNotification } from 'src/contexts/PushNotificationContext';
import { usePostSaveNotificationTokenMutation } from '@api/user';
import { styles } from 'src/components/MenuButton/style';
import { StoreType, storage } from 'src/storage';
import { Colors } from 'src/theme';
import { NAVIGATION_PAGES } from 'src/types';

import ListIcon from 'assets/icons/notifications/list-check.svg';
import PeopleIcon from 'assets/icons/notifications/people-group-solid.svg';
import ChatIcon from 'assets/icons/notifications/messages.svg';
import GearIcon from 'assets/icons/notifications/gear-solid.svg';
import BellIcon from 'assets/icons/notifications/bell-solid.svg';
import { useGetSettingsQuery, usePostSetSettingsMutation } from '@api/notifications';
import { useFocusEffect } from '@react-navigation/native';
import CalendarIcon from 'assets/icons/events/calendar-solid.svg';

const NotificationsScreen = ({ navigation }: { navigation: any }) => {
  const token = storage.get('token', StoreType.STRING) as string;
  const { data: notificationsSettings, refetch } = useGetSettingsQuery(token, !!token);

  const { mutateAsync: saveNotificationToken } = usePostSaveNotificationTokenMutation();
  const { isSubscribed, toggleSubscription, unsubscribeFromNotifications } = usePushNotification();
  const { mutateAsync: setNotificationsSettings } = usePostSetSettingsMutation();
  const [modalInfo, setModalInfo] = useState({
    visible: false,
    type: 'confirm',
    message: '',
    action: () => {}
  });
  const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState(false);
  const [initialPermissionStatus, setInitialPermissionStatus] = useState<
    'granted' | 'denied' | 'undetermined' | null
  >(null);
  const [isEnabledMessages, setIsEnabledMessages] = useState(false);

  const closeModal = () => {
    setModalInfo({ ...modalInfo, visible: false });
  };

  useEffect(() => {
    if (notificationsSettings) {
      const { settings } = notificationsSettings;
      setIsEnabledMessages(
        settings.some((setting) => setting.name === 'app-messages' && setting.active === 1)
      );
    }
  }, [notificationsSettings]);

  const handleSubscribe = async () => {
    const deviceData = await registerForPushNotificationsAsync();

    if (deviceData?.notificationToken) {
      toggleSubscription();
      await saveNotificationToken({
        token,
        platform: deviceData.platform,
        n_token: deviceData.notificationToken
      });
      refetchData();
    }
  };

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

        if (initialPermissionStatus !== 'granted' && currentStatus === 'granted') {
          await handleSubscribe();
          setInitialPermissionStatus(currentStatus);
        } else if (
          currentStatus !== 'granted' &&
          (isSubscribed || initialPermissionStatus === 'granted')
        ) {
          unsubscribeFromNotifications();
        }
      }
    });

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

  useEffect(() => {
    const getInitialPermissionsStatus = async () => {
      const status = await checkNotificationPermissions();
      if (status !== 'granted' && isSubscribed) {
        unsubscribeFromNotifications();
      }
      setInitialPermissionStatus(status);
    };

    getInitialPermissionsStatus();
  }, []);

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

  const checkNotificationPermissions = async () => {
    const { status } = await Notifications.getPermissionsAsync();
    return status;
  };

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

  if (!notificationsSettings) return <Loading />;

  const toggleSwitch = async () => {
    if (isSubscribed) {
      toggleSubscription();
    } else {
      const status = await checkNotificationPermissions();
      if (status !== 'granted') {
        setModalInfo({
          visible: true,
          type: 'success',
          message:
            'To use this feature we need your permission to access your notifications. If you press OK your system will ask you to confirm permission to receive notifications from NomadMania.',
          action: () => setShouldOpenWarningModal(true)
        });
      } else {
        handleSubscribe();
      }
    }
  };

  async function registerForPushNotificationsAsync() {
    const existingStatus = await checkNotificationPermissions();
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      setModalInfo({
        visible: true,
        type: 'success',
        message:
          'NomadMania app needs notification permissions to function properly. Open settings?',
        action: () =>
          Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings()
      });
      return null;
    }
    const deviceData = await Notifications.getDevicePushTokenAsync();
    console.log('deviceData', deviceData);

    if (Platform.OS === 'android') {
      Notifications.setNotificationChannelAsync('default', {
        name: 'default',
        importance: Notifications.AndroidImportance.MAX,
        vibrationPattern: [0, 250, 250, 250],
        lightColor: '#FF231F7C'
      });
    }
    storage.set('deviceToken', deviceData.data);

    return { notificationToken: deviceData.data ?? '', platform: deviceData.type ?? '' };
  }

  const handleToggleMessages = async () => {
    const dataToUpdate = { 'app-messages': isEnabledMessages ? 0 : 1 };
    setIsEnabledMessages(!isEnabledMessages);

    await setNotificationsSettings({
      token,
      settings: JSON.stringify(dataToUpdate)
    });
    refetchData();
  };

  return (
    <PageWrapper>
      <Header label="Notifications" />
      <TouchableOpacity
        style={[
          styles.alignStyle,
          styles.buttonWrapper,
          {
            justifyContent: 'space-between'
          }
        ]}
        onPress={toggleSwitch}
      >
        <View style={styles.alignStyle}>
          <BellIcon fill={Colors.DARK_BLUE} width={20} height={20} />
          <Text style={styles.buttonLabel}>Enable notifications</Text>
        </View>
        <View>
          <Switch
            trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
            thumbColor={Colors.WHITE}
            onValueChange={toggleSwitch}
            value={isSubscribed}
            style={{ transform: 'scale(0.8)' }}
          />
        </View>
      </TouchableOpacity>

      <TouchableOpacity
        style={[
          styles.alignStyle,
          styles.buttonWrapper,
          {
            justifyContent: 'space-between'
          }
        ]}
        onPress={handleToggleMessages}
        disabled={!isSubscribed}
      >
        <View style={styles.alignStyle}>
          <ChatIcon
            fill={isSubscribed ? Colors.DARK_BLUE : Colors.LIGHT_GRAY}
            width={20}
            height={20}
          />
          <Text style={[styles.buttonLabel, !isSubscribed ? { color: Colors.LIGHT_GRAY } : {}]}>
            Messages
          </Text>
        </View>
        <View>
          <Switch
            trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
            thumbColor={Colors.WHITE}
            onValueChange={handleToggleMessages}
            value={isEnabledMessages && isSubscribed}
            style={{ transform: 'scale(0.8)' }}
            disabled={!isSubscribed}
          />
        </View>
      </TouchableOpacity>

      {/* <MenuButton
        label="Notifications list"
        icon={
          <ListIcon
            fill={isSubscribed ? Colors.DARK_BLUE : Colors.LIGHT_GRAY}
            width={20}
            height={20}
          />
        }
        red={false}
        buttonFn={() => navigation.navigate(NAVIGATION_PAGES.NOTIFICATIONS_LIST as never)}
        disabled={!isSubscribed}
      /> */}

      <MenuButton
        label="Friends"
        icon={
          <PeopleIcon
            fill={isSubscribed ? Colors.DARK_BLUE : Colors.LIGHT_GRAY}
            width={20}
            height={20}
          />
        }
        red={false}
        buttonFn={() =>
          navigation.navigate(NAVIGATION_PAGES.FRIENDS_NOTIFICATIONS, {
            settings: notificationsSettings.settings,
            token
          } as never)
        }
        disabled={!isSubscribed}
      />

      <MenuButton
        label="Events"
        icon={<CalendarIcon fill={Colors.DARK_BLUE} width={20} height={20} />}
        red={false}
        buttonFn={() =>
          navigation.navigate(NAVIGATION_PAGES.EVENTS_NOTIFICATIONS, {
            settings: notificationsSettings.settings,
            token
          } as never)
        }
      />

      {/* <MenuButton
        label="System"
        icon={
          <GearIcon
            fill={isSubscribed ? Colors.DARK_BLUE : Colors.LIGHT_GRAY}
            width={20}
            height={20}
          />
        }
        red={false}
        buttonFn={() => navigation.navigate(NAVIGATION_PAGES.SYSTEM_NOTIFICATIONS as never)}
        disabled={!isSubscribed}
      /> */}

      <WarningModal
        isVisible={modalInfo.visible}
        onClose={closeModal}
        type={modalInfo.type}
        message={modalInfo.message}
        action={() => {
          modalInfo.action();
          closeModal();
        }}
        onModalHide={() => {
          if (shouldOpenWarningModal) {
            setShouldOpenWarningModal(false);
            handleSubscribe();
          }
        }}
      />
    </PageWrapper>
  );
};

export default NotificationsScreen;
