import firebase from 'firebase/app';
import 'firebase/messaging';
import { useEffect, useRef } from 'react';

import config from '../config';

import firebaseConfig from './firebaseConfig';
import { PushTokenAddMutation } from './__generated__/PushTokenAddMutation.graphql';
import { PushTokenAdd, USER_PUSHENDPOINT_TYPE } from './PushTokenAddMutation';

export const useSWReg = () => {
  const onTokenRefresh = useRef<firebase.Unsubscribe>(null);
  const onMessage = useRef<firebase.Unsubscribe>(null);

  const [pushTokenAdd] = useMutation<PushTokenAddMutation>(PushTokenAdd);

  useEffect(() => {
    const registerSW = async () => {
      if (!firebase.messaging.isSupported()) {
        return;
      }

      if ('serviceWorker' in navigator) {
        const registration = await navigator.serviceWorker.getRegistration('/home/sw.js');

        if (!registration) {
          return;
        }

        if (!firebase.apps.length) {
          firebase.initializeApp(firebaseConfig);
        }

        const messaging = firebase.messaging();

        messaging.usePublicVapidKey(config.FIREBASE_VAPID);
        messaging.useServiceWorker(registration);

        try {
          const permission = await Notification.requestPermission();

          if (permission === 'granted') {
            const token = await messaging.getToken();

            const config = {
              variables: {
                input: {
                  token,
                  os: USER_PUSHENDPOINT_TYPE.WEB,
                },
              },
            };

            pushTokenAdd(config);
          }
        } catch (err) {
          if (err.code === 'messaging/permission-blocked') {
            // eslint-disable-next-line
            console.log('Please Unblock Notification Request Manually: ', err);
          } else {
            // eslint-disable-next-line
            console.log('getToken err: ', err);
          }
        }

        onTokenRefresh.current = messaging.onTokenRefresh(async () => {
          const token = await messaging.getToken();

          const config = {
            variables: {
              input: {
                token,
                os: USER_PUSHENDPOINT_TYPE.WEB,
              },
            },
          };

          pushTokenAdd(config);
        });

        onMessage.current = messaging.onMessage((payload) => {
          const { data } = payload;

          registration.showNotification(data.title, {
            vibrate: [200],
            body: data.body,
            title: data.title,
            data,
          });
        });

        navigator.serviceWorker.addEventListener('message', (event) => {
        });
      }
    };

    registerSW();

    return () => {
      if (onTokenRefresh.current) {
        onTokenRefresh.current();
      }

      if (onMessage.current) {
        onMessage.current();
      }
    };
  }, []);
};
