"""Pagination helpers for list endpoints (Hardening 3.3).

Standard usage:

    from app.utils.pagination import paginate_query

    pagination, meta = paginate_query(query)
    items = pagination.items
    return jsonify({'things': [...], **meta})

Meta dict shape:
    {
        'page': 1,
        'per_page': 50,
        'total': 1234,
        'total_pages': 25,
        'has_next': True,
        'has_prev': False,
    }
"""
from flask import request

DEFAULT_PER_PAGE = 50
MAX_PER_PAGE = 200


def get_page_args():
    """Read and clamp ?page= and ?per_page= from the query string."""
    try:
        page = int(request.args.get('page', 1))
    except (TypeError, ValueError):
        page = 1
    try:
        per_page = int(request.args.get('per_page', DEFAULT_PER_PAGE))
    except (TypeError, ValueError):
        per_page = DEFAULT_PER_PAGE
    page = max(page, 1)
    per_page = min(max(per_page, 1), MAX_PER_PAGE)
    return page, per_page


def paginate_query(query, page=None, per_page=None):
    """Paginate a Flask-SQLAlchemy query.

    Returns (pagination, meta) where pagination.items holds the rows
    and meta is a JSON-serializable dict with pagination info.
    """
    if page is None or per_page is None:
        _page, _per_page = get_page_args()
        page = page if page is not None else _page
        per_page = per_page if per_page is not None else _per_page

    pagination = query.paginate(page=page, per_page=per_page, error_out=False)
    meta = {
        'page': pagination.page,
        'per_page': pagination.per_page,
        'total': pagination.total,
        'total_pages': pagination.pages,
        'has_next': pagination.has_next,
        'has_prev': pagination.has_prev,
    }
    return pagination, meta