import typing

from databases import (
    Modules,
    BuildLivingSpace,
)
from api_validations.validations_request import (
    RegisterModules2Occupant,
    RegisterModules2Employee,
)
from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject, OccupantTokenObject
from api_library.date_time_actions.date_functions import system_arrow
from databases.sql_models.company.employee import Employees
from databases.sql_models.event.event import Event2Occupant, Event2Employee


class ModulesBindOccupantEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "91003e90-8ead-4705-98a3-f8731c6ecb38": "modules_bind_occupant",
    }
    __event_validation__ = {
        "91003e90-8ead-4705-98a3-f8731c6ecb38": None,
    }

    @classmethod
    def bind_default_module_for_first_init_occupant(
        cls, build_living_space_id: int, expires_at: str = None
    ):

        living_space = BuildLivingSpace.filter_one(
            BuildLivingSpace.id == build_living_space_id, system=True
        ).data
        modules = Modules.filter_all(Modules.is_default_module == True).data
        print("living_space", living_space, "modules", modules)
        if not living_space or not modules:
            print(f"Giving living Space or Modules: Default not found")
            return
        service_build_dict = dict(build_living_space_id=living_space.id)
        if expires_at:
            service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
        else:
            expiry_ends = str(system_arrow.get(living_space.expiry_ends))
            service_build_dict["expires_at"] = expiry_ends

        for module in modules:
            for service in module.retrieve_services():
                event_occupant = Event2Occupant.find_or_create(
                    event_service_id=service.id,
                    event_service_uu_id=str(service.uu_id),
                    build_living_space_id=living_space.id,
                    build_living_space_uu_id=str(living_space.uu_id),
                )
                event_occupant.save_and_confirm()
        return True

    # @classmethod
    # def modules_bind_occupant_system(
    #     cls, build_living_space_id: int, modules_id: int, expires_at: str = None
    # ):
    #
    #     living_space = BuildLivingSpace.filter_one(
    #         BuildLivingSpace.id == build_living_space_id,
    #     ).data
    #     modules = Modules.filter_one(Modules.id == modules_id).data
    #
    #     if not living_space or not modules:
    #         print(f"Giving living Space or Modules: {modules.module_name} not found")
    #         return
    #     service_build_dict = dict(build_living_space_id=living_space.id)
    #     if expires_at:
    #         service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
    #     else:
    #         service_build_dict["expires_at"] = str(
    #             system_arrow.get(living_space.expiry_ends)
    #         )
    #
    #     for service in modules.retrieve_services():
    #         ServiceBindOccupantEventMethods.bind_services_occupant_system(
    #             **service_build_dict,
    #             service_id=service.id,
    #         )
    #     BuildLivingSpace.save()
    #     return True

    @classmethod
    def modules_bind_occupant(
        cls,
        data: RegisterModules2Occupant,
        token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
    ):

        return


class ModulesBindEmployeeEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "d4ed23db-62e9-4015-b7c0-698a7917aa0c": "modules_bind_employee",
    }
    __event_validation__ = {
        "d4ed23db-62e9-4015-b7c0-698a7917aa0c": None,
    }

    @classmethod
    def bind_default_module_for_first_init_occupant(
        cls, employee_id: int, expires_at: str = None
    ):

        employee = Employees.filter_one(
            Employees.id == employee_id,
        ).data
        modules = Modules.filter_all(Modules.is_default_module == True).data
        print("living_space", employee, "modules", modules)
        if not employee or not modules:
            print(f"Giving living Space or Modules: Default not found")
            return
        service_build_dict = dict(build_living_space_id=employee.id)
        if expires_at:
            service_build_dict["expires_at"] = str(system_arrow.get(expires_at))
        else:
            expiry_ends = str(system_arrow.get(employee.expiry_ends))
            service_build_dict["expires_at"] = expiry_ends

        for module in modules:
            for service in module.retrieve_services():
                event_employee = Event2Employee.find_or_create(
                    event_service_id=service.id,
                    event_service_uu_id=str(service.uu_id),
                    employee_id=employee.id,
                    employee_uu_id=str(employee.uu_id),
                )
                event_employee.save_and_confirm()
        return True

    @classmethod
    def modules_bind_employee(
        cls,
        data: RegisterModules2Employee,
        token_dict: typing.Union[EmployeeTokenObject, OccupantTokenObject],
    ):
        return


ModulesBindOccupantEventMethod = ModulesBindOccupantEventMethods(
    action=ActionsSchema(endpoint="/bind/modules/occupant")
)
ModulesBindEmployeeEventMethod = ModulesBindEmployeeEventMethods(
    action=ActionsSchema(endpoint="/bind/modules/employee")
)
