import { css } from '@emotion/css';
import { uniqueId } from 'lodash';
import { useEffect, useMemo, useState } from 'react';
import { Controller, FormProvider, type RegisterOptions, useForm, useFormContext } from 'react-hook-form';
import { useFirstMountState } from 'react-use';

import { type GrafanaTheme2, type SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Trans, t } from '@grafana/i18n';
import {
  Box,
  Button,
  Divider,
  Field,
  Icon,
  Input,
  Label,
  Modal,
  Select,
  Stack,
  Switch,
  Text,
  Tooltip,
  useStyles2,
} from '@grafana/ui';
import { type RulerRulesConfigDTO } from 'app/types/unified-alerting-dto';

import { evaluateEveryValidationOptions } from '../../group-details/validation';
import { useFetchGroupsForFolder } from '../../hooks/useFetchGroupsForFolder';
import { DEFAULT_GROUP_EVALUATION_INTERVAL } from '../../rule-editor/formDefaults';
import { type RuleFormValues } from '../../types/rule-form';
import {
  DOCS_URL_NO_DATA_ERROR_HANDLING,
  DOCS_URL_RULE_EVALUATION,
  DOCS_URL_STALE_ALERT_INSTANCES,
} from '../../utils/docs';
import {
  isGrafanaAlertingRuleByType,
  isGrafanaManagedRuleByType,
  isGrafanaRecordingRuleByType,
  isProvisionedRuleGroup,
} from '../../utils/rules';
import { parsePrometheusDuration, safeParsePrometheusDuration } from '../../utils/time';
import { CollapseToggle } from '../CollapseToggle';
import { ProvisioningBadge } from '../Provisioning';

import { DurationQuickPick } from './DurationQuickPick';
import { EvaluationGroupQuickPick } from './EvaluationGroupQuickPick';
import { GrafanaAlertStatePicker } from './GrafanaAlertStatePicker';
import { NeedHelpInfo } from './NeedHelpInfo';
import { RuleEditorSection } from './RuleEditorSection';

const namespaceToGroupOptions = (rulerNamespace: RulerRulesConfigDTO, enableProvisionedGroups: boolean) => {
  const folderGroups = Object.values(rulerNamespace).flat();

  return folderGroups
    .map<SelectableValue<string>>((group) => {
      const isProvisioned = isProvisionedRuleGroup(group);
      return {
        label: group.name,
        value: group.name,
        description: group.interval ?? DEFAULT_GROUP_EVALUATION_INTERVAL,
        // we include provisioned folders, but disable the option to select them
        isDisabled: !enableProvisionedGroups ? isProvisioned : false,
        isProvisioned: isProvisioned,
      };
    })

    .sort(sortByLabel);
};

const collator = new Intl.Collator();
const sortByLabel = (a: SelectableValue<string>, b: SelectableValue<string>) => {
  return collator.compare(a.label ?? '', b.label ?? '');
};

const forValidationOptions = (getEvaluateEvery: () => string): RegisterOptions<{ evaluateFor: string }> => ({
  required: {
    value: true,
    message: t('alerting.for-validation-options.message.required', 'Required.'),
  },
  validate: (value) => {
    // parsePrometheusDuration does not allow 0 but does allow 0s
    if (value === '0') {
      return true;
    }

    try {
      const millisFor = parsePrometheusDuration(value);

      // 0 is a special value meaning for equals evaluation interval
      if (millisFor === 0) {
        return true;
      }

      try {
        const millisEvery = parsePrometheusDuration(getEvaluateEvery());
        return millisFor >= millisEvery
          ? true
          : t(
              'alerting.rule-form.evaluation-behaviour-for.validation',
              'Pending period must be greater than or equal to the evaluation interval.'
            );
      } catch (err) {
        // if we fail to parse "every", assume validation is successful, or the error messages
        // will overlap in the UI
        return true;
      }
    } catch (error) {
      return error instanceof Error
        ? error.message
        : t('alerting.rule-form.evaluation-behaviour-for.error-parsing', 'Failed to parse duration');
    }
  },
});

