import typing

from fastapi import status
from fastapi.responses import JSONResponse

from databases import Companies

from api_validations.validations_request import (
    InsertCompany,
    UpdateCompany,
    ListOptions,
    PatchRecord,
)

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 CompanyListEventMethods(MethodToEvent):

    event_type = "SELECT"
    __event_keys__ = {
        "f6900cb5-ac5b-478e-8e7c-fa87e65cd2e5": "company_list",
    }

    @classmethod
    def company_list(
        cls,
        list_options: ListOptions,
        token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        if isinstance(token_dict, EmployeeTokenObject):
            Companies.pre_query = Companies.select_action(
                duty_id_list=[
                    token_dict.selected_company.duty_id,
                    token_dict.selected_company.bulk_duties_id,
                ]
            )
        elif isinstance(token_dict, OccupantTokenObject):
            Companies.pre_query = Companies.filter_all(
                Companies.id == token_dict.selected_occupant.responsible_company_id
            ).query
        Companies.filter_attr = list_options
        records = Companies.filter_all()
        return AlchemyJsonResponse(
            completed=True,
            message="Building Living Spaces are listed successfully",
            result=records,
        )


class CompanyCreateEventMethods(MethodToEvent):

    event_type = "CREATE"
    __event_keys__ = {
        "76f11a08-5f4a-4e1f-961f-aaef21699acd": "company_create",
    }

    @classmethod
    def company_create(
        cls,
        data: InsertCompany,
        token_dict: EmployeeTokenObject,
    ):
        created_company = Companies.create_action(data=data, token=token_dict)
        created_company.update(
            related_company=token_dict.selected_company.company_uu_id
        )
        created_company.save()
        return JSONResponse(
            content={
                "completed": True,
                "message": "Create Company record",
                "data": created_company.get_dict(),
            },
            status_code=status.HTTP_200_OK,
        )


class CompanyUpdateEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "41ea7f29-006a-4310-b5c4-b2a0e1a504bd": "company_update",
    }

    @classmethod
    def company_update(
        cls, company_uu_id: str, data: UpdateCompany, token_dict: EmployeeTokenObject
    ):
        Companies.pre_query = Companies.select_action(
            duty_id_list=[
                token_dict.selected_company.bulk_duties_id,
                token_dict.selected_company.duty_id,
            ],
        )
        find_one_company = Companies.filter_one(
            Companies.uu_id == company_uu_id,
        ).data
        if not find_one_company:
            return JSONResponse(
                content={
                    "completed": True,
                    "message": "Update Company record",
                    "data": {},
                },
                status_code=200,
            )
        updated_company = find_one_company.update(**data.excluded_dump())
        Companies.save()
        return JSONResponse(
            content={
                "completed": True,
                "message": "Update Company record",
                "data": updated_company,
            },
            status_code=200,
        )


class CompanyPatchEventMethods(MethodToEvent):

    event_type = "PATCH"
    __event_keys__ = {
        "6320d696-1fd1-49f9-860a-8f22e5b8a68d": "company_patch",
    }

    @classmethod
    def company_patch(
        cls, company_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
    ):
        find_one_company = Companies.filter_one(
            Companies.uu_id == company_uu_id,
        ).data
        access_authorized_company = Companies.select_action(
            duty_id_list=[
                token_dict.selected_company.bulk_duties_id,
                token_dict.selected_company.duty_id,
            ],
        )
        if access_authorized_company.count:
            action = data.excluded_dump()
            find_one_company.active = bool(
                action.get("active", find_one_company.active)
            )
            find_one_company.is_confirmed = bool(
                action.get("confirm", find_one_company.is_confirmed)
            )
            find_one_company.deleted = bool(
                action.get("delete", find_one_company.deleted)
            )
            find_one_company.save()
            return JSONResponse(
                content={
                    "completed": True,
                    "message": "Patch Company record completed",
                    "data": find_one_company.get_dict(),
                },
                status_code=status.HTTP_200_OK,
            )
        return JSONResponse(
            content={
                "completed": False,
                "message": "Patch Company record failed",
                "data": {},
            },
            status_code=status.HTTP_200_OK,
        )


CompanyPatchEventMethod = CompanyListEventMethods(
    action=ActionsSchema(endpoint="/company/list")
)
CompanyCreateEventMethod = CompanyCreateEventMethods(
    action=ActionsSchema(endpoint="/company/create")
)
CompanyUpdateEventMethod = CompanyUpdateEventMethods(
    action=ActionsSchema(endpoint="/company/update")
)
CompanyListEventMethod = CompanyPatchEventMethods(
    action=ActionsSchema(endpoint="/company/patch")
)
