# /apps/aroflo_connector_app/zones/tasks/base.py
from __future__ import annotations

from typing import Any, Dict, List, Tuple, Optional

from ..base import ZoneOperation, ParamSpec
from ._join_utils import request, raw_wrap, coerce_page_size, coerce_order, build_list_params

# -------------------------
# Operation codes (READ base)
# -------------------------
OP_LIST = "list_tasks"
OP_GET = "get_task"
OP_DUE_RANGE = "get_tasks_due_for_date_range"


# -------------------------
# Operations registry (READ base only)
# -------------------------
def get_operations() -> List[ZoneOperation]:
    return [
        ZoneOperation(
            code=OP_LIST,
            label="List Tasks",
            description="Devuelve una lista paginada de tasks (zone=tasks). Soporta filtro WHERE y ORDER.",
            http_method="GET",
            side_effect="read",
            idempotent=True,
            default_params={
                "where": "and|createdutc|>|2001-01-01",
                "order": None,
                "page": 1,
                "pageSize": None,
                "raw": False,
            },
            params=[
                ParamSpec("where", "string", False, "Cláusula WHERE estilo AroFlo."),
                ParamSpec("order", "string", False, "Orden: campo|asc o campo|desc (AroFlo 'order')."),
                ParamSpec("page", "integer", False, "Número de página (1..N)."),
                ParamSpec("pageSize", "integer", False, "Cantidad de registros por página (AroFlo pageSize)."),
                ParamSpec("raw", "boolean", False, "Si true, devuelve respuesta cruda + meta debug."),
            ],
            category="tasks",
            use_cases=["Listar tasks", "Filtrar tasks usando WHERE", "Ordenar tasks usando ORDER"],
            risk_level="low",
            requires_confirmation=False,
        ),
        ZoneOperation(
            code=OP_GET,
            label="Get Task",
            description="Obtiene un task específico filtrando por taskid (zone=tasks where=and|taskid|=|...).",
            http_method="GET",
            side_effect="read",
            idempotent=True,
            default_params={"raw": False},
            params=[
                ParamSpec("taskid", "string", True, "TaskID codificado en AroFlo."),
                ParamSpec("raw", "boolean", False, "Si true, devuelve respuesta cruda + meta debug."),
            ],
            category="tasks",
            use_cases=["Consultar detalle de un task por taskid"],
            risk_level="low",
            requires_confirmation=False,
        ),
        ZoneOperation(
            code=OP_DUE_RANGE,
            label="Get Tasks due for a date range",
            description=(
                "Devuelve tasks filtrados por rango de fechas usando daterangetype + fromdate/todate. "
                "Soporta WHERE adicional, ORDER y paginación."
            ),
            http_method="GET",
            side_effect="read",
            idempotent=True,
            default_params={
                "daterangetype": "DueDate",
                "fromdate": "2025-01-01",
                "todate": "2025-01-31",
                "where": None,
                "order": None,
                "page": 1,
                "pageSize": None,
                "raw": False,
            },
            params=[
                ParamSpec("daterangetype", "string", True, "Tipo de rango (ej: DueDate)."),
                ParamSpec("fromdate", "string", True, "Fecha inicio (YYYY-MM-DD)."),
                ParamSpec("todate", "string", True, "Fecha fin (YYYY-MM-DD)."),
                ParamSpec("where", "string", False, "Cláusula WHERE estilo AroFlo."),
                ParamSpec("order", "string", False, "Orden: campo|asc o campo|desc (AroFlo 'order')."),
                ParamSpec("page", "integer", False, "Número de página (1..N)."),
                ParamSpec("pageSize", "integer", False, "Cantidad de registros por página (AroFlo pageSize)."),
                ParamSpec("raw", "boolean", False, "Si true, devuelve respuesta cruda + meta debug."),
            ],
            category="tasks",
            use_cases=["Listar tasks por rango de fechas (DueDate)", "Filtrar por WHERE", "Ordenar por ORDER"],
            risk_level="low",
            requires_confirmation=False,
        ),
    ]


def supports(operation_code: str) -> bool:
    # IMPORTANTE: base.py solo soporta READ base.
    return operation_code in {OP_LIST, OP_GET, OP_DUE_RANGE}


# -------------------------
# Execute (READ base only)
# -------------------------
def execute(operation_code: str, client: Any, params: Dict[str, Any]) -> Any:
    raw = bool(params.get("raw", False))
    pageSize = coerce_page_size(params)  # maneja pageSize/pagesize si tu helper lo soporta
    order = coerce_order(params)

    if operation_code == OP_LIST:
        where = params.get("where", "and|createdutc|>|2001-01-01")
        page = int(params.get("page", 1))
        if page < 1:
            raise ValueError("page debe ser >= 1.")

        params_list = build_list_params(
            zone="tasks",
            where=where,
            join=None,
            order=order,
            page=page,
            pageSize=pageSize,
        )

        resp = request(client, "GET", params_list)
        return raw_wrap(resp, params_list) if raw else resp

    if operation_code == OP_GET:
        taskid = params["taskid"]
        where = f"and|taskid|=|{taskid}"
        params_list: List[Tuple[str, str]] = [("zone", "tasks"), ("where", where), ("page", "1")]

        resp = request(client, "GET", params_list)
        return raw_wrap(resp, params_list) if raw else resp

    if operation_code == OP_DUE_RANGE:
        daterangetype = params["daterangetype"]
        fromdate = params["fromdate"]
        todate = params["todate"]
        page = int(params.get("page", 1))
        if page < 1:
            raise ValueError("page debe ser >= 1.")

        params_list: List[Tuple[str, str]] = [
            ("zone", "tasks"),
            ("daterangetype", str(daterangetype)),
            ("fromdate", str(fromdate)),
            ("todate", str(todate)),
        ]

        where = params.get("where")
        if where:
            params_list.append(("where", where))

        if order:
            params_list.append(("order", order))

        if pageSize:
            params_list.append(("pageSize", pageSize))

        params_list.append(("page", str(page)))

        resp = request(client, "GET", params_list)
        return raw_wrap(resp, params_list) if raw else resp

    # Si entra aquí, supports() está mal o el dispatcher no corresponde.
    raise ValueError(f"[Tasks.base] Operación no soportada: {operation_code}")
