from fastapi import status
from fastapi.responses import JSONResponse
from fastapi.exceptions import HTTPException

from api_validations.validations_request import (
    InsertStaff,
    SelectStaff,
    PatchRecord,
    ListOptions,
)

from databases import Staff, Duties

from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject
from ApiServices.api_handlers import AlchemyJsonResponse


class StaffListEventMethods(MethodToEvent):
    event_type = "SELECT"
    __event_keys__ = {
        "8984a519-99bf-4f25-8f34-2e1aebba468c": "staff_list",
    }
    __event_validation__ = {"8984a519-99bf-4f25-8f34-2e1aebba468c": None}

    @classmethod
    def staff_list(cls, list_options: ListOptions, token_dict: EmployeeTokenObject):
        Staff.filter_attr = list_options
        records = Staff.filter_all()
        return AlchemyJsonResponse(
            completed=True,
            message="Staff are listed successfully",
            result=records,
        )


class StaffCreateEventMethods(MethodToEvent):
    event_type = "CREATE"
    __event_keys__ = {
        "8f619257-19fd-404f-b713-7392c588dc36": "staff_create",
    }
    __event_validation__ = {"8f619257-19fd-404f-b713-7392c588dc36": InsertStaff}

    @classmethod
    def staff_create(cls, data: InsertStaff, token_dict: EmployeeTokenObject):
        data_dict = data.excluded_dump()
        duties = Duties.filter_one(
            Duties.uu_id == data.duties_uu_id,
        ).data
        if not duties:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Duties not found",
            )
        data_dict["duties_id"] = duties.id
        created_duty = Staff.find_or_create(**data_dict)
        Staff.save()
        return JSONResponse(
            content={
                "completed": True,
                "message": "Create Staff record",
                "data": created_duty.get_dict(),
            },
            status_code=status.HTTP_200_OK,
        )


class StaffGetByUUIDEventMethods(MethodToEvent):

    event_type = "GET"
    __event_keys__ = {
        "7724cfbb-c0ee-4261-959b-61b84e88a34f": "staff_get_by_uu_id",
    }
    __event_validation__ = {"7724cfbb-c0ee-4261-959b-61b84e88a34f": SelectStaff}

    @classmethod
    def staff_get_by_uu_id(cls, data: SelectStaff, token_dict: EmployeeTokenObject):
        if data.duties_uu_id:
            duties_id = Duties.filter_one(
                Duties.uu_id == data.duties_uu_id,
            ).data
            selected_staffs = Staff.filter_all(Staff.duties_id == duties_id.id)
            return JSONResponse(
                content={
                    "completed": True,
                    "message": "Staff records are listed",
                    "data": [
                        selected_staff.get_dict()
                        for selected_staff in selected_staffs.data
                    ],
                },
                status_code=status.HTTP_200_OK,
            )
        return JSONResponse(
            content={
                "completed": False,
                "message": "Get Staff record failed",
                "data": {},
            },
            status_code=status.HTTP_202_ACCEPTED,
        )


class StaffUpdateEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "5329f35d-ff9d-4656-a831-ba9c8204e483": "staff_update",
    }
    __event_validation__ = {"5329f35d-ff9d-4656-a831-ba9c8204e483": None}

    @classmethod
    def staff_update(cls, staff_uu_id: str, data, token_dict: EmployeeTokenObject):
        return JSONResponse(
            content={"completed": True, "message": "Update Staff record", "data": {}},
            status_code=status.HTTP_200_OK,
        )


class StaffPatchEventMethods(MethodToEvent):

    event_type = "PATCH"
    __event_keys__ = {
        "b1cd7c0a-1458-472b-894f-3adc857c8512": "staff_patch",
    }
    __event_validation__ = {"b1cd7c0a-1458-472b-894f-3adc857c8512": None}

    @classmethod
    def staff_patch(
        cls, staff_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
    ):
        return JSONResponse(
            content={
                "completed": False,
                "message": "Patch Staff record failed",
                "data": {},
            },
            status_code=status.HTTP_200_OK,
        )


StaffListEventMethod = StaffListEventMethods(
    action=ActionsSchema(endpoint="/staff/list")
)
StaffCreateEventMethod = StaffCreateEventMethods(
    action=ActionsSchema(endpoint="/staff/create")
)
StaffGetByUUIDEventMethod = StaffGetByUUIDEventMethods(
    action=ActionsSchema(endpoint="/staff/get_by_duties_uu_id")
)
StaffUpdateEventMethod = StaffUpdateEventMethods(
    action=ActionsSchema(endpoint="/staff/update")
)
StaffPatchEventMethod = StaffPatchEventMethods(
    action=ActionsSchema(endpoint="/staff/patch")
)
