from sqlalchemy import or_


def sort_to_sqlalchemy(model: any, column_name: str, order: int, allowed_columns: dict, default_column: str):
    column = getattr(model, allowed_columns.get(column_name, default_column))
    sort_function = {
        1: lambda c: c.asc(),
        -1: lambda c: c.desc()
    }.get(order, lambda c: c.asc())

    return sort_function(column)


def filter_to_sqlalchemy(model: any, filter_data: dict, allowed_columns: dict) -> list:

    filter_modes = {
        'startsWith': lambda column, value: column.like("{}%".format(value)),
        'contains': lambda column, value: column.like("%{}%".format(value)),
        'endsWith': lambda column, value: column.like("%{}".format(value)),
        'equals': lambda column, value: column == value,
        'notEquals': lambda column, value: column != value,
        'in': lambda column, value: column.in_(value),
        'lt': lambda column, value: column > value,
        'lte': lambda column, value: column >= value,
        'gt': lambda column, value: column < value,
        'gte': lambda column, value: column <= value
    }

    filter_list = []

    for filter_name, filter_parameters in filter_data.items():
        filter_function = filter_modes.get(
            filter_parameters.get('match_mode'),
            lambda column, value: column.like("%{}%".format(value))
        )

        if filter_name == 'global':
            filter_list_or = []
            for column_name in allowed_columns.values():
                filter_list_or.append(filter_function(getattr(model, column_name), filter_parameters['value']))
            filter_list.append(or_(*filter_list_or))
        else:
            column_name = allowed_columns.get(filter_name)
            if column_name:
                filter_list.append(filter_function(getattr(model, column_name), filter_parameters['value']))

    return filter_list
