import type {ReactNode} from 'react';
import {Fragment, useCallback, useEffect, useState} from 'react';
import styled from '@emotion/styled';

import ButtonBar from 'sentry/components/buttonBar';
import {Button, LinkButton} from 'sentry/components/core/button';
import {SidebarPanelKey} from 'sentry/components/sidebar/types';
import {t} from 'sentry/locale';
import SidebarPanelStore from 'sentry/stores/sidebarPanelStore';
import type {Organization} from 'sentry/types/organization';
import useApi from 'sentry/utils/useApi';
import useDismissAlert from 'sentry/utils/useDismissAlert';

import {
  openAM2UpsellModal,
  openAM2UpsellModalSamePrice,
} from 'getsentry/actionCreators/modal';
import {sendReplayOnboardRequest} from 'getsentry/actionCreators/upsell';
import usePreviewData from 'getsentry/components/upgradeNowModal/usePreviewData';
import withSubscription from 'getsentry/components/withSubscription';
import type {Subscription} from 'getsentry/types';
import {PlanTier} from 'getsentry/types';
import trackGetsentryAnalytics from 'getsentry/utils/trackGetsentryAnalytics';

import {redirectToManage} from './upgradeNowModal/utils';

type ReplayOnboardingCTAUpsellProps = {
  organization: Organization;
  subscription: Subscription;
};

