from http import HTTPStatus

from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import NotFoundError
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
from meilisearch import Client as Meilisearch

from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import (
    COURSE_TABLE,
    MEILISEARCH_API_KEY,
    MEILISEARCH_HOST,
    USER_TABLE,
)
from middlewares import AuditLogMiddleware, Tenant, TenantMiddleware
from models import Course, Org
from rules.course import create_course, update_course

router = Router()
meili_client = Meilisearch(MEILISEARCH_HOST, MEILISEARCH_API_KEY)
course_layer = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client)
user_layer = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)


@router.get(
    '/',
    compress=True,
    tags=['Course'],
    summary='Get courses',
)
def get_courses():
    event = router.current_event
    query = event.get_query_string_value('q', '')
    sort = event.get_query_string_value('sort', 'create_date:desc')
    page = int(event.get_query_string_value('page', '1'))
    hits_per_page = int(event.get_query_string_value('hitsPerPage', '25'))

    return meili_client.index(COURSE_TABLE).search(
        query,
        {
            'sort': [sort],
            'locales': ['pt'],
            'page': page,
            'hitsPerPage': hits_per_page,
        },
    )


@router.post(
    '/',
    compress=True,
    tags=['Course'],
    middlewares=[
        TenantMiddleware(user_layer.collection),
        AuditLogMiddleware('COURSE_ADD', user_layer.collection, ('id', 'name')),
    ],
)
def post_course(payload: Course):
    tenant: Tenant = router.context['tenant']
    create_course(
        payload,
        Org(id=tenant.id, name=tenant.name),
        persistence_layer=course_layer,
    )
    return JSONResponse(
        body=payload,
        status_code=HTTPStatus.CREATED,
    )


@router.get('/<id>', compress=True, tags=['Course'])
def get_course(id: str):
    return course_layer.collection.get_item(
        KeyPair(id, '0'),
        exc_cls=NotFoundError,
    )


@router.put(
    '/<id>',
    compress=True,
    tags=['Course'],
    middlewares=[
        TenantMiddleware(user_layer.collection),
        AuditLogMiddleware('COURSE_UPDATE', user_layer.collection, ('id', 'name')),
    ],
)
def put_course(id: str, payload: Course):
    update_course(id, payload, persistence_layer=course_layer)

    return JSONResponse(
        body=payload,
        status_code=HTTPStatus.OK,
    )
