from datetime import timedelta

from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.data_classes import (
    EventBridgeEvent,
    event_source,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
from layercake.dateutils import now
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey

from boto3clients import dynamodb_client
from config import (
    COURSE_TABLE,
    ENROLLMENT_TABLE,
)

logger = Logger(__name__)
enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
course_layer = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client)


@event_source(data_class=EventBridgeEvent)
@logger.inject_lambda_context
def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
    new_image = event.detail['new_image']
    now_ = now()

    try:
        course = _get_course(new_image['course']['id'])
        access_period = int(course['access_period'])
        access_expires_at = now_ + timedelta(days=access_period)

        with enrollment_layer.transact_writer() as transact:
            transact.update(
                key=KeyPair(new_image['id'], new_image['sk']),
                update_expr='SET access_expires_at = :access_expires_at',
                expr_attr_values={
                    ':access_expires_at': access_expires_at,
                },
            )
    except Exception as exc:
        logger.exception(exc)
        return False
    else:
        return True


class CourseNotFoundError(Exception):
    def __init__(self, *args):
        super().__init__('Course not found')


def _get_course(id: str) -> dict:
    course = course_layer.get_item(KeyPair(pk=id, sk='0'))
    if course:
        return course

    course_id = course_layer.collection.get_item(
        KeyPair(
            pk='MIGRATION',
            sk=SortKey(
                f'COURSE#{id}',
                path_spec='course_id',
            ),
        ),
        exc_cls=CourseNotFoundError,
    )
    return course_layer.collection.get_item(
        KeyPair(pk=course_id, sk='0'),
    )
