from typing import Union

from databases import (
    BuildDecisionBookProjectItems,
    BuildDecisionBookProjectPerson,
)

from api_validations.validations_request import (
    InsertBuildDecisionBookProjectItems,
    UpdateBuildDecisionBookProjectItems,
    ListOptions,
)

from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.core_response import AlchemyJsonResponse
from databases.sql_models.building.decision_book import BuildDecisionBookProjects


class BuildDecisionBookProjectItemsListEventMethods(MethodToEvent):

    event_type = "SELECT"
    __event_keys__ = {
        "ce3630e4-2bf9-4433-bdab-1ee72117e54b": "build_decision_book_project_items_list",
    }

    @staticmethod
    def build_decision_book_project_items_list(
        requester: Union[EmployeeTokenObject, OccupantTokenObject],
        list_options: ListOptions,
    ):
        response = BuildDecisionBookProjectItems.list_items(
            requester=requester,
            list_options=list_options,
        )
        return AlchemyJsonResponse(
            message="Build Decision Book Project Items List",
            result=response,
        )


class BuildDecisionBookProjectItemsCreateEventMethods(MethodToEvent):

    event_type = "CREATE"
    __event_keys__ = {
        "b27e4fd0-6e3e-441b-9b33-806ac7082444": "build_decision_book_project_items_create",
    }

    @staticmethod
    def build_decision_book_project_items_create(
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
        data: InsertBuildDecisionBookProjectItems,
    ):
        if isinstance(token_dict, EmployeeTokenObject):
            raise BuildDecisionBookProjectItems.raise_http_exception(
                status_code="HTTP_403_FORBIDDEN",
                error_case="UNAUTHORIZED",
                message=f"No permission to create decision book project items",
                data={},
            )
        elif isinstance(token_dict, OccupantTokenObject):
            book_project = BuildDecisionBookProjects.filter_one(
                BuildDecisionBookProjects.uu_id
                == data.build_decision_book_project_uu_id,
                BuildDecisionBookProjects.project_response_living_space_id
                == token_dict.selected_occupant.living_space_id,
            ).data
            if not book_project:
                raise BuildDecisionBookProjectItems.raise_http_exception(
                    status_code="HTTP_404_NOT_FOUND",
                    error_case="NOT_FOUND",
                    message=f"This user can not create project item for this project uu_id : {data.build_decision_book_project_uu_id}",
                    data={},
                )
            data_dict = data.excluded_dump()
            data_dict["build_decision_book_project_id"] = book_project.id
            created_project_item = BuildDecisionBookProjectItems.find_or_create(
                **data_dict
            )
            created_project_item.save_and_confirm()
            return AlchemyJsonResponse(
                message="Build Decision Book Project Items Create",
                result=created_project_item.get_dict(),
            )


class BuildDecisionBookProjectItemsUpdateEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "b2b7cdce-9a0c-4722-90ff-8bef36b4ec6b": "build_decision_book_project_items_update",
    }

    @staticmethod
    def build_decision_book_project_items_update(
        requester: Union[EmployeeTokenObject, OccupantTokenObject],
        decision_book_project_items: UpdateBuildDecisionBookProjectItems,
    ):
        raise BuildDecisionBookProjectItems.raise_http_exception(
            status_code="HTTP_403_FORBIDDEN",
            error_case="UNAUTHORIZED",
            message=f"No permission to update decision book project items",
            data={},
        )


class BuildDecisionBookProjectItemsPatchEventMethods(MethodToEvent):

    event_type = "SELECT"
    __event_keys__ = {
        "e59d50df-dd22-4823-aeae-b9490332885c": "build_decision_book_project_items_patch",
    }

    @staticmethod
    def build_decision_book_project_items_patch(
        requester: Union[EmployeeTokenObject, OccupantTokenObject],
        decision_book_project_items: UpdateBuildDecisionBookProjectItems,
    ):
        response = BuildDecisionBookProjectItems.delete_item(
            requester=requester,
            decision_book_project_items=decision_book_project_items,
        )
        return AlchemyJsonResponse(
            message="Build Decision Book Project Items Patch",
            result=response,
        )


BuildDecisionBookProjectItemsListEventMethod = (
    BuildDecisionBookProjectItemsListEventMethods(
        action=ActionsSchema(endpoint="/build/decision_book/project/items/list")
    )
)
BuildDecisionBookProjectItemsCreateEventMethod = (
    BuildDecisionBookProjectItemsCreateEventMethods(
        action=ActionsSchema(endpoint="/build/decision_book/project/items/create")
    )
)
BuildDecisionBookProjectItemsUpdateEventMethod = (
    BuildDecisionBookProjectItemsUpdateEventMethods(
        action=ActionsSchema(endpoint="/build/decision_book/project/items/update")
    )
)
BuildDecisionBookProjectItemsPatchEventMethod = (
    BuildDecisionBookProjectItemsPatchEventMethods(
        action=ActionsSchema(endpoint="/build/decision_book/project/items/patch")
    )
)
