from decimal import Decimal
from http import HTTPStatus

from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import (
    BadRequestError,
)
from layercake.dateutils import now
from layercake.dynamodb import (
    DynamoDBPersistenceLayer,
    KeyPair,
    PartitionKey,
)
from pydantic import BaseModel
from pydantic.types import UUID4

from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import COURSE_TABLE

router = Router()
course_layer = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client)


@router.get('/<id>/custompricing', compress=True)
def get_custom_pricing(id: str):
    return course_layer.collection.query(
        PartitionKey(f'CUSTOM_PRICING#ORG#{id}'),
        limit=100,
    )


class CustomPricing(BaseModel):
    course_id: UUID4
    unit_price: Decimal


@router.post('/<id>/custompricing', compress=True)
def add_custom_pricing(id: str, custom_princing: CustomPricing):
    now_ = now()

    with course_layer.transact_writer() as transact:
        transact.put(
            item={
                'id': f'CUSTOM_PRICING#ORG#{id}',
                'sk': f'COURSE#{custom_princing.course_id}',
                'unit_price': custom_princing.unit_price,
                'created_at': now_,
            },
            cond_expr='attribute_not_exists(sk)',
            exc_cls=CoursConflictError,
        )
        transact.condition(
            key=KeyPair(str(custom_princing.course_id), '0'),
            cond_expr='attribute_exists(sk)',
            exc_cls=CourseNotFoundError,
        )

    return JSONResponse(status_code=HTTPStatus.CREATED)


class RemoveCustomPricing(BaseModel):
    course_id: UUID4


@router.delete('/<id>/custompricing', compress=True)
def remove_custom_pricing(id: str, custom_princing: RemoveCustomPricing):
    key = KeyPair(
        f'CUSTOM_PRICING#ORG#{id}',
        f'COURSE#{custom_princing.course_id}',
    )

    if course_layer.delete_item(key):
        return JSONResponse(status_code=HTTPStatus.OK)


class CoursConflictError(BadRequestError): ...


class CourseNotFoundError(BadRequestError): ...
