# apps/aroflo_connector_app/zones/users/join_customfields.py
from __future__ import annotations

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

from ..base import ZoneOperation


def get_operations() -> List[ZoneOperation]:
    """
    Operaciones de la sección 'JOIN customfields' bajo Users.
    """
    return [
        ZoneOperation(
            code="get_users_with_customfields",
            label="Get Users and customfields",
            description="Devuelve usuarios activos y sus customfields.",
            default_params={
                "where": "and|archived|=|false",
                "page": 1,
            },
        ),
        ZoneOperation(
            code="update_user_customfield",
            label="Update Users customfield",
            description="Actualiza un customfield de un usuario concreto.",
            http_method="POST",
        ),
        ZoneOperation(
            code="create_user_with_customfields",
            label="Create User with Custom Fields",
            description="Crea uno o varios usuarios con customfields.",
            http_method="POST",
        ),
    ]


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


# ---------------------------------------------------------------------
#  Helpers XML (para futuros POST, por ahora no los vamos a usar)
# ---------------------------------------------------------------------


def _build_update_customfield_postxml(userid: str, fieldid: str, value: str) -> str:
    return (
        "<users>"
        "<user>"
        f"<userid>{userid}</userid>"
        "<customfields>"
        "<customfield>"
        f"<fieldid>{fieldid}</fieldid>"
        "<value><![CDATA[ " + value + " ]]></value>"
        "</customfield>"
        "</customfields>"
        "</user>"
        "</users>"
    )


def _build_create_user_postxml_from_dict(user: Dict[str, Any]) -> str:
    from typing import List as _List

    simple_fields = [
        "givennames",
        "surname",
        "username",
        "password",
        "email",
        "email2",
        "phone",
        "fax",
        "mobile",
        "accesstype",
    ]

    xml_parts: _List[str] = []
    xml_parts.append("<users><user>")

    for key in simple_fields:
        value = user.get(key)
        if value not in (None, ""):
            xml_parts.append(f"<{key}>{value}</{key}>")

    orgid = user.get("orgid")
    if orgid:
        xml_parts.append("<org>")
        xml_parts.append(f"<orgid>{orgid}</orgid>")
        xml_parts.append("</org>")

    perm_groups = user.get("permissiongroups") or []
    if perm_groups:
        xml_parts.append("<permissiongroups>")
        for pg in perm_groups:
            groupid = pg.get("groupid")
            if not groupid:
                continue
            xml_parts.append("<permissiongroup>")
            xml_parts.append(f"<groupid>{groupid}</groupid>")
            xml_parts.append("</permissiongroup>")
        xml_parts.append("</permissiongroups>")

    customfields = user.get("customfields") or []
    if customfields:
        xml_parts.append("<customfields>")
        for cf in customfields:
            fieldid = cf.get("fieldid")
            name = cf.get("name")
            ctype = cf.get("type")
            value = cf.get("value", "")

            xml_parts.append("<customfield>")
            if fieldid:
                xml_parts.append(f"<fieldid>{fieldid}</fieldid>")
            if name:
                xml_parts.append(f"<name>{name}</name>")
            if ctype:
                xml_parts.append(f"<type>{ctype}</type>")
            xml_parts.append("<value><![CDATA[ " + str(value) + " ]]></value>")
            xml_parts.append("</customfield>")
        xml_parts.append("</customfields>")

    xml_parts.append("</user></users>")
    return "".join(xml_parts)


# ---------------------------------------------------------------------
#  Ejecutor sección
# ---------------------------------------------------------------------


def execute(operation_code: str, client: Any, params: Dict[str, Any]) -> Any:
    """
    Implementa las llamadas reales a AroFlo para JOIN customfields.

    Por ahora solo usamos el GET (Get Users and customfields),
    que es el que estamos probando con la CLI.
    Los POST quedan para la siguiente fase.
    """
    # ---------- GET: Get Users and customfields ----------
    if operation_code == "get_users_with_customfields":
        where = params.get("where", "and|archived|=|false")
        page = params.get("page", 1)

        params_list = [
            ("zone", "users"),
            ("where", where),
            ("join", "customfields"),
            ("page", str(page)),
        ]
        var_string = urlencode(params_list)
        query_params = dict(params_list)

        # Igual que tu ping: path vacío, var_string + params
        return client.request(
            "",
            method="GET",
            params=query_params,
            var_string=var_string,
        )

    # Dejamos los POST para la siguiente fase, para no meter ruido ahora
    if operation_code in ("update_user_customfield", "create_user_with_customfields"):
        raise NotImplementedError(
            f"[Users.join_customfields] Operación '{operation_code}' aún no implementada."
        )

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