from typing import Union

from ApiServices.api_handlers import AlchemyJsonResponse
from api_validations.validations_response import BuildPartsListResponse
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_validations.validations_request import (
    InsertBuildParts,
    UpdateBuildParts,
    ListOptions,
)
from databases import (
    Build,
    BuildParts,
)


class BuildingBuildPartsListEventMethods(MethodToEvent):

    event_type = "SELECT"
    __event_keys__ = {
        "b860e37a-e19b-4c45-9543-461241f7587c": "building_build_parts_list"
    }
    __event_validation__ = {
        "b860e37a-e19b-4c45-9543-461241f7587c": BuildPartsListResponse
    }

    @classmethod
    def building_build_parts_list(
        cls,
        list_options: ListOptions,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        build_list_query = Build.select_action(
            employee_id=token_dict.selected_company.employee_id,
        )
        build_list_ids = [build.id for build in build_list_query.all()]
        BuildParts.pre_query = BuildParts.filter_all(
            BuildParts.build_id.in_(build_list_ids),
        ).query
        BuildParts.filter_attr = list_options
        records = BuildParts.filter_all()
        return AlchemyJsonResponse(
            completed=True,
            message="Building parts listed successfully",
            result=records,
            cls_object=BuildParts,
            filter_attributes=list_options,
            response_model=BuildPartsListResponse,
        )


class BuildingBuildPartsCreateEventMethods(MethodToEvent):

    event_type = "CREATE"
    __event_keys__ = {
        "fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": "building_build_parts_create"
    }
    __event_validation__ = {"fb403f69-11ed-4f4f-ad71-5e6fb4a793d2": InsertBuildParts}

    @classmethod
    def building_build_parts_create(
        cls,
        data: InsertBuildParts,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        created_build = BuildParts.create_action(data=data, token=token_dict)
        created_build.save()
        created_build.update(is_confirmed=True)
        created_build.save()
        return AlchemyJsonResponse(
            completed=True,
            message="Building part created successfully",
            result=created_build,
        )


class BuildingBuildPartsUpdateEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "58fdf95e-2110-4ed6-9c26-95f4be87eaee": "building_build_parts_update"
    }
    __event_validation__ = {"58fdf95e-2110-4ed6-9c26-95f4be87eaee": UpdateBuildParts}

    @classmethod
    def building_build_parts_update(
        cls,
        data: UpdateBuildParts,
        token_dict: Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        updated_build = BuildParts.update_action(data=data, token=token_dict)
        updated_build.save()
        return AlchemyJsonResponse(
            completed=True,
            message="Building part updated successfully",
            result=updated_build,
        )


class BuildingBuildPartsPatchEventMethods(MethodToEvent):

    event_type = "PATCH"
    __event_keys__ = {
        "87a15ade-3474-4206-b574-bbf8580cbb14": "building_build_parts_patch"
    }
    __event_validation__ = {"87a15ade-3474-4206-b574-bbf8580cbb14": None}

    @classmethod
    def building_build_parts_patch(cls, data, token_dict):
        find_one_build = BuildParts.filter_one(
            BuildParts.uu_id == data.uu_id,
        ).data
        access_authorized_build = BuildParts.select_action(
            duty_id=token_dict.selected_company.duty_id,
            filter_expr=[BuildParts.id == find_one_build.id],
        )
        if access_authorized_build.count:
            action = data.excluded_dump()
            find_one_build.active = bool(action.get("active", find_one_build.active))
            find_one_build.is_confirmed = bool(
                action.get("confirm", find_one_build.is_confirmed)
            )
            find_one_build.deleted = bool(action.get("delete", find_one_build.deleted))
            find_one_build.save()
            return AlchemyJsonResponse(
                completed=True,
                message="Building part patched successfully",
                result=find_one_build,
            )
        return AlchemyJsonResponse(
            completed=False,
            message="Building part patched failed",
            result={},
        )


BuildingBuildPartsListEventMethod = BuildingBuildPartsListEventMethods(
    action=ActionsSchema(endpoint="/building/parts/list")
)
BuildingBuildPartsCreateEventMethod = BuildingBuildPartsCreateEventMethods(
    action=ActionsSchema(endpoint="/building/parts/create")
)
BuildingBuildPartsUpdateEventMethod = BuildingBuildPartsUpdateEventMethods(
    action=ActionsSchema(endpoint="/building/parts/update")
)
BuildingBuildPartsPatchEventMethod = BuildingBuildPartsPatchEventMethods(
    action=ActionsSchema(endpoint="/building/parts/patch")
)
