"""Issue Handler - manages Gitea issues, labels, milestones, and comments"""

import json
from typing import Any

from plugins.gitea.client import GiteaClient


def get_tool_specifications() -> list[dict[str, Any]]:
    """Return tool specifications for ToolGenerator"""
    return [
        # === ISSUES ===
        {
            "name": "list_issues",
            "method_name": "list_issues",
            "description": "List issues in a Gitea repository with filters. Returns paginated list of issues.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "state": {
                        "type": "string",
                        "description": "Filter by state",
                        "enum": ["open", "closed", "all"],
                        "default": "open",
                    },
                    "labels": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Comma-separated label IDs",
                    },
                    "q": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Search query",
                    },
                    "page": {
                        "type": "integer",
                        "description": "Page number",
                        "default": 1,
                        "minimum": 1,
                    },
                    "limit": {
                        "type": "integer",
                        "description": "Items per page (1-100)",
                        "default": 30,
                        "minimum": 1,
                        "maximum": 100,
                    },
                },
                "required": ["owner", "repo"],
            },
            "scope": "read",
        },
        {
            "name": "get_issue",
            "method_name": "get_issue",
            "description": "Get details of a specific issue by number.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "issue_number": {
                        "type": "integer",
                        "description": "Issue number",
                        "minimum": 1,
                    },
                },
                "required": ["owner", "repo", "issue_number"],
            },
            "scope": "read",
        },
        {
            "name": "create_issue",
            "method_name": "create_issue",
            "description": "Create a new issue in a Gitea repository with optional labels, assignees, and milestone.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "title": {
                        "type": "string",
                        "description": "Issue title",
                        "minLength": 1,
                        "maxLength": 255,
                    },
                    "body": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Issue description (supports Markdown)",
                    },
                    "assignee": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Assignee username",
                    },
                    "assignees": {
                        "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}],
                        "description": "List of assignee usernames",
                    },
                    "labels": {
                        "anyOf": [
                            {"type": "array", "items": {"type": "integer"}},
                            {"type": "null"},
                        ],
                        "description": "List of label IDs",
                    },
                    "milestone": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Milestone ID",
                    },
                    "closed": {
                        "type": "boolean",
                        "description": "Create as closed",
                        "default": False,
                    },
                },
                "required": ["owner", "repo", "title"],
            },
            "scope": "write",
        },
        {
            "name": "update_issue",
            "method_name": "update_issue",
            "description": "Update an existing issue. Can modify title, body, state, assignees, labels, and milestone.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "issue_number": {
                        "type": "integer",
                        "description": "Issue number",
                        "minimum": 1,
                    },
                    "title": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Issue title",
                    },
                    "body": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Issue description",
                    },
                    "state": {
                        "anyOf": [{"type": "string", "enum": ["open", "closed"]}, {"type": "null"}],
                        "description": "Issue state",
                    },
                    "assignee": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Assignee username",
                    },
                    "assignees": {
                        "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}],
                        "description": "List of assignee usernames",
                    },
                    "labels": {
                        "anyOf": [
                            {"type": "array", "items": {"type": "integer"}},
                            {"type": "null"},
                        ],
                        "description": "List of label IDs",
                    },
                    "milestone": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Milestone ID",
                    },
                },
                "required": ["owner", "repo", "issue_number"],
            },
            "scope": "write",
        },
        {
            "name": "close_issue",
            "method_name": "close_issue",
            "description": "Close an issue.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "issue_number": {
                        "type": "integer",
                        "description": "Issue number",
                        "minimum": 1,
                    },
                },
                "required": ["owner", "repo", "issue_number"],
            },
            "scope": "write",
        },
        {
            "name": "reopen_issue",
            "method_name": "reopen_issue",
            "description": "Reopen a closed issue.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "issue_number": {
                        "type": "integer",
                        "description": "Issue number",
                        "minimum": 1,
                    },
                },
                "required": ["owner", "repo", "issue_number"],
            },
            "scope": "write",
        },
        # === COMMENTS ===
        {
            "name": "list_issue_comments",
            "method_name": "list_issue_comments",
            "description": "List all comments on an issue.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "issue_number": {
                        "type": "integer",
                        "description": "Issue number",
                        "minimum": 1,
                    },
                },
                "required": ["owner", "repo", "issue_number"],
            },
            "scope": "read",
        },
        {
            "name": "create_issue_comment",
            "method_name": "create_issue_comment",
            "description": "Add a comment to an issue.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "issue_number": {
                        "type": "integer",
                        "description": "Issue number",
                        "minimum": 1,
                    },
                    "body": {
                        "type": "string",
                        "description": "Comment body (supports Markdown)",
                        "minLength": 1,
                    },
                },
                "required": ["owner", "repo", "issue_number", "body"],
            },
            "scope": "write",
        },
        # === LABELS ===
        {
            "name": "list_labels",
            "method_name": "list_labels",
            "description": "List all labels in a repository.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                },
                "required": ["owner", "repo"],
            },
            "scope": "read",
        },
        {
            "name": "create_label",
            "method_name": "create_label",
            "description": "Create a new label in a repository.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "name": {
                        "type": "string",
                        "description": "Label name",
                        "minLength": 1,
                        "maxLength": 50,
                    },
                    "color": {
                        "type": "string",
                        "description": "Label color (hex without #, e.g., 'ff0000')",
                        "pattern": "^[0-9A-Fa-f]{6}$",
                    },
                    "description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Label description",
                        "maxLength": 200,
                    },
                },
                "required": ["owner", "repo", "name", "color"],
            },
            "scope": "write",
        },
        {
            "name": "delete_label",
            "method_name": "delete_label",
            "description": "Delete a label from a repository.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "label_id": {
                        "type": "integer",
                        "description": "Label ID to delete",
                        "minimum": 1,
                    },
                },
                "required": ["owner", "repo", "label_id"],
            },
            "scope": "write",
        },
        # === MILESTONES ===
        {
            "name": "list_milestones",
            "method_name": "list_milestones",
            "description": "List all milestones in a repository.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "state": {
                        "anyOf": [
                            {"type": "string", "enum": ["open", "closed", "all"]},
                            {"type": "null"},
                        ],
                        "description": "Filter by state",
                        "default": "open",
                    },
                },
                "required": ["owner", "repo"],
            },
            "scope": "read",
        },
        {
            "name": "create_milestone",
            "method_name": "create_milestone",
            "description": "Create a new milestone in a repository.",
            "schema": {
                "type": "object",
                "properties": {
                    "owner": {"type": "string", "description": "Repository owner", "minLength": 1},
                    "repo": {"type": "string", "description": "Repository name", "minLength": 1},
                    "title": {
                        "type": "string",
                        "description": "Milestone title",
                        "minLength": 1,
                        "maxLength": 255,
                    },
                    "description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Milestone description",
                    },
                    "due_on": {
                        "anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}],
                        "description": "Due date (ISO 8601 format)",
                    },
                    "state": {
                        "type": "string",
                        "description": "State",
                        "enum": ["open", "closed"],
                        "default": "open",
                    },
                },
                "required": ["owner", "repo", "title"],
            },
            "scope": "write",
        },
    ]


