import json
import os
import urllib.parse

import boto3
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.typing import LambdaContext
from botocore.config import Config

logger = Logger(service="dlq-handler", level=os.environ["APPLICATION_LOG_LEVEL"])

REGION = os.environ.get("AWS_REGION")
QUEUE_LAMBDA_NAME = os.environ.get("QUEUE_LAMBDA_NAME")
SNS_TOPIC_ARN = os.environ.get("SNS_TOPIC_ARN")


retry_config = Config(retries={"max_attempts": 3, "mode": "standard"})
sns_client = boto3.client("sns", config=retry_config)


@logger.inject_lambda_context
def handler(event: dict, context: LambdaContext) -> dict:
    """DLQにメッセージが追加された際に cloudWatchLog に記録し、SNSに通知する。"""
    records = event.get("Records", [])
    message_count = len(records)

    dlq_messages = [{"message_id": record.get("messageId"), "body": record.get("body")} for record in records]
    logger.warning("DLQ messages received", extra={"dlq_messages": dlq_messages})

    log_group = urllib.parse.quote(context.log_group_name, safe="")
    log_stream = urllib.parse.quote(context.log_stream_name, safe="")
    dlq_log_link = f"https://console.aws.amazon.com/cloudwatch/home?region={REGION}#logsV2:log-groups/log-group/{log_group}/log-events/{log_stream}"
    message = {
        "version": "1.0",
        "source": "custom",
        "content": {
            "title": f"🚨 DLQ Alarm | {QUEUE_LAMBDA_NAME} | {REGION}",
            "description": f"{QUEUE_LAMBDA_NAME} で失敗し、{message_count} 件のメッセージがDLQに格納されました。",
            "nextSteps": [
                f"<{dlq_log_link}|CloudWatch Logs を確認する>",
            ],
        },
    }

    try:
        sns_client.publish(
            TopicArn=SNS_TOPIC_ARN,
            Message=json.dumps(message),
        )
    except Exception:
        logger.exception("Error publishing SNS message")
        # エラーになった時にLambdaの再実行を防ぐために正常終了を返す
        return {"statusCode": 200, "body": "Error publishing SNS message"}

    return {"statusCode": 200}
