import type { ConnectorMetadata } from '@logto/schemas';
import { useCallback, useContext } from 'react';

import { invokeSocialSignIn } from '@/apis/social';
import { getLogtoNativeSdk, isNativeWebview } from '@/utils/native-sdk';
import { generateState, storeState, buildSocialLandingUri } from '@/utils/social-connectors';

import useApi from './use-api';
import { PageContext } from './use-page-context';
import useTerms from './use-terms';

const useSocial = () => {
  const { experienceSettings, theme } = useContext(PageContext);
  const { termsValidation } = useTerms();

  const { run: asyncInvokeSocialSignIn } = useApi(invokeSocialSignIn);

  const nativeSignInHandler = useCallback((redirectTo: string, connector: ConnectorMetadata) => {
    const { id: connectorId, platform } = connector;

    const redirectUri =
      platform === 'Universal'
        ? buildSocialLandingUri(`/social/landing/${connectorId}`, redirectTo).toString()
        : redirectTo;

    getLogtoNativeSdk()?.getPostMessage()({
      callbackUri: `${window.location.origin}/sign-in/social/${connectorId}`,
      redirectTo: redirectUri,
    });
  }, []);

  const invokeSocialSignInHandler = useCallback(
    async (connector: ConnectorMetadata) => {
      if (!(await termsValidation())) {
        return;
      }

      const { id: connectorId } = connector;

      const state = generateState();
      storeState(state, connectorId);

      const result = await asyncInvokeSocialSignIn(
        connectorId,
        state,
        `${window.location.origin}/callback/${connectorId}`
      );

      if (!result?.redirectTo) {
        return;
      }

      // Invoke Native Social Sign In flow
      if (isNativeWebview()) {
        nativeSignInHandler(result.redirectTo, connector);

        return;
      }

      // Invoke Web Social Sign In flow
      window.location.assign(result.redirectTo);
    },
    [asyncInvokeSocialSignIn, nativeSignInHandler, termsValidation]
  );

  return {
    theme,
    socialConnectors: experienceSettings?.socialConnectors ?? [],
    invokeSocialSignIn: invokeSocialSignInHandler,
  };
};

export default useSocial;