async def list_issues(
    client: GiteaClient,
    owner: str,
    repo: str,
    state: str = "open",
    labels: str | None = None,
    q: str | None = None,
    page: int = 1,
    limit: int = 30,
) -> str:
    """List repository issues"""
    params = {"state": state, "labels": labels, "q": q, "page": page, "limit": limit}
    issues = await client.list_issues(owner, repo, params)
    result = {"success": True, "count": len(issues), "issues": issues}
    return json.dumps(result, indent=2)


async def get_issue(client: GiteaClient, owner: str, repo: str, issue_number: int) -> str:
    """Get issue details"""
    issue = await client.get_issue(owner, repo, issue_number)
    result = {"success": True, "issue": issue}
    return json.dumps(result, indent=2)


async def create_issue(
    client: GiteaClient,
    owner: str,
    repo: str,
    title: str,
    body: str | None = None,
    assignee: str | None = None,
    assignees: list[str] | None = None,
    labels: list[int] | None = None,
    milestone: int | None = None,
    closed: bool = False,
) -> str:
    """Create a new issue"""
    data = {
        "title": title,
        "body": body,
        "assignee": assignee,
        "assignees": assignees,
        "labels": labels,
        "milestone": milestone,
        "closed": closed,
    }
    issue = await client.create_issue(owner, repo, data)
    result = {
        "success": True,
        "message": f"Issue #{issue['number']} created successfully",
        "issue": issue,
    }
    return json.dumps(result, indent=2)


