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

from typing import Any, Dict, List, Tuple
from urllib.parse import urlencode

from ..base import ZoneOperation, ParamSpec


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


def _raw_wrap(resp: Any, params_list: List[Tuple[str, str]]) -> Dict[str, Any]:
    return {"data": resp, "meta": {"params": params_list, "var_string": urlencode(params_list)}}


def _coerce_maxpageresults(params: Dict[str, Any]) -> str | None:
    if "maxpageresults" not in params:
        return None
    v = params.get("maxpageresults")
    if v in (None, ""):
        return None
    try:
        iv = int(v)
    except Exception:
        raise ValueError("maxpageresults debe ser un entero.")
    if iv <= 0:
        raise ValueError("maxpageresults debe ser > 0.")
    return str(iv)


def get_operations() -> List[ZoneOperation]:
    return [
        # GENÉRICO (este es el que el CLI intenta llamar con `invoices task`)
        ZoneOperation(
            code="get_invoices_with_task",
            label="Invoices JOIN task",
            description="Devuelve invoices incluyendo join=task. Acepta WHERE genérico.",
            http_method="GET",
            side_effect="read",
            idempotent=True,
            default_params={"where": "and|createdutc|>|2001-01-01", "page": 1, "maxpageresults": None, "raw": False},
            params=[
                ParamSpec("where", "string", False, "Cláusula WHERE estilo AroFlo."),
                ParamSpec("page", "integer", False, "Número de página (1..N)."),
                ParamSpec("maxpageresults", "integer", False, "Límite de registros por página (si AroFlo lo soporta)."),
                ParamSpec("raw", "boolean", False, "Si es true, devuelve respuesta cruda (debug)."),
            ],
            category="invoices",
            use_cases=["Traer invoice + task para enlazar con jobnumber/taskid"],
            risk_level="low",
            requires_confirmation=False,
        ),
        # SHORTCUT (lo conservas)
        ZoneOperation(
            code="get_approved_unprocessed_invoices_with_task",
            label="Get Approved Unprocessed Invoices (JOIN task)",
            description="Invoices Approved + linkprocessed=false incluyendo join=task.",
            http_method="GET",
            side_effect="read",
            idempotent=True,
            default_params={"page": 1, "maxpageresults": None, "raw": False},
            params=[
                ParamSpec("page", "integer", False, "Número de página (1..N)."),
                ParamSpec("maxpageresults", "integer", False, "Límite de registros por página (si AroFlo lo soporta)."),
                ParamSpec("raw", "boolean", False, "Si es true, devuelve respuesta cruda (debug)."),
            ],
            category="invoices",
            use_cases=["Extraer invoices aprobadas con datos de task"],
            risk_level="low",
            requires_confirmation=False,
        ),
    ]


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


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

    if operation_code == "get_invoices_with_task":
        where = params.get("where", "and|createdutc|>|2001-01-01")
        params_list: List[Tuple[str, str]] = [
            ("zone", "invoices"),
            ("where", where),
            ("join", "task"),
        ]
        if maxpageresults:
            params_list.append(("maxpageresults", maxpageresults))
        params_list.append(("page", page))
        resp = _request(client, params_list)
        return _raw_wrap(resp, params_list) if raw else resp

    if operation_code == "get_approved_unprocessed_invoices_with_task":
        params_list = [
            ("zone", "invoices"),
            ("where", "and|status|=|Approved"),
            ("where", "and|linkprocessed|=|false"),
            ("join", "task"),
        ]
        if maxpageresults:
            params_list.append(("maxpageresults", maxpageresults))
        params_list.append(("page", page))
        resp = _request(client, params_list)
        return _raw_wrap(resp, params_list) if raw else resp

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