from http import HTTPStatus
from typing import Annotated

from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import NotFoundError
from aws_lambda_powertools.event_handler.openapi.params import Body
from glom import glom
from layercake.dateutils import now
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey

from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import ENROLLMENT_TABLE

logger = Logger(__name__)
router = Router()
dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)


@router.get('/<enrollment_id>/scorm')
def get_scorm(enrollment_id: str):
    enrollment = dyn.collection.get_items(
        TransactKey(enrollment_id)
        + SortKey('0')
        + SortKey('SCORM_COMMIT#LAST', rename_key='last_commit')
    )

    if not enrollment:
        raise NotFoundError('Enrollment not found')

    spec = {'id': 'course.id', 'scormset': 'course.scormset'}
    course_id, scormset_id = glom(enrollment, spec).values()
    scormset = dyn.collection.get_item(
        KeyPair(course_id, f'SCORMSET#{scormset_id}'),
        raise_on_error=False,
        default={},
    )

    return enrollment | {'scormset': scormset}


@router.post('/<enrollment_id>/scorm')
def post_scorm(
    enrollment_id: str,
    cmi: Annotated[dict, Body(embed=True)],
):
    now_ = now()

    with dyn.transact_writer() as transact:
        transact.condition(
            key=KeyPair(enrollment_id, '0'),
            cond_expr='attribute_exists(sk)',
            exc_cls=NotFoundError,
        )
        transact.put(
            item={
                'id': enrollment_id,
                'sk': 'SCORM_COMMIT#LAST',
                'cmi': cmi,
                'created_at': now_,
            }
        )
        transact.put(
            item={
                'id': f'SCORM_COMMIT#{enrollment_id}',
                'sk': now_.isoformat(),
                'cmi': cmi,
                'created_at': now_,
            }
        )

    return JSONResponse(HTTPStatus.NO_CONTENT)
