import { useCallback, useMemo } from 'react';
import FeatureGates from '@atlaskit/feature-gate-js-client';
import { useSmartLinkContext } from '@atlaskit/link-provider';
import { ACTION_RESOLVING, ACTION_UPDATE_METADATA_STATUS, cardAction } from '@atlaskit/linking-common';
import { auth } from '@atlaskit/outbound-auth-flow-client';
import { useAnalyticsEvents } from '../../common/analytics/generated/use-analytics-events';
import { SmartLinkStatus } from '../../constants';
import { AUTH_WINDOW_HEIGHT, AUTH_WINDOW_WIDTH, getWindowOpenFeatures } from '../../utils/window-open-features';
import { startUfoExperience } from '../analytics';
import { getByDefinitionId, getDefinitionId, getExtensionKey, getServices } from '../helpers';
import useInvokeClientAction from '../hooks/use-invoke-client-action';
import useResolve from '../hooks/use-resolve';
export const useSmartCardActions = (id, url) => {
  const resolveUrl = useResolve();
  const invokeClientAction = useInvokeClientAction({});
  const {
    fireEvent
  } = useAnalyticsEvents();
  const {
    store
  } = useSmartLinkContext();
  const {
    getState,
    dispatch
  } = store;
  const getSmartLinkState = useCallback(() => {
    var _getState$url;
    const {
      details,
      status,
      metadataStatus
    } = (_getState$url = getState()[url]) !== null && _getState$url !== void 0 ? _getState$url : {
      status: SmartLinkStatus.Pending
    };
    return {
      details,
      status,
      metadataStatus
    };
  }, [getState, url]);
  const setMetadataStatus = useCallback(metadataStatus => {
    dispatch(cardAction(ACTION_UPDATE_METADATA_STATUS, {
      url
    }, undefined, undefined, metadataStatus));
  }, [dispatch, url]);
  const resolve = useCallback(async (resourceUrl = url, isReloading = false, isMetadataRequest = false) => resolveUrl(resourceUrl, isReloading, isMetadataRequest, id), [id, resolveUrl, url]);
  const register = useCallback(() => {
    const {
      details
    } = getSmartLinkState();
    if (!details) {
      dispatch(cardAction(ACTION_RESOLVING, {
        url
      }));
      setMetadataStatus('pending');
    }
    return resolve();
  }, [getSmartLinkState, resolve, dispatch, url, setMetadataStatus]);
  const reload = useCallback(() => {
    const {
      details
    } = getSmartLinkState();
    const definitionId = getDefinitionId(details);
    if (definitionId) {
      getByDefinitionId(definitionId, getState()).map(url => resolve(url, true));
    } else {
      resolve(url, true);
    }
  }, [getSmartLinkState, url, getState, resolve]);
  const loadMetadata = useCallback(() => {
    const {
      metadataStatus
    } = getSmartLinkState();
    //metadataStatus will be undefined for SSR links only
    if (metadataStatus === undefined) {
      setMetadataStatus('pending');
      return resolve(url, false, true);
    }
  }, [getSmartLinkState, resolve, setMetadataStatus, url]);
  const authorize = useCallback(appearance => {
    const {
      details,
      status
    } = getSmartLinkState();
    const definitionId = getDefinitionId(details);
    const extensionKey = getExtensionKey(details);
    const services = getServices(details);
    // When authentication is triggered, let GAS know!
    if (status === 'unauthorized') {
      fireEvent('ui.button.clicked.connectAccount', {
        display: appearance,
        definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null
      });
    }
    if (status === 'forbidden') {
      fireEvent('ui.smartLink.clicked.tryAnotherAccount', {
        display: appearance,
        definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null
      });
    }
    if (services.length > 0) {
      fireEvent('screen.consentModal.viewed', {
        definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null
      });
      const shouldShowInPopupWindow = status === 'unauthorized' && FeatureGates.getExperimentValue('platform_sl_3p_auth_window_experiment', 'cohort', 'control') === 'test';
      const windowFeatures = shouldShowInPopupWindow ? getWindowOpenFeatures(AUTH_WINDOW_HEIGHT, AUTH_WINDOW_WIDTH) : undefined;
      auth(services[0].url, windowFeatures).then(() => {
        fireEvent('track.applicationAccount.connected', {
          definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null
        });
        startUfoExperience('smart-link-authenticated', id, {
          extensionKey,
          status: 'success'
        });
        fireEvent('operational.smartLink.connectSucceeded', {
          definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null
        });
        reload();
      }, err => {
        var _err$type;
        startUfoExperience('smart-link-authenticated', id, {
          extensionKey,
          status: err.type
        });
        fireEvent('operational.smartLink.connectFailed', {
          definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null,
          reason: (_err$type = err.type) !== null && _err$type !== void 0 ? _err$type : null
        });
        if (err.type === 'auth_window_closed') {
          fireEvent('ui.consentModal.closed', {
            display: appearance,
            definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null
          });
        }
        reload();
      });
    }
  }, [getSmartLinkState, id, reload, fireEvent]);
  const invoke = useCallback(async (opts, appearance) => {
    const {
      key,
      action
    } = opts;
    const source = opts.source || appearance;
    if (opts.type === 'client') {
      return await invokeClientAction({
        actionFn: opts.action.promise,
        actionType: action.type,
        display: source,
        extensionKey: key
      });
    }
  }, [invokeClientAction]);
  return useMemo(() => ({
    register,
    reload,
    authorize,
    invoke,
    loadMetadata
  }), [register, reload, authorize, invoke, loadMetadata]);
};