from databases import (
    Events,
    Services,
    Service2Events,
    Employees,
    Staff,
)

from databases.sql_models.event.event import Event2Employee
from api_events.events.events.events_bind_modules import ModulesBindEmployeeEventMethods

active_confirmed = dict(
    created_by="System",
    confirmed_by="System",
    is_confirmed=True,
    active=True,
    deleted=False,
    is_notification_send=True,
)


def create_all_events_from_actions():
    import api_events.events as events
    from databases import EndpointRestriction

    an_empty_list, duplicate_list = [], []

    for event in events.__all__:
        event_selected = getattr(events, event)
        for (
            event_selected_key,
            event_selected_one,
        ) in event_selected.__event_keys__.items():
            an_empty_list.append(event_selected_key)
            event_selected_function = getattr(event_selected, event_selected_one, None)
            if not event_selected.action.endpoint:
                raise Exception(
                    f"Endpoint not found in {event_selected.__name__} class"
                )
            endpoint_restriction = EndpointRestriction.filter_one(
                EndpointRestriction.endpoint_name.ilike(
                    f"%{event_selected.action.endpoint}%"
                ),
                system=True,
            ).data
            if endpoint_restriction and event_selected_function:
                selected_event = Events.filter_one(
                    Events.event_type == event_selected.event_type,
                    Events.function_class == event,
                    Events.function_code == event_selected_key,
                    Events.endpoint_id == endpoint_restriction.id,
                    Events.endpoint_uu_id == str(endpoint_restriction.uu_id),
                    system=True,
                ).data
                if not selected_event:
                    created_event = Events.find_or_create(
                        event_type=event_selected.event_type,
                        function_class=event,
                        function_code=event_selected_key,
                        endpoint_id=endpoint_restriction.id,
                        endpoint_uu_id=str(endpoint_restriction.uu_id),
                        **active_confirmed,
                    )
                    created_event.save()
                    created_event.update(is_confirmed=True)
                    created_event.save()
                    print(f"Event created: {created_event.uu_id}")

    for item in an_empty_list:
        if an_empty_list.count(item) > 1:
            if item not in duplicate_list:
                duplicate_list.append(item)

    if duplicate_list:
        raise Exception(
            f"Duplicate events found: {duplicate_list}. Check events folder look for given uu-ids."
        )
    return True


def add_events_all_services_and_occupant_types():
    import api_events.tasks2events as tasks2events

    for event_block in tasks2events.__all__:
        event_block_class = getattr(tasks2events, event_block)
        service_selected = Services.filter_one(
            Services.service_code == getattr(event_block_class, "service_code", None),
            system=True,
        ).data
        if not service_selected:
            raise Exception(f"{event_block_class.service_code} service is not found")

        service_selected.update(
            related_responsibility=getattr(event_block_class, "related_code", None)
        )
        for event_id, event_uu_id in event_block_class():
            if Service2Events.filter_by_one(
                service_id=service_selected.id, event_id=event_id, system=True
            ).data:
                continue
            service_events = Service2Events.find_or_create(
                service_id=service_selected.id,
                service_uu_id=str(service_selected.uu_id),
                event_id=event_id,
                event_uu_id=event_uu_id,
            )
            service_events.save_and_confirm()
    return


def add_events_to_system_super_user():

    add_service = Services.filter_by_one(system=True, service_code="SRE-SUE").data
    if not add_service:
        raise Exception("Service not found")

    find_staff = Staff.filter_by_one(system=True, staff_code="SUE").data
    if not find_staff:
        raise Exception("Super User not found")

    add_employee = Employees.filter_by_one(system=True, staff_id=find_staff.id).data
    if not add_employee:
        raise Exception("Super User Employee not found")

    ModulesBindEmployeeEventMethods.bind_default_module_for_first_init_occupant(
        employee_id=add_employee.id
    )
    event_employee = Event2Employee.find_or_create(
        event_service_id=add_service.id,
        event_service_uu_id=str(add_service.uu_id),
        employee_id=add_employee.id,
        employee_uu_id=str(add_employee.uu_id),
    )
    event_employee.save_and_confirm()
