# suma_browser/app/bp/order/filters/qs.py
from quart import request

from typing import Iterable, Optional, Union

from shared.browser.app.filters.qs_base import KEEP, build_qs
from shared.browser.app.filters.query_types import OrderQuery


def decode() -> OrderQuery:
    """
    Decode current query string into an OrderQuery(page, search).
    """
    try:
        page = int(request.args.get("page", 1) or 1)
    except ValueError:
        page = 1

    search = request.args.get("search") or None
    return OrderQuery(page, search)


def makeqs_factory():
    """
    Build a makeqs(...) that starts from the current filters + page.

    Behaviour:
    - If filters change and you don't explicitly pass page,
      the page is reset to 1 (same pattern as browse/blog).
    - You can clear search with search=None.
    """
    q = decode()
    base_search = q.search or None
    base_page = int(q.page or 1)

    def makeqs(
        *,
        clear_filters: bool = False,
        search: Union[str, None, object] = KEEP,
        page: Union[int, None, object] = None,
        extra: Optional[Iterable[tuple]] = None,
        leading_q: bool = True,
    ) -> str:
        filters_changed = False

        # --- search logic ---
        if search is KEEP and not clear_filters:
            final_search = base_search
        else:
            filters_changed = True
            final_search = (search or None)

        # --- page logic ---
        if page is None:
            final_page = 1 if filters_changed else base_page
        else:
            final_page = page

        # --- build params ---
        params: list[tuple[str, str]] = []

        if final_search:
            params.append(("search", final_search))
        if final_page is not None:
            params.append(("page", str(final_page)))

        if extra:
            for k, v in extra:
                if v is not None:
                    params.append((k, str(v)))

        return build_qs(params, leading_q=leading_q)

    return makeqs
