import psycopg
from aws_lambda_powertools.utilities.data_classes import SQSEvent, SQSRecord, event_source
from aws_lambda_powertools.utilities.typing import LambdaContext
from psycopg import Connection
from src.__types.index import UsageEventRequestMessage
from src.infrastructure.clients.s3_client import S3Client
from src.infrastructure.usage_event_request_storage import UsageEventRequestStorage
from src.logger import logger
from src.routers.client.connection import set_session_variables
from src.settings import Settings
from src.usecases.usage_event_usecase import UsageEventUseCase

settings = Settings()


def _process_record(record: SQSRecord, connection: Connection) -> None:
    """単一のレコードを処理する"""
    logger.info(f"Processing record: {record}")

    message = UsageEventRequestMessage.model_validate(record.json_body)

    set_session_variables(message.tenant, connection)
    usecase = UsageEventUseCase.create(message.tenant, connection)
    storage = UsageEventRequestStorage(client=S3Client(tenant_id=message.tenant.id))
    usecase.consume(message=message, storage=storage)


@event_source(data_class=SQSEvent)
def handler(event: SQSEvent, _: LambdaContext) -> dict:
    records = list(event.records)
    logger.debug(f"Received record count: {len(records)}")
    failures = []
    with psycopg.connect(settings.postgres_url, autocommit=True) as connection:
        for record in records:
            try:
                _process_record(record, connection)
            except Exception:  # noqa: PERF203 BLE001 # 部分バッチ失敗のため全例外キャッチ
                logger.exception(f"Error processing record: message_id = {record.message_id}")
                failures.append({"itemIdentifier": record.message_id})

    return {"batchItemFailures": failures}
