from flask import request
from sqlalchemy import desc, asc

from ._common import get_dict, is_str, is_dict

__all__ = ['get_remote_addr', 'is_ajax', 'get_pss']


def get_remote_addr():
    """
    Get the remote ip address.
    :return:
    """
    return request.environ.get('HTTP_X_REAL_IP', request.remote_addr)


def is_ajax():
    """
    Check if the request is an ajax request.
    :return:
    """
    return request.headers.get('X-Requested-With') == 'XMLHttpRequest'


def get_pss(cls, pss_config=None):
    """
    Get the search, sort and paging information.
    :param cls:
    :param pss_config:
    :return:
    """
    pss_config = get_dict(pss_config)
    search = pss_config.get('search') or {}
    sort = pss_config.get('sort') or {}
    page = pss_config.get('page') or {}
    # --------------------search--------------------
    ands = []
    ors = []
    search_like = search.pop('like', None)
    like_columns = getattr(cls, 'like_columns', None)
    likes = []
    if search_like and like_columns is not None:
        search_like = str(search_like).strip()
        if search_like != '':
            for col in like_columns:
                if is_str(col):
                    col_field = col
                else:
                    col_field = cls.get_column_field(col)
                likes.append(col_field + " like '%" + search_like + "%'")

    _ands = search.pop('_ands', None)
    if _ands:
        for key in _ands:
            _append_item(ands, key, _ands[key])

    _ors = search.pop('_ors', None)
    if _ors:
        for key in _ors:
            _append_item(ors, key, _ors[key])

    for key in search:
        _append_item(ands, key, search[key])
    # --------------------page--------------------
    offset = page.get('offset') or page.get('skip') or 0
    limit = page.get('limit') or page.get('size') or 100000

    # --------------------query--------------------
    sort_field = sort.get('field')  #
    order = sort.get('order')

    if order and sort_field:
        order = str(order).strip().lower()
        if order in ['desc', 'descend', 'descending']:
            order = desc(sort_field)  # default is desc.
        else:
            order = asc(sort_field)
    elif sort_field:
        if is_str(sort_field):
            order = asc(sort_field)
        else:
            order = sort_field
    else:
        order = None

    return {
        'filter_ands': ands,
        'filter_ors': ors,
        'filter_likes': likes,
        'offset': offset,
        'limit': limit,
        'order': order,
    }


def _append_item(items, key, value):
    if value is not None:
        if is_str(value):
            value = value.strip()
            if value != '':
                val_arr = value.split('||')
                for op_v in val_arr:
                    items.append(key + "='" + op_v + "'")
        elif is_dict(value):
            for operator, op_v in value.items():
                items.append(key + operator + str(op_v))
        else:
            items.append(key + '=' + str(value))
    return items
