"""TicketParser — extract structured testing context from a Jira ticket.

Uses the configured LLM (via Agno Agent) to analyse the ticket's
summary + description and extract:
  - Affected areas / pages
  - Acceptance criteria
  - Suggested test scenarios
"""

from __future__ import annotations

import json
import logging
from typing import Any

from agno.agent import Agent
from pydantic import BaseModel, Field

from antiqa.config.models import resolve_model
from antiqa.config.schema import AntiQAConfig

log = logging.getLogger("antiqa.jira")


class ParsedTicket(BaseModel):
    """Structured information extracted from a Jira ticket."""
    key: str
    summary: str
    affected_areas: list[str] = Field(default_factory=list)
    acceptance_criteria: list[str] = Field(default_factory=list)
    suggested_scenarios: list[str] = Field(default_factory=list)
    test_urls: list[str] = Field(default_factory=list)
    priority: str = "Medium"


class TicketParser:
    """Extract structured test context from a Jira ticket using AI."""

    def __init__(self, config: AntiQAConfig) -> None:
        self.config = config
        self.model = resolve_model(config.llm)

    def parse(self, issue_data: dict[str, Any]) -> ParsedTicket:
        """Analyse an issue dict (from JiraAgent.get_issue) and return structured info."""
        key = issue_data.get("key", "UNKNOWN")
        summary = issue_data.get("summary", "")
        description = issue_data.get("description", "")

        if not description and not summary:
            log.warning("Ticket %s has no summary or description", key)
            return ParsedTicket(key=key, summary=summary)

        agent = Agent(
            model=self.model,
            instructions=[
                "You are a QA analyst. Given a Jira ticket, extract structured testing information.",
                "Return ONLY valid JSON — no markdown, no extra text.",
            ],
            markdown=False,
        )

        prompt = (
            f"Analyse this Jira ticket and extract QA-relevant information.\n\n"
            f"Ticket: {key}\n"
            f"Summary: {summary}\n"
            f"Description:\n{description}\n\n"
            f"Return a JSON object with these fields:\n"
            f'  "affected_areas": list of UI pages/features affected\n'
            f'  "acceptance_criteria": list of acceptance criteria found\n'
            f'  "suggested_scenarios": list of test scenarios to verify\n'
            f'  "test_urls": list of specific URL paths mentioned (e.g. /login, /dashboard)\n'
            f'  "priority": "Critical" | "High" | "Medium" | "Low"\n'
        )

        try:
            response = agent.run(prompt)
            content = response.content if response.content else ""

            # Strip markdown code fences if the LLM wraps its response
            content = content.strip()
            if content.startswith("```"):
                content = content.split("\n", 1)[1] if "\n" in content else content[3:]
            if content.endswith("```"):
                content = content[:-3]
            content = content.strip()

            parsed = json.loads(content)

            return ParsedTicket(
                key=key,
                summary=summary,
                affected_areas=parsed.get("affected_areas", []),
                acceptance_criteria=parsed.get("acceptance_criteria", []),
                suggested_scenarios=parsed.get("suggested_scenarios", []),
                test_urls=parsed.get("test_urls", []),
                priority=parsed.get("priority", "Medium"),
            )
        except (json.JSONDecodeError, Exception) as exc:
            log.warning("AI parsing failed for %s, returning minimal info: %s", key, exc)
            return ParsedTicket(key=key, summary=summary)
