# apps/aroflo_connector_app/zones/invoices/queries.py
from __future__ import annotations

from typing import Any, Dict, List

from ..base import ZoneOperation, ParamSpec
from urllib.parse import urlencode


def get_operations() -> List[ZoneOperation]:
    return [
        ZoneOperation(
            code="list_invoices_by_task",
            label="List Invoices by Task",
            description="Lista invoices filtrando por taskid.",
            http_method="GET",
            side_effect="read",
            idempotent=True,
            params=[
                ParamSpec("taskid", "string", True, "TaskID codificado de AroFlo."),
                ParamSpec("page", "integer", False, "Número de página (1..N)."),
                ParamSpec("raw", "boolean", False, "Devuelve data + meta debug si true."),
            ],
            category="invoices",
            use_cases=["Consultar invoices asociadas a un task específico"],
            risk_level="low",
            requires_confirmation=False,
        ),
        ZoneOperation(
            code="list_invoices_updated_after",
            label="List Approved Invoices updated after DATETIME",
            description=(
                "Lista invoices filtrando por lastupdateddatetime > {updated_after}. "
                "Puedes combinar un filtro base adicional (ej: linkprocessed=false)."
            ),
            http_method="GET",
            side_effect="read",
            idempotent=True,
            params=[
                ParamSpec("updated_after", "string", True, "Formato: YYYY-MM-DD HH:mm:ss"),
                ParamSpec("where_base", "string", False, "Filtro extra (ej: and|linkprocessed|=|false)."),
                ParamSpec("page", "integer", False, "Número de página (1..N)."),
                ParamSpec("raw", "boolean", False, "Devuelve data + meta debug si true."),
            ],
            category="invoices",
            use_cases=["Polling incremental de invoices actualizadas"],
            risk_level="low",
            requires_confirmation=False,
        ),
    ]


def supports(operation_code: str) -> bool:
    return any(op.code == operation_code for op in get_operations())


def _request(client: Any, params_list: List[tuple]) -> Any:
    var_string = urlencode(params_list)
    return client.request("", method="GET", params=params_list, var_string=var_string)


def execute(operation_code: str, client: Any, params: Dict[str, Any]) -> Any:
    raw = bool(params.get("raw", False))
    page = params.get("page", 1)

    if operation_code == "list_invoices_by_task":
        taskid = params["taskid"]
        params_list = [
            ("zone", "invoices"),
            ("where", f"and|taskid|=|{taskid}"),
            ("page", str(page)),
        ]
        resp = _request(client, params_list)
        return {"data": resp, "meta": {"params": params_list, "var_string": urlencode(params_list)}} if raw else resp

    if operation_code == "list_invoices_updated_after":
        updated_after = params["updated_after"]
        where_base = params.get("where_base", "")
        params_list = [("zone", "invoices")]
        if where_base:
            params_list.append(("where", where_base))
        params_list.append(("where", f"and|lastupdateddatetime|>|{updated_after}"))
        params_list.append(("page", str(page)))

        resp = _request(client, params_list)
        return {"data": resp, "meta": {"params": params_list, "var_string": urlencode(params_list)}} if raw else resp

    raise ValueError(f"[Invoices.queries] Operación no soportada: {operation_code}")