export function GrafanaEvaluationBehaviorStep({
  existing,
  enableProvisionedGroups,
}: {
  existing: boolean;
  enableProvisionedGroups: boolean;
}) {
  const styles = useStyles2(getStyles);
  const [showErrorHandling, setShowErrorHandling] = useState(false);

  const {
    watch,
    setValue,
    getValues,
    formState: { errors },
    control,
    register,
  } = useFormContext<RuleFormValues>();

  const [group, type, isPaused, folder, evaluateEvery] = watch([
    'group',
    'type',
    'isPaused',
    'folder',
    'evaluateEvery',
    'keepFiringFor',
  ]);

  const isGrafanaAlertingRule = isGrafanaAlertingRuleByType(type);
  const isGrafanaRecordingRule = isGrafanaRecordingRuleByType(type);
  const { currentData: rulerNamespace, isLoading: loadingGroups } = useFetchGroupsForFolder(folder?.uid ?? '');

  const groupOptions = useMemo(() => {
    return rulerNamespace ? namespaceToGroupOptions(rulerNamespace, enableProvisionedGroups) : [];
  }, [enableProvisionedGroups, rulerNamespace]);

  const existingGroup = Object.values(rulerNamespace ?? {})
    .flat()
    .find((ruleGroup) => ruleGroup.name === group);

  // synchronize the evaluation interval with the group name when it's an existing group
  useEffect(() => {
    if (existingGroup) {
      setValue('evaluateEvery', existingGroup.interval ?? DEFAULT_GROUP_EVALUATION_INTERVAL);
    }
  }, [existingGroup, setValue]);

  const [isCreatingEvaluationGroup, setIsCreatingEvaluationGroup] = useState(false);

  const handleEvalGroupCreation = (groupName: string, evaluationInterval: string) => {
    setValue('group', groupName);
    setValue('evaluateEvery', evaluationInterval);

    // Auto-adjust pending period so it's never shorter than the new evaluation interval
    const currentFor = getValues('evaluateFor');
    const millisFor = safeParsePrometheusDuration(currentFor);
    const millisEvery = safeParsePrometheusDuration(evaluationInterval);
    if (millisFor !== 0 && millisFor < millisEvery) {
      setValue('evaluateFor', evaluationInterval);
    }

    setIsCreatingEvaluationGroup(false);
  };

  const defaultGroupValue = group ? { value: group, label: group } : undefined;

  const pauseContentText = isGrafanaRecordingRule
    ? t('alerting.rule-form.evaluation.pause.recording', 'Turn on to pause evaluation for this recording rule.')
    : t('alerting.rule-form.evaluation.pause.alerting', 'Turn on to pause evaluation for this alert rule.');

  const onOpenEvaluationGroupCreationModal = () => setIsCreatingEvaluationGroup(true);

  const step = isGrafanaManagedRuleByType(type) ? 4 : 3;
  const label =
    isGrafanaManagedRuleByType(type) && !folder?.uid
      ? t(
          'alerting.rule-form.evaluation.select-folder-before',
          'Select a folder before setting evaluation group and interval'
        )
      : t('alerting.rule-form.evaluation.evaluation-group-and-interval', 'Evaluation group and interval');

  return (
    // TODO remove "and alert condition" for recording rules
    <RuleEditorSection
      stepNo={step}
      title={t('alerting.grafana-evaluation-behavior-step.title-set-evaluation-behavior', 'Set evaluation behavior')}
      description={getDescription(isGrafanaRecordingRule)}
    >
      <Stack direction="column" justify-content="flex-start" align-items="flex-start">
        <Stack alignItems="center">
          <div style={{ width: 420 }}>
            <Field
              noMargin
              label={label}
              data-testid="group-picker"
              className={styles.formInput}
              error={errors.group?.message}
              invalid={!!errors.group?.message}
              htmlFor="group"
            >
              <Controller
                render={({ field: { ref, ...field }, fieldState }) => (
                  <Select
                    disabled={!folder?.uid || loadingGroups}
                    inputId="group"
                    key={uniqueId()}
                    {...field}
                    onChange={(group) => {
                      field.onChange(group.label ?? '');
                    }}
                    isLoading={loadingGroups}
                    invalid={Boolean(folder?.uid) && !group && Boolean(fieldState.error)}
                    cacheOptions
                    loadingMessage={t(
                      'alerting.grafana-evaluation-behavior-step.loadingMessage-loading-groups',
                      'Loading groups...'
                    )}
                    defaultValue={defaultGroupValue}
                    options={groupOptions}
                    getOptionLabel={(option: SelectableValue<string>) => (
                      <div>
                        <span>{option.label}</span>
                        {option.isProvisioned && (
                          <>
                            {' '}
                            <ProvisioningBadge />
                          </>
                        )}
                      </div>
                    )}
                    placeholder={t(
                      'alerting.grafana-evaluation-behavior-step.placeholder-select-an-evaluation-group',
                      'Select an evaluation group...'
                    )}
                  />
                )}
                name="group"
                control={control}
                rules={{
                  required: {
                    value: true,
                    message: t(
                      'alerting.grafana-evaluation-behavior-step.message.must-enter-a-group-name',
                      'Must enter a group name'
                    ),
                  },
                }}
              />
            </Field>
          </div>
          <Box gap={1} display={'flex'} alignItems={'center'}>
            <Text color="secondary">
              <Trans i18nKey="alerting.grafana-evaluation-behavior-step.or">or</Trans>
            </Text>
            <Button
              onClick={onOpenEvaluationGroupCreationModal}
              type="button"
              icon="plus"
              fill="outline"
              variant="secondary"
              disabled={!folder?.uid}
              data-testid={selectors.components.AlertRules.newEvaluationGroupButton}
            >
              <Trans i18nKey="alerting.rule-form.evaluation.new-group">New evaluation group</Trans>
            </Button>
          </Box>
          {isCreatingEvaluationGroup && (
            <EvaluationGroupCreationModal
              onCreate={handleEvalGroupCreation}
              onClose={() => setIsCreatingEvaluationGroup(false)}
            />
          )}
        </Stack>

        {folder?.title && group && (
          <div className={styles.evaluationContainer}>
            <Stack direction="column" gap={0}>
              <div className={styles.marginTop}>
                <Stack direction="column" gap={1}>
                  {getValues('group') && getValues('evaluateEvery') && (
                    <Trans i18nKey="alerting.rule-form.evaluation.group-text" values={{ evaluateEvery }}>
                      All rules in the selected group are evaluated every {{ evaluateEvery }}.
                    </Trans>
                  )}
                </Stack>
              </div>
            </Stack>
          </div>
        )}
        {/* Show the pending period input only for Grafana alerting rules */}
        {isGrafanaAlertingRule && <ForInput evaluateEvery={evaluateEvery} />}
        <Divider />
        {/*Show the keepFiringFor input only for Grafana alerting rules*/}
        {isGrafanaAlertingRule && <KeepFiringFor evaluateEvery={evaluateEvery} />}

        {existing && (
          <Field noMargin htmlFor="pause-alert-switch">
            <Controller
              render={() => (
                <Stack gap={1} direction="row" alignItems="center">
                  <Switch
                    id="pause-alert"
                    onChange={(value) => {
                      setValue('isPaused', value.currentTarget.checked);
                    }}
                    value={Boolean(isPaused)}
                  />
                  <label htmlFor="pause-alert" className={styles.switchLabel}>
                    <Trans i18nKey="alerting.rule-form.pause.label">Pause evaluation</Trans>
                    <Tooltip placement="top" content={pauseContentText} theme={'info'}>
                      <Icon tabIndex={0} name="info-circle" size="sm" className={styles.infoIcon} />
                    </Tooltip>
                  </label>
                </Stack>
              )}
              name="isPaused"
            />
          </Field>
        )}
      </Stack>
      {isGrafanaAlertingRule && (
        <>
          <CollapseToggle
            isCollapsed={!showErrorHandling}
            onToggle={(collapsed) => setShowErrorHandling(!collapsed)}
            text={t(
              'alerting.grafana-evaluation-behavior-step.text-configure-no-data-and-error-handling',
              'Configure no data and error handling'
            )}
          />
          {showErrorHandling && (
            <Stack direction="column" gap={2}>
              <NeedHelpInfoForConfigureNoDataError />
              <Field
                noMargin
                htmlFor="no-data-state-input"
                label={t('alerting.alert.state-no-data', 'Alert state if no data or all values are null')}
              >
                <Controller
                  render={({ field: { onChange, ref, ...field } }) => (
                    <GrafanaAlertStatePicker
                      {...field}
                      inputId="no-data-state-input"
                      width={42}
                      includeNoData={true}
                      includeError={false}
                      onChange={(value) => onChange(value?.value)}
                    />
                  )}
                  name="noDataState"
                />
              </Field>
              <Field
                noMargin
                htmlFor="exec-err-state-input"
                label={t('alerting.alert.state-error-timeout', 'Alert state if execution error or timeout')}
              >
                <Controller
                  render={({ field: { onChange, ref, ...field } }) => (
                    <GrafanaAlertStatePicker
                      {...field}
                      inputId="exec-err-state-input"
                      width={42}
                      includeNoData={false}
                      includeError={true}
                      onChange={(value) => onChange(value?.value)}
                    />
                  )}
                  name="execErrState"
                />
              </Field>
              <Field
                noMargin
                label={t('alerting.alert.missing-series-resolve', 'Missing series evaluations to resolve')}
                description={t(
                  'alerting.alert.description-missing-series-evaluations',
                  'The number of consecutive evaluation intervals a dimension must be missing before the alert instance becomes stale, and is then automatically resolved and evicted. Defaults to 2 if empty.'
                )}
                invalid={!!errors.missingSeriesEvalsToResolve?.message}
                error={errors.missingSeriesEvalsToResolve?.message}
                className={styles.inlineField}
                htmlFor="missing-series-resolve"
              >
                <Stack direction="row" gap={0.5} alignItems="center">
                  <Input
                    placeholder={t(
                      'alerting.grafana-evaluation-behavior-step.missing-series-resolve-placeholder',
                      'Default: 2'
                    )}
                    id="missing-series-resolve"
                    {...register('missingSeriesEvalsToResolve', {
                      pattern: {
                        value: /^\d+$/,
                        message: t(
                          'alerting.grafana-evaluation-behavior-step.message.must-be-a-positive-integer',
                          'Must be a positive integer.'
                        ),
                      },
                    })}
                    width={21}
                  />
                  <NeedHelpInfo
                    contentText={
                      <>
                        <p>
                          {t(
                            'alerting.alert-missing-evaluations-to-stale.help-info.text1',
                            'An alert instance is considered stale if the alert rule query returns data, but the specific dimension (or series) for that alert instance is missing for several consecutive evaluation intervals.'
                          )}
                        </p>
                        <p>
                          {t(
                            'alerting.alert-missing-evaluations-to-stale.help-info.text2',
                            'A stale alert instance is resolved and then evicted.'
                          )}
                        </p>
                        {t(
                          'alerting.alert-missing-evaluations-to-stale.help-info.text3',
                          'This setting defines how many consecutive evaluation intervals must pass without data before an alert instance is considered stale. Defaults to 2 if empty.'
                        )}
                      </>
                    }
                    externalLink={DOCS_URL_STALE_ALERT_INSTANCES}
                    linkText={t(
                      'alerting.alert-missing-evaluations-to-stale.help-info.link-text',
                      `Read more about stale alert instances`
                    )}
                    title={t('alerting.alert-missing-evaluations-to-stale.help-info.title', 'Stale alert instances')}
                  />
                </Stack>
              </Field>
            </Stack>
          )}
        </>
      )}
    </RuleEditorSection>
  );
}