async def update_issue(
    client: GiteaClient, owner: str, repo: str, issue_number: int, **kwargs
) -> str:
    """Update an issue"""
    # Build update data from kwargs
    data = {
        k: v
        for k, v in kwargs.items()
        if v is not None and k not in ["owner", "repo", "issue_number"]
    }

    issue = await client.update_issue(owner, repo, issue_number, data)
    result = {
        "success": True,
        "message": f"Issue #{issue_number} updated successfully",
        "issue": issue,
    }
    return json.dumps(result, indent=2)


async def close_issue(client: GiteaClient, owner: str, repo: str, issue_number: int) -> str:
    """Close an issue"""
    data = {"state": "closed"}
    issue = await client.update_issue(owner, repo, issue_number, data)
    result = {
        "success": True,
        "message": f"Issue #{issue_number} closed successfully",
        "issue": issue,
    }
    return json.dumps(result, indent=2)


async def reopen_issue(client: GiteaClient, owner: str, repo: str, issue_number: int) -> str:
    """Reopen an issue"""
    data = {"state": "open"}
    issue = await client.update_issue(owner, repo, issue_number, data)
    result = {
        "success": True,
        "message": f"Issue #{issue_number} reopened successfully",
        "issue": issue,
    }
    return json.dumps(result, indent=2)


# Comment operations
async def list_issue_comments(client: GiteaClient, owner: str, repo: str, issue_number: int) -> str:
    """List issue comments"""
    comments = await client.list_issue_comments(owner, repo, issue_number)
    result = {"success": True, "count": len(comments), "comments": comments}
    return json.dumps(result, indent=2)


async def create_issue_comment(
    client: GiteaClient, owner: str, repo: str, issue_number: int, body: str
) -> str:
    """Create issue comment"""
    data = {"body": body}
    comment = await client.create_issue_comment(owner, repo, issue_number, data)
    result = {
        "success": True,
        "message": f"Comment added to issue #{issue_number}",
        "comment": comment,
    }
    return json.dumps(result, indent=2)


# Label operations
async def list_labels(client: GiteaClient, owner: str, repo: str) -> str:
    """List repository labels"""
    labels = await client.list_labels(owner, repo)
    result = {"success": True, "count": len(labels), "labels": labels}
    return json.dumps(result, indent=2)


async def create_label(
    client: GiteaClient,
    owner: str,
    repo: str,
    name: str,
    color: str,
    description: str | None = None,
) -> str:
    """Create a label"""
    data = {"name": name, "color": color, "description": description}
    label = await client.create_label(owner, repo, data)
    result = {"success": True, "message": f"Label '{name}' created successfully", "label": label}
    return json.dumps(result, indent=2)


async def delete_label(client: GiteaClient, owner: str, repo: str, label_id: int) -> str:
    """Delete a label"""
    await client.delete_label(owner, repo, label_id)
    result = {"success": True, "message": f"Label {label_id} deleted successfully"}
    return json.dumps(result, indent=2)


# Milestone operations
async def list_milestones(
    client: GiteaClient, owner: str, repo: str, state: str | None = None
) -> str:
    """List repository milestones"""
    milestones = await client.list_milestones(owner, repo, state=state)
    result = {"success": True, "count": len(milestones), "milestones": milestones}
    return json.dumps(result, indent=2)


async def create_milestone(
    client: GiteaClient,
    owner: str,
    repo: str,
    title: str,
    description: str | None = None,
    due_on: str | None = None,
    state: str = "open",
) -> str:
    """Create a milestone"""
    data = {"title": title, "description": description, "due_on": due_on, "state": state}
    milestone = await client.create_milestone(owner, repo, data)
    result = {
        "success": True,
        "message": f"Milestone '{title}' created successfully",
        "milestone": milestone,
    }
    return json.dumps(result, indent=2)
