from __future__ import annotations

from collections.abc import Mapping, Sequence
from pathlib import Path

from influxdb_client.client.influxdb_client import InfluxDBClient

from .query_build import build_query
from ..settings import load_settings


def query_rows(
    *,
    settings_path: str | Path | None = None,
    bucket: str | None = None,
    start: str = "-1h",
    stop: str | None = None,
    measurement: str | None = None,
    fields: Sequence[str] | None = None,
    tags: Mapping[str, str] | None = None,
    columns: Sequence[str] | None = None,
    limit: int | None = None,
    sort_desc: bool = False,
) -> list[dict[str, object]]:
    """Run a query and return result rows as dictionaries.

    Parameters
    ----------
    settings_path : str | Path | None, default=None
        Optional path to settings TOML.
    bucket : str | None, default=None
        Optional bucket override. Defaults to value from settings.
    start : str, default="-1h"
        Flux start time expression.
    stop : str | None, default=None
        Optional Flux stop time expression.
    measurement : str | None, default=None
        Optional measurement filter.
    fields : Sequence[str] | None, default=None
        Optional field list filter.
    tags : Mapping[str, str] | None, default=None
        Optional tag equality filters.
    columns : Sequence[str] | None, default=None
        Optional keep-column list.
    limit : int | None, default=None
        Optional row limit.
    sort_desc : bool, default=False
        If ``True``, sort by ``_time`` descending.

    Returns
    -------
    list[dict[str, object]]
        Query result rows.
    """
    settings = load_settings(settings_path)
    query = build_query(
        bucket=bucket or settings.bucket,
        start=start,
        stop=stop,
        measurement=measurement,
        fields=fields,
        tags=tags,
        columns=columns,
        limit=limit,
        sort_desc=sort_desc,
    )

    client = InfluxDBClient(url=settings.url, token=settings.token, org=settings.org)
    try:
        tables = client.query_api().query(query=query, org=settings.org)
    finally:
        client.close()

    rows: list[dict[str, object]] = []
    for table in tables:
        for record in table.records:
            rows.append({str(key): value for key, value in record.values.items()})
    return rows
