import styled from '@emotion/styled';

import type {PromptResponse} from 'sentry/actionCreators/prompts';
import {
  makePromptsCheckQueryKey,
  promptsUpdate,
  usePromptsCheck,
} from 'sentry/actionCreators/prompts';
import Alert from 'sentry/components/alert';
import {Button, LinkButton} from 'sentry/components/button';
import ButtonBar from 'sentry/components/buttonBar';
import {IconClose, IconEdit} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {Project} from 'sentry/types';
import {promptIsDismissed} from 'sentry/utils/promptIsDismissed';
import {setApiQueryData, useQueryClient} from 'sentry/utils/queryClient';
import useApi from 'sentry/utils/useApi';
import useOrganization from 'sentry/utils/useOrganization';
import type {MetricRule} from 'sentry/views/alerts/rules/metric/types';
import {
  hasIgnoreArchivedFeatureFlag,
  ruleNeedsErrorMigration,
} from 'sentry/views/alerts/utils/migrationUi';

interface ErrorMigrationWarningProps {
  project?: Project;
  rule?: MetricRule;
}

const METRIC_ALERT_IGNORE_ARCHIVED_ISSUES = 'metric_alert_ignore_archived_issues';

function createdOrModifiedAfterMigration(rule: MetricRule) {
  const migrationDate = new Date('2023-12-11T00:00:00Z').getTime();
  return (
    (rule.dateCreated && new Date(rule.dateCreated).getTime() > migrationDate) ||
    (rule.dateModified && new Date(rule.dateModified).getTime() > migrationDate)
  );
}

/**
 * Displays a message to filter events from archived issues when the metric alert
 * is counting error events.
 */
export function ErrorMigrationWarning({project, rule}: ErrorMigrationWarningProps) {
  const api = useApi();
  const organization = useOrganization();
  const queryClient = useQueryClient();
  const showErrorMigrationWarning =
    rule && hasIgnoreArchivedFeatureFlag(organization) && ruleNeedsErrorMigration(rule);
  const isCreatedAfterMigration = rule && createdOrModifiedAfterMigration(rule);
  const prompt = usePromptsCheck(
    {
      organization,
      feature: METRIC_ALERT_IGNORE_ARCHIVED_ISSUES,
      projectId: project?.id,
    },
    {staleTime: Infinity, enabled: showErrorMigrationWarning && !isCreatedAfterMigration}
  );

  const isPromptDismissed =
    prompt.isSuccess && prompt.data.data
      ? promptIsDismissed({
          dismissedTime: prompt.data.data.dismissed_ts,
          snoozedTime: prompt.data.data.snoozed_ts,
        })
      : false;

  if (
    !showErrorMigrationWarning ||
    !rule ||
    isPromptDismissed ||
    isCreatedAfterMigration
  ) {
    return null;
  }

  const dismissPrompt = () => {
    promptsUpdate(api, {
      organization,
      projectId: project?.id,
      feature: METRIC_ALERT_IGNORE_ARCHIVED_ISSUES,
      status: 'dismissed',
    });

    // Update cached query data, set to dismissed
    setApiQueryData<PromptResponse>(
      queryClient,
      makePromptsCheckQueryKey({
        organization,
        feature: METRIC_ALERT_IGNORE_ARCHIVED_ISSUES,
        projectId: project?.id,
      }),
      () => {
        const dimissedTs = new Date().getTime() / 1000;
        return {
          data: {dismissed_ts: dimissedTs},
          features: {[METRIC_ALERT_IGNORE_ARCHIVED_ISSUES]: {dismissed_ts: dimissedTs}},
        };
      }
    );
  };

  return (
    <Alert
      type="warning"
      showIcon
      trailingItems={
        <ButtonBar gap={1}>
          <LinkButton
            to={{
              pathname: `/organizations/${organization.slug}/alerts/metric-rules/${
                project?.slug ?? rule?.projects?.[0]
              }/${rule.id}/`,
              query: {migration: '1'},
            }}
            size="xs"
            icon={<IconEdit />}
          >
            {t('Exclude archived issues')}
          </LinkButton>
          <DismissButton
            priority="link"
            icon={<IconClose />}
            onClick={dismissPrompt}
            aria-label={t('Dismiss Alert')}
            title={t('Dismiss Alert')}
          />
        </ButtonBar>
      }
    >
      {t(
        "Alert rules can now exclude errors associated with archived issues. Please make sure to review the rule's alert thresholds after editing."
      )}
    </Alert>
  );
}

const DismissButton = styled(Button)`
  color: ${p => p.theme.alert.warning.iconColor};
  pointer-events: all;
  &:hover {
    color: ${p => p.theme.alert.warning.iconHoverColor};
    opacity: 0.5;
  }
`;