import Constants from 'expo-constants';
import * as Notifications from 'expo-notifications';
import * as Permissions from 'expo-permissions';
import { StackScreenProps } from '@react-navigation/stack';
import * as React from 'react';
import { useNavigation } from '@react-navigation/native';
import { WebView } from 'react-native-webview';
import useModel from 'flooks';
import { useMount } from 'ahooks';

import IM from './model';

import { useTranslation } from 'react-i18next';

import { SoundPlay } from '../utils/SoundUtils';
if (!__DEV__) {
  Notifications.setNotificationHandler({
    handleNotification: async () => ({
      shouldShowAlert: true,
      shouldPlaySound: false,
      shouldSetBadge: false,
    }),
  });
}

export default function NoticeScreen({
  navigation,
}: StackScreenProps<RootStackParamList, 'Login'>) {
  const { t } = useTranslation();
  const webRef = React.useRef();
  const {
    getChat,
    getSysNotice,
    userID,
    userSig,
    tim,
    setTim,
    initChat,
    updateChatInfo,
    sendPushNotification,
  } = useModel(IM, ['userID', 'userSig', 'tim']);
  useMount(() => {
    initChat();
  });

  const [expoPushToken, setExpoPushToken] = React.useState('');
  const [notification, setNotification] = React.useState(false);
  const notificationListener = React.useRef();
  const responseListener = React.useRef();

  React.useEffect(() => {
    if (!__DEV__) {
      registerForPushNotificationsAsync().then((token) =>
        setExpoPushToken(token)
      );

      notificationListener.current = Notifications.addNotificationReceivedListener(
        (notification) => {
          setNotification(notification);
        }
      );

      responseListener.current = Notifications.addNotificationResponseReceivedListener(
        (response) => {
          console.log(response);
        }
      );

      return () => {
        Notifications.removeNotificationSubscription(notificationListener);
        Notifications.removeNotificationSubscription(responseListener);
      };
    }
  }, []);

  React.useEffect(() => {
    if (userSig && tim)
      tim.injectJavaScript(
        `window.chatLogin(${JSON.stringify(userID)},${JSON.stringify(userSig)})`
      );
  }, [userSig, tim]);

  return (
    <>
      <WebView
        ref={webRef}
        source={{
          uri: `http://dingdong.izouma.com/map/tim`,
        }}
        onMessage={({ nativeEvent }) => {
          console.log(nativeEvent);
          const info =
            nativeEvent.data.indexOf('{') !== -1
              ? JSON.parse(nativeEvent.data)
              : {};
          console.log(info);
          if (Array.isArray(info)) {
            getChat();
            const message = info[0];
            if (/^\d{n}$/.test(message.from)) {
              updateChatInfo(message);
            } else {
              getSysNotice();
              const { payload } = message;
              let body = payload ? payload.text : '';
              if (body.indexOf('voice_') !== -1) {
                const textInfo = body.split(';');
                body = textInfo[1];
                SoundPlay(textInfo[0]);
              }
              sendPushNotification('系统通知', body);
            }
          }
        }}
        onLoadEnd={() => {
          setTim(webRef.current);
        }}
      />
    </>
  );
}

async function registerForPushNotificationsAsync() {
  let token;
  if (Constants.isDevice) {
    const { status: existingStatus } = await Permissions.getAsync(
      Permissions.NOTIFICATIONS
    );
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      alert('Failed to get push token for push notification!');
      return;
    }
    token = (await Notifications.getExpoPushTokenAsync()).data;
    console.log(token);
  } else {
    alert('Must use physical device for Push Notifications');
  }

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

  return token;
}
