import { useCallback, useMemo, useRef } from 'react';
import { extractSmartLinkProvider, extractSmartLinkTitle } from '@atlaskit/link-extractors';
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 { fg } from '@atlaskit/platform-feature-flags';
import { ROVO_POST_MESSAGE_EVENT_TYPE } from '@atlaskit/rovo-triggers/post-message-to-pubsub';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { useAnalyticsEvents } from '../../common/analytics/generated/use-analytics-events';
import { SmartLinkStatus } from '../../constants';
import { getIsRovoChatEnabled } from '../../utils/rovo';
import { startUfoExperience } from '../analytics';
import { getByDefinitionId, getDefinitionId, getExtensionKey, getServices } from '../helpers';
import useActionFlags from '../hooks/use-action-flags';
import useInvokeClientAction from '../hooks/use-invoke-client-action';
import useResolve from '../hooks/use-resolve';
const POST_AUTH_CHAT_EXTENSION_KEY = 'google-object-provider';
// Smart Card resolver key differs from the consumer-facing Rovo payload key.
const POST_AUTH_CHAT_PAYLOAD_EXTENSION_KEY = 'google-drive';
const SMART_LINK_3P_POST_AUTH_SOURCE = 'smart-link-3p-post-auth';
const getPostAuthChatPayloadId = () => {
  if (typeof crypto !== 'undefined') {
    if (typeof crypto.randomUUID === 'function') {
      return crypto.randomUUID();
    }
    if (typeof crypto.getRandomValues === 'function') {
      const values = new Uint32Array(4);
      crypto.getRandomValues(values);
      return `smart-link-post-auth-chat-${Array.from(values, value => value.toString(16)).join('-')}`;
    }
  }
  return `smart-link-post-auth-chat-${Date.now()}`;
};
const sendPostAuthChatOpenMessage = (url, documentTitle) => {
  var _window$parent;
  if (typeof window === 'undefined' || typeof ((_window$parent = window.parent) === null || _window$parent === void 0 ? void 0 : _window$parent.postMessage) !== 'function') {
    return;
  }
  const payload = {
    type: 'chat-smartlink-3p-post-auth-launch',
    source: SMART_LINK_3P_POST_AUTH_SOURCE,
    openChat: true,
    openChatMode: 'mini-modal',
    data: {
      extensionKey: POST_AUTH_CHAT_PAYLOAD_EXTENSION_KEY,
      provider: 'Google Drive',
      projectContext: {
        projectId: url,
        projectName: documentTitle !== null && documentTitle !== void 0 ? documentTitle : 'Google Drive',
        projectUrl: url
      }
    }
  };
  window.parent.postMessage({
    eventType: ROVO_POST_MESSAGE_EVENT_TYPE,
    payload,
    payloadId: getPostAuthChatPayloadId()
  }, '*');
};
export const useSmartCardActions = (id, url) => {
  const resolveUrl = useResolve();
  const invokeClientAction = useInvokeClientAction({});
  const {
    fireEvent
  } = useAnalyticsEvents();
  const flags = useActionFlags();
  const {
    store,
    rovoOptions
  } = useSmartLinkContext();
  const rovoOptionsRef = useRef(rovoOptions);
  rovoOptionsRef.current = rovoOptions;
  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]);

  // Original resolve function — signature kept intact for maximum safety when FG is off.
  const resolve = useCallback(async (resourceUrl = url, isReloading = false, isMetadataRequest = false) => resolveUrl({
    url: resourceUrl,
    isReloading,
    isMetadataRequest,
    id
  }), [id, resolveUrl, url]);

  // New resolve function accepting ResolveUrlParams (minus 'id' which is closed over).
  // Used when FG is enabled to pass appearance to ORS.
  const resolveNew = useCallback(async (params = {}) => {
    const {
      url: resourceUrl = url,
      isReloading = false,
      isMetadataRequest = false,
      appearance
    } = params;
    return resolveUrl({
      url: resourceUrl,
      isReloading,
      isMetadataRequest,
      id,
      appearance
    });
  }, [id, resolveUrl, url]);

  /**
   * Register a smart link for resolution.
   * @param appearance - Card appearance hint for ORS to optimize response payload.
   *                     When 'inline', ORS returns minimal data (title, status).
   *                     When 'block' or 'embed', ORS returns full data including summary.
   */
  const register = useCallback(appearance => {
    const {
      details
    } = getSmartLinkState();
    if (!details) {
      dispatch(cardAction(ACTION_RESOLVING, {
        url
      }));
      // Always set metadataStatus to 'pending' during registration to prevent
      // loadMetadata from firing a duplicate concurrent fetch if a hover card
      // mounts while registration is in-flight. This matches pre-PR behaviour.
      setMetadataStatus('pending');
    }
    if (fg('platform_smartlink_inline_resolve_optimization')) {
      return resolveNew({
        url,
        appearance
      });
    }
    return resolve(url);
  }, [getSmartLinkState, resolve, resolveNew, dispatch, url, setMetadataStatus]);
  const reload = useCallback(appearance => {
    const {
      details
    } = getSmartLinkState();
    const definitionId = getDefinitionId(details);
    if (fg('platform_smartlink_inline_resolve_optimization')) {
      if (definitionId) {
        getByDefinitionId(definitionId, getState()).map(reloadUrl => resolveNew({
          url: reloadUrl,
          isReloading: true,
          appearance
        }));
      } else {
        resolveNew({
          url,
          isReloading: true,
          appearance
        });
      }
    } else {
      if (definitionId) {
        getByDefinitionId(definitionId, getState()).map(reloadUrl => resolve(reloadUrl, true));
      } else {
        resolve(url, true);
      }
    }
  }, [getSmartLinkState, url, getState, resolve, resolveNew]);

  /**
   * Load metadata for hover card preview.
   * This always requests 'block' appearance to get full data including summary.
   *
   * Inline optimized and SSR-resolved links keep metadataStatus pending until hover
   * requests the full block response.
   */
  const loadMetadata = useCallback(() => {
    const {
      metadataStatus
    } = getSmartLinkState();
    const needsBlockData = metadataStatus === undefined || metadataStatus === 'pending' && fg('platform_smartlink_inline_resolve_optimization');
    if (needsBlockData) {
      setMetadataStatus('pending');
      if (fg('platform_smartlink_inline_resolve_optimization')) {
        // Always request 'block' appearance for hover card metadata to get full data
        return resolveNew({
          url,
          isMetadataRequest: true,
          appearance: 'block'
        });
      }
      return resolve(url, false, true);
    }
  }, [getSmartLinkState, resolve, resolveNew, setMetadataStatus, url]);
  const authorize = useCallback(appearance => {
    const {
      details,
      status
    } = getSmartLinkState();
    const definitionId = getDefinitionId(details);
    const extensionKey = getExtensionKey(details);
    const isSupportedPostAuthChatExtensionKey = extensionKey === POST_AUTH_CHAT_EXTENSION_KEY;
    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
      });
      auth(services[0].url).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
        });

        // Post-auth Chat onboarding: auto-open Rovo Chat mini-modal with the
        // authed 3P link as context, for supported providers (e.g. Google Drive).
        // Provider eligibility is derived from the pre-auth SmartLink state.
        const isEligibleForPostAuthChat = status === 'unauthorized' && isSupportedPostAuthChatExtensionKey && fg('platform_sl_3p_post_auth_chat_open_fg') && getIsRovoChatEnabled(rovoOptionsRef.current);

        // Experiment check: fires exposure for both control and treatment.
        // Only reached after eligibility preconditions + kill switch pass, so
        // exposure is counted for the triggered eligible pool.
        const isPostAuthChatTreatment = isEligibleForPostAuthChat && expValEquals('platform_sl_3p_post_auth_chat_open_exp', 'isEnabled', true);
        if (status === 'unauthorized' && !isPostAuthChatTreatment) {
          const provider = extractSmartLinkProvider(details);
          flags.showConnectFlag({
            id: `smart-link-connect-success-${extensionKey}`,
            provider
          });
        }
        reload();
        if (isPostAuthChatTreatment) {
          sendPostAuthChatOpenMessage(url, extractSmartLinkTitle(details));
        }
      }, 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, flags, url]);
  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]);
};