def call_webhook_with_failure_mail_after_retries(  # type: ignore[no-untyped-def]
    webhook_id: int,
    data: typing.Mapping,  # type: ignore[type-arg]
    webhook_type: str,
    send_failure_mail: bool = False,
    max_retries: int = settings.WEBHOOK_BACKOFF_RETRIES,
    try_count: int = 1,
):
    """
    Call a webhook with support for sending failure emails after retries.

    :param webhook_id: The ID of the webhook to be called.
    :param data: A mapping containing the data to be sent in the webhook request.
    :param webhook_type: The type of the webhook to be triggered.
    :param send_failure_mail: Whether to send a failure notification email (bool, default is False).
    :param max_retries: The maximum number of retries to attempt (int, default is 3).
    :param try_count: Stores the current retry attempt count in scheduled tasks,
                        not needed to be specified (int, default is 1).
    """

    if try_count > max_retries:
        raise ValueError("try_count can't be greater than max_retries")

    if webhook_type == WebhookType.ORGANISATION.value:
        webhook = OrganisationWebhook.objects.get(id=webhook_id)
    else:
        webhook = Webhook.objects.get(id=webhook_id)

    headers = {"content-type": "application/json"}
    json_data = json.dumps(data, sort_keys=True, cls=DjangoJSONEncoder)
    if webhook.secret:
        signature = sign_payload(json_data, key=webhook.secret)
        headers.update({FLAGSMITH_SIGNATURE_HEADER: signature})

    try:
        res = requests.post(
            str(webhook.url), data=json_data, headers=headers, timeout=10
        )
        res.raise_for_status()
    except requests.exceptions.RequestException as exc:
        if try_count == max_retries or not settings.RETRY_WEBHOOKS:
            if send_failure_mail:
                send_failure_email(
                    webhook,
                    data,
                    webhook_type,
                    f"{f'HTTP {exc.response.status_code}' if exc.response else 'N/A'} ({exc.__class__.__name__})",
                )
        else:
            from webhooks.tasks import call_webhook_with_failure_mail_after_retries

            call_webhook_with_failure_mail_after_retries.delay(
                delay_until=(
                    timezone.now()
                    + timezone.timedelta(  # type: ignore[attr-defined]
                        seconds=settings.WEBHOOK_BACKOFF_BASE**try_count
                    )
                    if settings.TASK_RUN_METHOD == TaskRunMethod.TASK_PROCESSOR
                    else None
                ),
                args=(
                    webhook_id,
                    data,
                    webhook_type,
                    send_failure_mail,
                    max_retries,
                    try_count + 1,
                ),
            )
        return
    return res

    Call a webhook with support for sending failure emails after retries.

    :param webhook_id: The ID of the webhook to be called.
    :param data: A mapping containing the data to be sent in the webhook request.
    :param webhook_type: The type of the webhook to be triggered.
    :param send_failure_mail: Whether to send a failure notification email (bool, default is False).
    :param max_retries: The maximum number of retries to attempt (int, default is 3).
    :param try_count: Stores the current retry attempt count in scheduled tasks,
                        not needed to be specified (int, default is 1).
    
api/webhooks/webhooks.py