"""Jira data agent — A2A server using pydantic-ai with mock ticket data."""
import os
from pathlib import Path

from loguru import logger as _log
from pydantic_ai import RunContext

from backend.chanakya.a2a_context import RequestContext, make_metadata_aware_app
from backend.chanakya.base import EnterpriseAgent
from backend.chanakya.config import AGENT_REGISTRY
from data.mock_data.tickets import TICKETS
from pylogue.shell import app_factory as create_core_app

_cfg = AGENT_REGISTRY["jira"]

_TICKETS_BY_ID = {t["id"]: t for t in TICKETS}

_JIRA_AGENT_PROMPT = """\
You are a Jira data agent. You answer questions about Tata Steel's Jira tickets using mock data.
Always cite the issue key and status in your answers.
Use search_jql for keyword or JQL-style queries, search_tickets for full-text keyword search,
get_ticket for a specific issue, and filter_tickets for status/priority/label/project/assignee filtering.
If a tool returns no results, respond with a clear 'nothing found' message.
"""


def _fmt_ticket(t: dict) -> str:
    return (
        f"[{t['id']}] {t['status']} | {t['priority']} | {t['summary']}\n"
        f"Type: {t['type']} | Assignee: {t['assignee']} | Reporter: {t['reporter']}\n"
        f"Created: {t['created']} | Updated: {t['updated']}\n"
        f"Project: {t['project']} | Labels: {', '.join(t.get('labels', [])) or 'none'}"
    )


jira_agent = EnterpriseAgent(
    api_base=os.environ["LITELLM_PROVIDER_BASE_URL"],
    instructions=_JIRA_AGENT_PROMPT,
    logfire_env="chanakya-alpha",
    service_name="jira",
    deps_type=RequestContext,
)


@jira_agent.tool
def search_jql(ctx: RunContext[RequestContext], jql: str, max_results: int = 20) -> str:
    """Search tickets using a keyword or JQL-style query string.

    The query is matched against ticket summary, description, project, and labels.

    Args:
        jql: Keyword or phrase to search for, e.g. 'coal supply' or 'status = In Progress'.
        max_results: Maximum number of results to return (default 20).
    """
    _log.debug("search_jql caller={} jql={!r}", ctx.deps.user_email, jql)
    term = jql.lower()
    matches = [
        t for t in TICKETS
        if term in t["summary"].lower()
        or term in t.get("description", "").lower()
        or term in t["project"].lower()
        or any(term in lbl for lbl in t.get("labels", []))
    ][:max_results]
    if not matches:
        return f"No issues found for query: {jql}"
    return "\n---\n".join(_fmt_ticket(t) for t in matches)


@jira_agent.tool
def search_tickets(ctx: RunContext[RequestContext], query: str, project: str = "", max_results: int = 20) -> str:
    """Search tickets by keyword across summary, description, and labels.

    Args:
        query: Keyword or phrase to search.
        project: Optional project key to scope the search, e.g. 'bf3-coal-supply'.
        max_results: Maximum number of results to return (default 20).
    """
    _log.debug("search_tickets caller={} query={!r} project={!r}", ctx.deps.user_email, query, project)
    term = query.lower()
    results = [
        t for t in TICKETS
        if (not project or t["project"] == project)
        and (
            term in t["summary"].lower()
            or term in t.get("description", "").lower()
            or any(term in lbl for lbl in t.get("labels", []))
        )
    ][:max_results]
    if not results:
        return f"No tickets found matching '{query}'."
    return "\n---\n".join(_fmt_ticket(t) for t in results)


@jira_agent.tool
def get_ticket(ctx: RunContext[RequestContext], ticket_id: str) -> str:
    """Retrieve full details of a specific ticket by ID.

    Args:
        ticket_id: Issue key, e.g. 'TS-101'.
    """
    _log.debug("get_ticket caller={} ticket={}", ctx.deps.user_email, ticket_id)
    t = _TICKETS_BY_ID.get(ticket_id.upper())
    if not t:
        return f"Ticket '{ticket_id}' not found."
    return (
        f"Key: {t['id']} | Type: {t['type']} | Status: {t['status']} | Priority: {t['priority']}\n"
        f"Summary: {t['summary']}\n"
        f"Assignee: {t['assignee']} | Reporter: {t['reporter']}\n"
        f"Created: {t['created']} | Updated: {t['updated']}\n"
        f"Project: {t['project']} | Labels: {', '.join(t.get('labels', [])) or 'none'}\n\n"
        f"{t.get('description', '(no description)')}"
    )


@jira_agent.tool
def filter_tickets(
    ctx: RunContext[RequestContext],
    status: str = "",
    priority: str = "",
    label: str = "",
    project: str = "",
    assignee: str = "",
    max_results: int = 20,
) -> str:
    """Filter tickets by status, priority, label, project, or assignee.

    Args:
        status: Filter by status, e.g. 'Open', 'In Progress', 'Done', 'To Do'.
        priority: Filter by priority, e.g. 'Critical', 'High', 'Medium', 'Low'.
        label: Filter by label, e.g. 'safety', 'procurement'.
        project: Filter by project key, e.g. 'bf3-coal-supply'.
        assignee: Filter by assignee email or partial name.
        max_results: Maximum number of results to return (default 20).
    """
    if not any([status, priority, label, project, assignee]):
        return "Please provide at least one filter criterion."

    results = [
        t for t in TICKETS
        if (not status or t["status"].lower() == status.lower())
        and (not priority or t["priority"].lower() == priority.lower())
        and (not label or label.lower() in [lbl.lower() for lbl in t.get("labels", [])])
        and (not project or t["project"].lower() == project.lower())
        and (not assignee or assignee.lower() in t["assignee"].lower())
    ][:max_results]

    if not results:
        return "No tickets match the given filters."
    return "\n".join(
        f"[{t['id']}] {t['status']} | {t['priority']} | {t['summary']}"
        for t in results
    )


app = make_metadata_aware_app(
    jira_agent,
    name=_cfg.name,
    description=_cfg.description,
)


@app.on_event("startup")
async def _startup_banner() -> None:
    port = os.environ.get("JIRA_AGENT_PORT", "8002")
    _log.info("\n  Jira Agent ready:")
    _log.info("    A2A   → http://0.0.0.0:{}/", port)
    _log.info("    Chat  → http://0.0.0.0:{}/chat", port)
    _log.info("    Card  → http://0.0.0.0:{}/.well-known/agent-card.json", port)


_PROJECT_ROOT = Path(__file__).parents[3]
_jira_db_path = os.environ.get(
    "PYLOGUE_DB_PATH",
    str(_PROJECT_ROOT / "data" / "conversation-histories" / "jira" / "chat_history.db"),
)
Path(_jira_db_path).parent.mkdir(parents=True, exist_ok=True)


app.mount(
    "/chat",
    create_core_app(
        responder_factory=lambda: jira_agent,
        hero_title="Jira Agent",
        hero_subtitle="Search and retrieve Tata Steel Jira tickets.",
        db_path=_jira_db_path,
    ),
)


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(_cfg.module_path, host=_cfg.host, port=_cfg.port, reload=True)
