"""Fase 5 — API Tools: Admin / Configuracao / Roles / Jobs / Substitutos"""
import json
from urllib.parse import quote as urlquote
from mcp.server.fastmcp import FastMCP
from http_client import fluig_get, fluig_post, fluig_put, fluig_delete


def register(mcp: FastMCP):

    # ── CONFIGURACOES ────────────────────────────────────────

    @mcp.tool()
    async def fluig_config_listar() -> str:
        """Lista todos os parametros globais de configuracao do sistema Fluig."""
        return await fluig_get("/api/public/2.0/globalparameters/listAll")

    @mcp.tool()
    async def fluig_config_obter(chave: str) -> str:
        """
        Obtem o valor de um parametro global de configuracao.

        Args:
            chave: Chave do parametro. Ex: 'fluig.mail.smtp.host'.
        """
        safe_key = urlquote(str(chave), safe="")
        return await fluig_get(f"/api/public/2.0/globalparameters/{safe_key}")

    # ── PERMISSOES ───────────────────────────────────────────

    @mcp.tool()
    async def fluig_permissao_obter(
        tipo_recurso: str,
        recurso_id: str,
    ) -> str:
        """
        Retorna as permissoes configuradas para um recurso especifico.

        Args:
            tipo_recurso: Tipo do recurso. Ex: 'document', 'workflow', 'community'.
            recurso_id: ID do recurso.
        """
        safe_type = urlquote(str(tipo_recurso), safe="")
        safe_id = urlquote(str(recurso_id), safe="")
        return await fluig_get(f"/api/public/2.0/permissions/{safe_type}/{safe_id}")

    # ── ROLES (PAPEIS) ──────────────────────────────────────

    @mcp.tool()
    async def fluig_role_listar(
        pagina: int = 0,
        tamanho: int = 20,
        ordem: str = "",
    ) -> str:
        """
        Lista todos os papeis (roles) cadastrados no Fluig.

        Args:
            pagina: Pagina de resultados.
            tamanho: Itens por pagina.
            ordem: Campo de ordenacao.
        """
        params: dict = {"page": pagina, "pageSize": tamanho}
        if ordem:
            params["order"] = ordem
        return await fluig_get("/api/v1/roles", params)

    @mcp.tool()
    async def fluig_role_criar(role_json: str) -> str:
        """
        Cria um novo papel (role) no Fluig.

        Args:
            role_json: JSON string com dados do papel (code, description, etc.).
        """
        try:
            body = json.loads(role_json)
        except json.JSONDecodeError as e:
            return f"Erro: role_json invalido - {e}"
        return await fluig_post("/api/v1/roles", body)

    @mcp.tool()
    async def fluig_role_obter(codigo: str) -> str:
        """
        Obtem um papel especifico pelo codigo.

        Args:
            codigo: Codigo do papel. Ex: 'ADMIN'.
        """
        safe_code = urlquote(str(codigo), safe="")
        return await fluig_get(f"/api/v1/roles/{safe_code}")

    @mcp.tool()
    async def fluig_role_atualizar(
        codigo: str,
        role_json: str,
    ) -> str:
        """
        Atualiza um papel existente.

        Args:
            codigo: Codigo do papel a atualizar.
            role_json: JSON string com os campos a atualizar.
        """
        try:
            body = json.loads(role_json)
        except json.JSONDecodeError as e:
            return f"Erro: role_json invalido - {e}"
        safe_code = urlquote(str(codigo), safe="")
        return await fluig_put(f"/api/v1/roles/{safe_code}", body)

    @mcp.tool()
    async def fluig_role_excluir(codigo: str) -> str:
        """
        Exclui um papel (role).

        Args:
            codigo: Codigo do papel a excluir.
        """
        safe_code = urlquote(str(codigo), safe="")
        return await fluig_delete(f"/api/v1/roles/{safe_code}")

    @mcp.tool()
    async def fluig_role_usuarios(
        codigo: str,
        pagina: int = 0,
        tamanho: int = 20,
    ) -> str:
        """
        Lista os usuarios que possuem um papel especifico.

        Args:
            codigo: Codigo do papel.
            pagina: Pagina de resultados.
            tamanho: Usuarios por pagina.
        """
        safe_code = urlquote(str(codigo), safe="")
        return await fluig_get(
            f"/api/v1/roles/{safe_code}/users",
            params={"page": pagina, "pageSize": tamanho},
        )

    # ── JOBS ─────────────────────────────────────────────────

    @mcp.tool()
    async def fluig_job_listar() -> str:
        """Lista todos os jobs agendados configurados na plataforma Fluig."""
        return await fluig_get("/api/public/2.0/jobs/listAll")

    # ── SUBSTITUTOS BPM ──────────────────────────────────────

    @mcp.tool()
    async def fluig_substituto_listar(login_usuario: str = "") -> str:
        """
        Lista os substitutos BPM configurados (delegacao de tarefas).

        Args:
            login_usuario: Login do usuario para filtrar. Vazio = todos.
        """
        params = {}
        if login_usuario:
            params["userId"] = login_usuario
        return await fluig_get(
            "/api/public/2.0/substitute/listAll",
            params if params else None,
        )

    @mcp.tool()
    async def fluig_substituto_criar(
        login_titular: str,
        login_substituto: str,
        data_inicio: str,
        data_fim: str,
        processo_id: str = "",
    ) -> str:
        """
        Configura um substituto para um usuario no BPM (delegacao de tarefas).

        Args:
            login_titular: Login do usuario que sera substituido.
            login_substituto: Login do usuario que assumira as tarefas.
            data_inicio: Data de inicio no formato 'dd/mm/yyyy'. Ex: '01/03/2026'.
            data_fim: Data de fim no formato 'dd/mm/yyyy'. Ex: '31/03/2026'.
            processo_id: Codigo do processo para restringir a substituicao. Vazio = todos os processos.
        """
        body: dict = {
            "colleagueId": login_titular,
            "substituteId": login_substituto,
            "startDate": data_inicio,
            "endDate": data_fim,
        }
        if processo_id:
            body["processId"] = processo_id
        return await fluig_post("/api/public/2.0/substitute/create", body)