export function EvaluationGroupCreationModal({
  onClose,
  onCreate,
}: {
  onClose: () => void;
  onCreate: (group: string, evaluationInterval: string) => void;
}): React.ReactElement {
  const styles = useStyles2(getStyles);
  const { watch } = useFormContext<RuleFormValues>();

  const evaluateEveryId = 'eval-every-input';
  const evaluationGroupNameId = 'new-eval-group-name';
  const type = watch('type');
  const isGrafanaRecordingRule = type ? isGrafanaRecordingRuleByType(type) : false;

  const formAPI = useForm({
    defaultValues: { group: '', evaluateEvery: DEFAULT_GROUP_EVALUATION_INTERVAL },
    mode: 'onChange',
    shouldFocusError: true,
  });

  const { register, handleSubmit, formState, setValue, getValues, watch: watchGroupFormValues } = formAPI;
  const evaluationInterval = watchGroupFormValues('evaluateEvery');

  const onSubmit = () => {
    onCreate(getValues('group'), getValues('evaluateEvery'));
  };

  const onCancel = () => {
    onClose();
  };

  const setEvaluationInterval = (interval: string) => {
    setValue('evaluateEvery', interval, { shouldValidate: true });
  };

  const modalTitle = isGrafanaRecordingRule
    ? t(
        'alerting.folderAndGroup.evaluation.modal.text.recording',
        'Create a new evaluation group to use for this recording rule.'
      )
    : t(
        'alerting.folderAndGroup.evaluation.modal.text.alerting',
        'Create a new evaluation group to use for this alert rule.'
      );

  return (
    <Modal
      className={styles.modal}
      isOpen={true}
      title={t('alerting.evaluation-group-creation-modal.title-new-evaluation-group', 'New evaluation group')}
      onDismiss={onCancel}
      onClickBackdrop={onCancel}
    >
      <div className={styles.modalTitle}>{modalTitle}</div>

      <FormProvider {...formAPI}>
        <form onSubmit={handleSubmit(() => onSubmit())}>
          <Stack direction="column" gap={2}>
            <Field
              noMargin
              label={
                <Label
                  htmlFor={evaluationGroupNameId}
                  description={t(
                    'alerting.evaluation-group-creation-modal.description-group-name',
                    'A group evaluates all its rules over the same evaluation interval.'
                  )}
                >
                  <Trans i18nKey="alerting.rule-form.evaluation.group-name">Evaluation group name</Trans>
                </Label>
              }
              error={formState.errors.group?.message}
              invalid={Boolean(formState.errors.group)}
            >
              <Input
                data-testid={selectors.components.AlertRules.newEvaluationGroupName}
                className={styles.formInput}
                autoFocus={true}
                id={evaluationGroupNameId}
                placeholder={t('alerting.evaluation-group-creation-modal.placeholder-enter-a-name', 'Enter a name')}
                {...register('group', {
                  required: {
                    value: true,
                    message: t('alerting.evaluation-group-creation-modal.message.required', 'Required.'),
                  },
                })}
              />
            </Field>

            <Field
              noMargin
              error={formState.errors.evaluateEvery?.message}
              label={
                <Label
                  htmlFor={evaluateEveryId}
                  description={t(
                    'alerting.evaluation-group-creation-modal.description-often-rules-group-evaluated',
                    'How often all rules in the group are evaluated.'
                  )}
                >
                  <Trans i18nKey="alerting.rule-form.evaluation.group.interval">Evaluation interval</Trans>
                </Label>
              }
              invalid={Boolean(formState.errors.evaluateEvery)}
            >
              <Input
                data-testid={selectors.components.AlertRules.newEvaluationGroupInterval}
                className={styles.formInput}
                id={evaluateEveryId}
                placeholder={DEFAULT_GROUP_EVALUATION_INTERVAL}
                {...register(
                  'evaluateEvery',
                  evaluateEveryValidationOptions<{ group: string; evaluateEvery: string }>([])
                )}
              />
            </Field>

            <EvaluationGroupQuickPick currentInterval={evaluationInterval} onSelect={setEvaluationInterval} />
          </Stack>

          <Modal.ButtonRow>
            <Button variant="secondary" type="button" onClick={onCancel}>
              <Trans i18nKey="alerting.rule-form.evaluation.group.cancel">Cancel</Trans>
            </Button>
            <Button
              type="submit"
              disabled={!formState.isValid}
              data-testid={selectors.components.AlertRules.newEvaluationGroupCreate}
            >
              <Trans i18nKey="alerting.rule-form.evaluation.group.create">Create</Trans>
            </Button>
          </Modal.ButtonRow>
        </form>
      </FormProvider>
    </Modal>
  );
}

