"""
Users Handler - User management

Phase J.2: 10 tools
- list_users, get_user, get_current_user
- create_user, update_user, delete_user, delete_users
- invite_user, accept_invite, update_current_user
"""

import json
from typing import Any

from plugins.directus.client import DirectusClient


def get_tool_specifications() -> list[dict[str, Any]]:
    """Return tool specifications for ToolGenerator (10 tools)"""
    return [
        {
            "name": "list_users",
            "method_name": "list_users",
            "description": "List all users in Directus with filtering options.",
            "schema": {
                "type": "object",
                "properties": {
                    "filter": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": 'Filter object (e.g., {"status": {"_eq": "active"}})',
                    },
                    "sort": {
                        "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}],
                        "description": "Sort fields (e.g., ['email'])",
                    },
                    "limit": {
                        "type": "integer",
                        "description": "Maximum users to return",
                        "default": 100,
                    },
                    "offset": {"type": "integer", "description": "Users to skip", "default": 0},
                    "search": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Search term",
                    },
                },
                "required": [],
            },
            "scope": "read",
        },
        {
            "name": "get_user",
            "method_name": "get_user",
            "description": "Get user details by ID.",
            "schema": {
                "type": "object",
                "properties": {"id": {"type": "string", "description": "User UUID"}},
                "required": ["id"],
            },
            "scope": "read",
        },
        {
            "name": "get_current_user",
            "method_name": "get_current_user",
            "description": "Get the currently authenticated user.",
            "schema": {"type": "object", "properties": {}, "required": []},
            "scope": "read",
        },
        {
            "name": "create_user",
            "method_name": "create_user",
            "description": "Create a new user.",
            "schema": {
                "type": "object",
                "properties": {
                    "email": {
                        "type": "string",
                        "format": "email",
                        "description": "User email address",
                    },
                    "password": {"type": "string", "minLength": 8, "description": "User password"},
                    "role": {"type": "string", "description": "Role UUID"},
                    "first_name": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "First name",
                    },
                    "last_name": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Last name",
                    },
                    "status": {
                        "type": "string",
                        "enum": ["draft", "invited", "active", "suspended", "archived"],
                        "default": "active",
                        "description": "User status",
                    },
                },
                "required": ["email", "password", "role"],
            },
            "scope": "admin",
        },
        {
            "name": "update_user",
            "method_name": "update_user",
            "description": "Update user details.",
            "schema": {
                "type": "object",
                "properties": {
                    "id": {"type": "string", "description": "User UUID"},
                    "data": {
                        "type": "object",
                        "description": "Fields to update (email, first_name, last_name, role, status, etc.)",
                    },
                },
                "required": ["id", "data"],
            },
            "scope": "admin",
        },
        {
            "name": "delete_user",
            "method_name": "delete_user",
            "description": "Delete a user. This action is irreversible.",
            "schema": {
                "type": "object",
                "properties": {"id": {"type": "string", "description": "User UUID to delete"}},
                "required": ["id"],
            },
            "scope": "admin",
        },
        {
            "name": "delete_users",
            "method_name": "delete_users",
            "description": "Delete multiple users. This action is irreversible.",
            "schema": {
                "type": "object",
                "properties": {
                    "ids": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Array of user UUIDs to delete",
                    }
                },
                "required": ["ids"],
            },
            "scope": "admin",
        },
        {
            "name": "invite_user",
            "method_name": "invite_user",
            "description": "Invite a user by email.",
            "schema": {
                "type": "object",
                "properties": {
                    "email": {
                        "type": "string",
                        "format": "email",
                        "description": "Email to invite",
                    },
                    "role": {"type": "string", "description": "Role UUID for the invited user"},
                    "invite_url": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Custom invite URL",
                    },
                },
                "required": ["email", "role"],
            },
            "scope": "admin",
        },
        {
            "name": "update_current_user",
            "method_name": "update_current_user",
            "description": "Update the currently authenticated user's profile.",
            "schema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "description": "Fields to update (first_name, last_name, language, theme, etc.)",
                    }
                },
                "required": ["data"],
            },
            "scope": "write",
        },
        {
            "name": "get_user_role",
            "method_name": "get_user_role",
            "description": "Get the role of a specific user.",
            "schema": {
                "type": "object",
                "properties": {"id": {"type": "string", "description": "User UUID"}},
                "required": ["id"],
            },
            "scope": "read",
        },
    ]