function ReplayOnboardingCTAUpsell({
  organization,
  subscription,
}: ReplayOnboardingCTAUpsellProps) {
  const hasBillingAccess = organization.access?.includes('org:billing');

  const api = useApi();
  const {dismiss, isDismissed} = useDismissAlert({
    key: `${organization.id}:dismiss-replay-update-plan-button`,
    expirationDays: 14,
  });

  useEffect(() => {
    trackGetsentryAnalytics('replay.list_page.viewed', {
      organization,
      surface: 'replay_onboarding_banner',
      planTier: subscription.planTier,
      canSelfServe: subscription.canSelfServe,
      channel: subscription.channel,
      has_billing_scope: organization.access?.includes('org:billing'),
    });
  }, [organization, subscription]);

  const onEmailOwner = useCallback(async () => {
    await sendReplayOnboardRequest({
      orgSlug: organization.slug,
      api,
      currentPlan: 'am1-non-beta',
      onSuccess: () => {
        dismiss();

        trackGetsentryAnalytics('replay.list_page.sent_email', {
          organization,
          surface: 'replay_onboarding_banner',
          planTier: subscription.planTier,
          canSelfServe: subscription.canSelfServe,
          channel: subscription.channel,
          has_billing_scope: organization.access?.includes('org:billing'),
        });
      },
    });
  }, [api, organization, subscription, dismiss]);

  const [didClickOpenModal, setDidClickOpenModal] = useState<boolean>();
  const previewData = usePreviewData({
    organization,
    subscription,
    enabled: !subscription.canSelfServe || !hasBillingAccess,
  });

  const handleOpenModal = useCallback(() => {
    setDidClickOpenModal(true);
  }, []);

  // Once we have 1) previewData, and 2) the user clicked the button; then open the modal
  useEffect(() => {
    if (!didClickOpenModal || previewData.loading) {
      return;
    }

    if (previewData.error) {
      if (hasBillingAccess) {
        // Redirect the user to the subscriptions page, where they will find important information.
        // If they wish to update their plan, we ask them to contact our sales/support team.
        redirectToManage(organization);
      }
      return;
    }

    setDidClickOpenModal(false);
    const onComplete = () => {
      dismiss();
      trackGetsentryAnalytics('replay.list_page.open_modal', {
        organization,
        surface: 'replay_onboarding_banner',
        planTier: subscription.planTier,
        canSelfServe: subscription.canSelfServe,
        channel: subscription.channel,
        has_billing_scope: hasBillingAccess,
        has_price_change: previewData.previewData.billedAmount !== 0,
      });
    };
    if (hasBillingAccess && previewData.previewData.billedAmount === 0) {
      openAM2UpsellModalSamePrice({
        organization,
        subscription,
        onComplete: () => {
          window.location.hash = 'replay-sidequest';
          SidebarPanelStore.activatePanel(SidebarPanelKey.REPLAYS_ONBOARDING);
          onComplete();
        },
        surface: 'replay',
        ...previewData,
      });
    } else {
      openAM2UpsellModal({
        organization,
        subscription,
        isActionDisabled: isDismissed,
        onComplete,
        surface: 'replay',
        ...previewData,
      });
    }
  }, [
    dismiss,
    didClickOpenModal,
    hasBillingAccess,
    isDismissed,
    organization,
    previewData,
    subscription,
  ]);

  const onClickManageSubscription = useCallback(() => {
    trackGetsentryAnalytics('replay.list_page.manage_sub', {
      organization,
      surface: 'replay_onboarding_banner',
      planTier: subscription.planTier,
      canSelfServe: subscription.canSelfServe,
      channel: subscription.channel,
      has_billing_scope: organization.access?.includes('org:billing'),
    });
  }, [organization, subscription]);

  if (!subscription.canSelfServe) {
    // Two cases:
    // 1. Touch sales -> They need to call sales.
    // 2. Managed/Partner accounts, that are not AM2 -> no update path. They're stuck for now.
    // In either case the Subscription Overview page has a note about what options are available.

    return (
      <Fragment>
        <h3>{t('Get to the root cause faster')}</h3>
        {subscription.channel === 'sales' ? null : (
          <p>{t('Your current plan doesn’t support Session Replay.')}</p>
        )}
        <p>
          {t(
            'Session Replay is a video-like reproduction of user interactions including page visits, mouse movements, clicks, and scrolls on a site or web app.'
          )}
        </p>
        <ButtonList gap={1}>
          <LinkButton
            to={`/settings/${organization.slug}/billing/overview/?referrer=replay_onboard-managed-cta`}
            onClick={onClickManageSubscription}
            priority="primary"
          >
            {t('Manage Subscription')}
          </LinkButton>
          <LinkButton href="https://docs.sentry.io/product/session-replay/" external>
            {t('Read Docs')}
          </LinkButton>
        </ButtonList>
      </Fragment>
    );
  }

  if ([PlanTier.MM1, PlanTier.MM2].includes(subscription.planTier as PlanTier)) {
    // MM1 & MM2 plans have no direct update path into AM2, prices could be wildly different
    // Members get an email, owners get to Manage Subscription
    return (
      <Fragment>
        <h3>{t('Get to the root cause faster')}</h3>
        <p>
          {t(
            'Update to the latest version of your plan to get access to Session Replay and get video-like reproduction of user interactions including page visits, mouse movements, clicks, and scrolls on a site or web app.'
          )}
        </p>
        <ButtonList gap={1}>
          {hasBillingAccess ? (
            <LinkButton
              to={`/settings/${organization.slug}/billing/overview/?referrer=replay_onboard_mmx-cta`}
              onClick={onClickManageSubscription}
              priority="primary"
            >
              {t('Manage Subscription')}
            </LinkButton>
          ) : (
            <Button disabled={isDismissed} onClick={onEmailOwner} priority="primary">
              {t('Request to Update Plan')}
            </Button>
          )}
          <LinkButton href="https://docs.sentry.io/product/session-replay/" external>
            {t('Read Docs')}
          </LinkButton>
        </ButtonList>
      </Fragment>
    );
  }

  // AM1 orgs get a Modal which includes the one-click "Update Now" button
  return (
    <Fragment>
      <h3>{t('Get to the root cause faster')}</h3>
      <p>
        {t(
          'Update to the latest version of your plan to get access to Session Replay and get video-like reproduction of user interactions including page visits, mouse movements, clicks, and scrolls on a site or web app.'
        )}
      </p>
      {hasBillingAccess ? null : (
        <p>{t('Notify your organization owner to start using Session Replay.')}</p>
      )}
      <ButtonList gap={1}>
        {hasBillingAccess ? (
          <Button
            onClick={handleOpenModal}
            priority="primary"
            disabled={didClickOpenModal && previewData.loading}
          >
            {t('Set Up Replays')}
          </Button>
        ) : (
          <Button disabled={isDismissed} onClick={onEmailOwner} priority="primary">
            {t('Notify Owner')}
          </Button>
        )}

        <LinkButton href="https://docs.sentry.io/product/session-replay/" external>
          {t('Read Docs')}
        </LinkButton>
      </ButtonList>
    </Fragment>
  );
}

const ButtonList = styled(ButtonBar)`
  grid-template-columns: repeat(auto-fit, minmax(130px, max-content));
`;

type ReplayOnboardingCTAProps = {
  children: ReactNode;
  organization: Organization;
  subscription: Subscription;
};

/**
 * The majority of orgs have the replays feature, so we check for that first
 */
function ReplayOnboardingCTA(props: ReplayOnboardingCTAProps) {
  const hasReplaysFeature = props.organization.features.includes('session-replay');
  if (hasReplaysFeature) {
    // AM2 orgs are ready to go, show the open source "Setup Replay SDK onboarding" panel
    // Also, any org that is trialing any AM2 plan is ready to go
    return <Fragment>{props.children}</Fragment>;
  }

  return <ReplayOnboardingCTAUpsell {...props} />;
}

export default withSubscription(ReplayOnboardingCTA, {noLoader: true});