export function ForInput({ evaluateEvery }: { evaluateEvery: string }) {
  const styles = useStyles2(getStyles);
  const {
    register,
    formState: { errors },
    setValue,
    getValues,
    watch,
    trigger,
  } = useFormContext<RuleFormValues>();

  const evaluateForId = 'eval-for-input';
  const currentPendingPeriod = watch('evaluateFor');

  const isFirstMount = useFirstMountState();
  useEffect(() => {
    if (isFirstMount) {
      return;
    }
    trigger('evaluateFor');
  }, [evaluateEvery, currentPendingPeriod, trigger, isFirstMount]);

  const setPendingPeriod = (pendingPeriod: string) => {
    setValue('evaluateFor', pendingPeriod);
  };

  return (
    <Stack direction="column" justify-content="flex-start" align-items="flex-start" gap={2}>
      <Field
        noMargin
        label={
          <Label
            htmlFor={evaluateForId}
            description={t(
              'alerting.for-input.description-pending',
              'Period during which the threshold condition must be met to trigger an alert. Selecting "None" triggers the alert immediately once the condition is met.'
            )}
          >
            <Trans i18nKey="alerting.rule-form.evaluation-behaviour.pending-period">Pending period</Trans>
          </Label>
        }
        className={styles.inlineField}
        error={errors.evaluateFor?.message}
        invalid={Boolean(errors.evaluateFor?.message) ? true : undefined}
        validationMessageHorizontalOverflow={true}
      >
        <Input
          id={evaluateForId}
          width={8}
          {...register(
            'evaluateFor',
            forValidationOptions(() => getValues('evaluateEvery'))
          )}
        />
      </Field>
      <DurationQuickPick
        selectedDuration={currentPendingPeriod}
        groupEvaluationInterval={evaluateEvery}
        onSelect={setPendingPeriod}
      />
    </Stack>
  );
}