# =====================
# HANDLER FUNCTIONS
# =====================


async def list_users(
    client: DirectusClient,
    filter: dict | None = None,
    sort: list[str] | None = None,
    limit: int = 100,
    offset: int = 0,
    search: str | None = None,
) -> str:
    """List users."""
    try:
        result = await client.list_users(
            filter=filter, sort=sort, limit=limit, offset=offset, search=search
        )
        users = result.get("data", [])
        return json.dumps(
            {"success": True, "total": len(users), "users": users}, indent=2, ensure_ascii=False
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def get_user(client: DirectusClient, id: str) -> str:
    """Get user by ID."""
    try:
        result = await client.get_user(id)
        return json.dumps(
            {"success": True, "user": result.get("data")}, indent=2, ensure_ascii=False
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def get_current_user(client: DirectusClient) -> str:
    """Get current user."""
    try:
        result = await client.get_current_user()
        return json.dumps(
            {"success": True, "user": result.get("data")}, indent=2, ensure_ascii=False
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def create_user(
    client: DirectusClient,
    email: str,
    password: str,
    role: str,
    first_name: str | None = None,
    last_name: str | None = None,
    status: str = "active",
) -> str:
    """Create a new user."""
    try:
        result = await client.create_user(
            email=email,
            password=password,
            role=role,
            first_name=first_name,
            last_name=last_name,
            status=status,
        )
        return json.dumps(
            {"success": True, "message": f"User {email} created", "user": result.get("data")},
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def update_user(client: DirectusClient, id: str, data: dict[str, Any]) -> str:
    """Update user."""
    try:
        result = await client.update_user(id, data)
        return json.dumps(
            {"success": True, "message": "User updated", "user": result.get("data")},
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def delete_user(client: DirectusClient, id: str) -> str:
    """Delete a user."""
    try:
        await client.delete_user(id)
        return json.dumps({"success": True, "message": f"User {id} deleted"}, indent=2)
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def delete_users(client: DirectusClient, ids: list[str]) -> str:
    """Delete multiple users."""
    try:
        await client.delete_users(ids)
        return json.dumps({"success": True, "message": f"Deleted {len(ids)} users"}, indent=2)
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def invite_user(
    client: DirectusClient, email: str, role: str, invite_url: str | None = None
) -> str:
    """Invite a user."""
    try:
        result = await client.invite_user(email, role, invite_url)
        return json.dumps(
            {
                "success": True,
                "message": f"Invitation sent to {email}",
                "result": result.get("data"),
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def update_current_user(client: DirectusClient, data: dict[str, Any]) -> str:
    """Update current user profile."""
    try:
        # Get current user first to get ID
        current = await client.get_current_user()
        user_id = current.get("data", {}).get("id")
        if not user_id:
            return json.dumps(
                {"success": False, "error": "Cannot determine current user"}, indent=2
            )

        result = await client.update_user(user_id, data)
        return json.dumps(
            {"success": True, "message": "Profile updated", "user": result.get("data")},
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)


async def get_user_role(client: DirectusClient, id: str) -> str:
    """Get user's role."""
    try:
        result = await client.get_user(id)
        user = result.get("data", {})
        role_id = user.get("role")

        if role_id:
            role_result = await client.get_role(role_id)
            return json.dumps(
                {"success": True, "user_id": id, "role": role_result.get("data")},
                indent=2,
                ensure_ascii=False,
            )
        else:
            return json.dumps(
                {
                    "success": True,
                    "user_id": id,
                    "role": None,
                    "message": "User has no role assigned",
                },
                indent=2,
            )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2)
