from typing import Union

from databases import (
    BuildDecisionBookProjects,
    BuildDecisionBookProjectPerson,
)

from api_validations.validations_request import (
    InsertBuildDecisionBookProjectPerson,
    UpdateBuildDecisionBookProjectPerson,
    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


class ProjectDecisionBookPersonListEventMethods(MethodToEvent):

    event_type = "LIST"

    __event_keys__ = {
        "7101b5ca-8bef-40f9-8b4d-646d9994e18f": "project_decision_book_person_list",
    }

    @classmethod
    def project_decision_book_person_list(
        cls,
        list_options: ListOptions,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        if isinstance(token_dict, EmployeeTokenObject):
            raise BuildDecisionBookProjects.raise_http_exception(
                status_code="HTTP_403_FORBIDDEN",
                error_case="NOT_ALLOWED",
                message="Employee cannot create project project decision book",
                data={},
            )
        elif isinstance(token_dict, OccupantTokenObject):
            project_person = BuildDecisionBookProjectPerson.filter_all(
                BuildDecisionBookProjects.living_space_id
                == token_dict.selected_occupant.living_space_id,
            )
            decision_book_ids = [
                _.build_decision_book_project_id for _ in project_person.data
            ]
            decision_book_projects = BuildDecisionBookProjects.filter_all(
                BuildDecisionBookProjects.build_decision_book_project_id.in_(
                    decision_book_ids
                ),
            )
            return AlchemyJsonResponse(
                status_code="HTTP_200_OK",
                message="Project decision person book listed successfully",
                result=decision_book_projects,
            )


class ProjectDecisionBookPersonCreateEventMethods(MethodToEvent):

    event_type = "CREATE"

    __event_keys__ = {
        "9c88e314-84e8-435e-8c1e-6a5aae80b2e6": "project_decision_book_person_create",
    }

    @classmethod
    def project_decision_book_create(
        cls,
        data: InsertBuildDecisionBookProjectPerson,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        if isinstance(token_dict, EmployeeTokenObject):
            raise BuildDecisionBookProjects.raise_http_exception(
                status_code="HTTP_403_FORBIDDEN",
                error_case="NOT_ALLOWED",
                message="Employee cannot create project project decision book",
                data={},
            )
        elif isinstance(token_dict, OccupantTokenObject):
            decision_book = BuildDecisionBookProjects.filter_one(
                BuildDecisionBookProjects.build_decision_book_uu_id
                == data.get("build_decision_book_uu_id"),
                BuildDecisionBookProjects.project_response_living_space_id
                == token_dict.selected_occupant.living_space_id,
            )
            return AlchemyJsonResponse(
                status_code="HTTP_200_OK",
                message="Project decision book created successfully",
                result=decision_book,
            )


class ProjectDecisionBookPersonUpdateEventMethods(MethodToEvent):

    event_type = "UPDATE"

    __event_keys__ = {
        "7fbd18a0-c099-4494-ada1-bb23e39bb141": "project_decision_book_update_person",
    }

    @classmethod
    def project_decision_book_update(
        cls,
        data: UpdateBuildDecisionBookProjectPerson,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        if isinstance(token_dict, EmployeeTokenObject):
            raise BuildDecisionBookProjects.raise_http_exception(
                status_code="HTTP_403_FORBIDDEN",
                error_case="NOT_ALLOWED",
                message="Employee cannot create project project decision book",
                data={},
            )
        elif isinstance(token_dict, OccupantTokenObject):
            decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
                BuildDecisionBookProjects.build_decision_book_project_uu_id
                == data.get("build_decision_book_uu_id"),
                BuildDecisionBookProjects.living_space_id
                == token_dict.selected_occupant.living_space_id,
            )

            return AlchemyJsonResponse(
                status_code="HTTP_200_OK",
                message="Project decision book created successfully",
                result=decision_book_project_person,
            )


class ProjectDecisionBookPersonPatchEventMethods(MethodToEvent):

    event_type = "PATCH"

    __event_keys__ = {
        "a122e84a-5556-4bf7-b680-1f47c438d4f7": "project_decision_book_person_patch",
    }

    @classmethod
    def project_decision_book_patch(
        cls,
        data,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        if isinstance(token_dict, EmployeeTokenObject):
            raise BuildDecisionBookProjects.raise_http_exception(
                status_code="HTTP_403_FORBIDDEN",
                error_case="NOT_ALLOWED",
                message="Employee cannot create project project decision book",
                data={},
            )
        elif isinstance(token_dict, OccupantTokenObject):
            decision_book_project_person = BuildDecisionBookProjectPerson.filter_one(
                BuildDecisionBookProjects.build_decision_book_project_uu_id
                == data.get("build_decision_book_uu_id"),
                BuildDecisionBookProjects.living_space_id
                == token_dict.selected_occupant.living_space_id,
            )
            return AlchemyJsonResponse(
                status_code="HTTP_200_OK",
                message="Project decision book created successfully",
                result=decision_book_project_person,
            )


ProjectDecisionBookPersonListEventMethod = ProjectDecisionBookPersonListEventMethods(
    action=ActionsSchema(endpoint="/build/decision_book/project/people/list")
)
ProjectDecisionBookPersonCreateEventMethod = (
    ProjectDecisionBookPersonCreateEventMethods(
        action=ActionsSchema(endpoint="/build/decision_book/project/people/create")
    )
)
ProjectDecisionBookPersonUpdateEventMethod = (
    ProjectDecisionBookPersonUpdateEventMethods(
        action=ActionsSchema(endpoint="/build/decision_book/project/people/update")
    )
)
ProjectDecisionBookPersonPatchEventMethod = ProjectDecisionBookPersonPatchEventMethods(
    action=ActionsSchema(endpoint="/build/decision_book/project/people/patch")
)
