import { useCallback, useEffect, useMemo, useState } from "react";
import { useAuthHeaders } from "./useAuthHeaders";
import { useRequest } from "ahooks";
import { isNotificationSupport } from "../utils/front";
import { getFirebaseToken } from "../utils/firebase-frontend";
import { App } from "antd";

const MSG_KEY = 'NOTIFICATION_CONTROL_MSG';

export const useNotificationControl = () => {
  const [token, setToken] = useState<string>();
  const headers = useAuthHeaders();
  const updateTokenReq = useRequest(async () => {
    if (!token || !headers) return;
    return fetch('/api/notification-token', {
      headers,
      method: 'PUT',
      body: JSON.stringify({ token }),
    });
  }, { manual: true, refreshDeps: [headers, token] });
  const unsetTokenReq = useRequest(async () => {
    if (!token || !headers) return;
    return fetch('/api/notification-token', {
      headers,
      method: 'DELETE',
      body: JSON.stringify({ token }),
    });
  }, { manual: true, refreshDeps: [headers, token] });
  const isTokenSetedReq = useRequest<Boolean, [string]>(async (token) => {
    if (!token || !headers) return false;
    return fetch(`/api/notification-token?token=${token}`, {
      headers,
      method: 'GET',
    })
      .then(res => res.json())
      .then(data => data.isSubscribed);
  }, { manual: true, refreshDeps: [headers, token]});
  const loading = useMemo(() => {
    return updateTokenReq.loading || unsetTokenReq.loading || isTokenSetedReq.loading;
  }, [updateTokenReq, unsetTokenReq, isTokenSetedReq]);
  useEffect(() => {
    if (!isNotificationSupport()) return;
    getFirebaseToken()
      .then(token => setToken(token))
      .catch(() => {});
  }, []);
  useEffect(() => {
    if (!token) return;
    isTokenSetedReq.runAsync(token);
  }, [token]);
  const isSupported = useMemo(() => {
    if (!isNotificationSupport()) return false;
    if (!token) return false;
    return true;
  }, [token]);
  const message = App.useApp().message;
  const handleEnableNotificationClick = useCallback(async () => {
    if (!token) return;
    const permission = await Notification.requestPermission();
    if (permission === 'denied') {
      const content = '已拒绝通知权限，请在浏览器设置中开启，或者移除该应用后重新添加至开始屏幕。';
      message.open({ key: MSG_KEY, content, type: 'warning' });
      return;
    }
    if (permission === 'granted') {
      message.open({ key: MSG_KEY, type: 'success', content: '已开启通知' });
      await updateTokenReq.runAsync();
      await isTokenSetedReq.runAsync(token);
      return;
    }
  }, [updateTokenReq, isTokenSetedReq, token]);
  const handleDisableNotificationClick = useCallback(async () => {
    if (!token) return;
    await unsetTokenReq.runAsync();
    await isTokenSetedReq.runAsync(token);
    message.open({ key: MSG_KEY, type: 'success', content: '已取消通知' });
  }, [unsetTokenReq, isTokenSetedReq, token]);
  const isNotificationEnable = useMemo(() => {
    return Boolean(isTokenSetedReq.data);
  }, [isTokenSetedReq]);
  return { loading, isSupported, handleDisableNotificationClick, handleEnableNotificationClick, isNotificationEnable };
};