function KeepFiringFor({ evaluateEvery }: { evaluateEvery: string }) {
  const styles = useStyles2(getStyles);
  const {
    register,
    formState: { errors },
    setValue,
    watch,
  } = useFormContext<RuleFormValues>();

  const currentKeepFiringFor = watch('keepFiringFor');
  const keepFiringForId = 'keep-firing-for-input';

  const setKeepFiringFor = (keepFiringFor: string) => {
    setValue('keepFiringFor', keepFiringFor);
  };

  return (
    <Stack direction="column" justify-content="flex-start" align-items="flex-start" gap={2}>
      <Field
        noMargin
        label={
          <Label
            htmlFor={keepFiringForId}
            description={t(
              'alerting.rule-form.evaluation-behaviour.keep-firing-for.label-description',
              'Period during which the alert will continue to show up as firing even though the threshold condition is no longer breached. Selecting "None" means the alert will be back to normal immediately.'
            )}
          >
            <Trans i18nKey="alerting.rule-form.evaluation-behaviour.keep-firing-for.label-text">Keep firing for</Trans>
          </Label>
        }
        className={styles.inlineField}
        error={errors.keepFiringFor?.message}
        invalid={Boolean(errors.keepFiringFor?.message) ? true : undefined}
        validationMessageHorizontalOverflow={true}
      >
        <Input id={keepFiringForId} width={8} {...register('keepFiringFor')} />
      </Field>
      <DurationQuickPick
        selectedDuration={currentKeepFiringFor}
        groupEvaluationInterval={evaluateEvery}
        onSelect={setKeepFiringFor}
      />
    </Stack>
  );
}

function NeedHelpInfoForConfigureNoDataError() {
  return (
    <Stack direction="row" gap={0.5} alignItems="center">
      <Text variant="bodySmall" color="secondary">
        <Trans i18nKey="alerting.rule-form.evaluation-behaviour.info-help.text">
          Define the alert behavior when the evaluation fails or the query returns no data.
        </Trans>
      </Text>
      <NeedHelpInfo
        contentText={t(
          'alerting.rule-form.evaluation-behaviour.info-help.content',
          'These settings can help mitigate temporary data source issues, preventing alerts from unintentionally firing due to lack of data, errors, or timeouts.'
        )}
        externalLink={DOCS_URL_NO_DATA_ERROR_HANDLING}
        linkText={t('alerting.rule-form.evaluation-behaviour.info-help.link-text', `Read more about this option`)}
        title={t(
          'alerting.rule-form.evaluation-behaviour.info-help.link-title',
          'Configure no data and error handling'
        )}
      />
    </Stack>
  );
}

function getDescription(isGrafanaRecordingRule: boolean) {
  return (
    <Stack direction="row" gap={0.5} alignItems="center">
      <Text variant="bodySmall" color="secondary">
        {isGrafanaRecordingRule ? (
          <Trans i18nKey="alerting.alert-recording-rule-form.evaluation-behaviour.description.text">
            Define how the recording rule is evaluated.
          </Trans>
        ) : (
          <Trans i18nKey="alerting.rule-form.evaluation-behaviour.description.text">
            Define how the alert rule is evaluated.
          </Trans>
        )}
      </Text>
      <NeedHelpInfo
        contentText={
          <>
            <p>
              <Trans i18nKey="alerting.rule-form.evaluation-behaviour-description1">
                Evaluation groups are containers for evaluating alert and recording rules.
              </Trans>
            </p>
            <p>
              <Trans i18nKey="alerting.rule-form.evaluation-behaviour-description2">
                An evaluation group defines an evaluation interval - how often a rule is evaluated. Alert rules within
                the same evaluation group are evaluated over the same evaluation interval.
              </Trans>
            </p>
            <p>
              <Trans i18nKey="alerting.rule-form.evaluation-behaviour-description3">
                Pending period specifies how long the threshold condition must be met before the alert starts firing.
                This option helps prevent alerts from being triggered by temporary issues.
              </Trans>
            </p>
          </>
        }
        externalLink={DOCS_URL_RULE_EVALUATION}
        linkText={t(
          'alerting.rule-form.evaluation-behaviour.info-help2.link-text',
          `Read about evaluation and alert states`
        )}
        title={t('alerting.rule-form.evaluation-behaviour.info-help2.link-title', 'Alert rule evaluation')}
      />
    </Stack>
  );
}

const getStyles = (theme: GrafanaTheme2) => ({
  inlineField: css({
    marginBottom: 0,
  }),
  evaluationContainer: css({
    color: theme.colors.text.secondary,
    maxWidth: `${theme.breakpoints.values.sm}px`,
    fontSize: theme.typography.size.sm,
  }),
  infoIcon: css({
    marginLeft: '10px',
  }),
  marginTop: css({
    marginTop: theme.spacing(1),
  }),
  switchLabel: css({
    color: theme.colors.text.primary,
    cursor: 'pointer',
    fontSize: theme.typography.bodySmall.fontSize,
  }),
  formInput: css({
    flexGrow: 1,
  }),
  modal: css({
    width: `${theme.breakpoints.values.sm}px`,
  }),
  modalTitle: css({
    color: theme.colors.text.secondary,
    marginBottom: theme.spacing(2),
  }),
});
