"""VisualReviewerAgent — AI-powered screenshot analysis for visual bugs.

Uses vision-capable models (GPT-4o, Gemini) to inspect screenshots and
detect layout issues, broken UI, missing images, and design inconsistencies.
"""

from __future__ import annotations

import base64
import json
import logging
from pathlib import Path
from typing import Any

from pydantic import BaseModel, Field

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

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

_PROMPT_PATH = Path(__file__).parent / "prompts" / "visual_review.md"


class VisualIssue(BaseModel):
    severity: str = "warning"
    category: str = "visual_bug"
    description: str = ""
    location: str = ""


class VisualReviewResult(BaseModel):
    page_url: str = ""
    page_assessment: str = "good"
    issues: list[VisualIssue] = Field(default_factory=list)
    summary: str = ""
    screenshot_path: str = ""


class VisualReviewerAgent:
    """Analyse screenshots for visual / UI issues using a vision model."""

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

    def review_screenshot(
        self,
        screenshot_path: str | Path,
        page_url: str = "",
    ) -> VisualReviewResult:
        """Analyse a single screenshot and return visual issues found."""
        screenshot_path = Path(screenshot_path)
        if not screenshot_path.exists():
            log.warning("Screenshot not found: %s", screenshot_path)
            return VisualReviewResult(
                page_url=page_url,
                screenshot_path=str(screenshot_path),
                summary="Screenshot file not found",
            )

        image_b64 = base64.b64encode(screenshot_path.read_bytes()).decode()

        from agno.agent import Agent
        from agno.media import Image as AgnoImage
        from agno.utils.log import logger as agno_logger

        prev_handlers = agno_logger.handlers[:]
        prev_propagate = agno_logger.propagate
        agno_logger.handlers = [logging.NullHandler()]
        agno_logger.propagate = False
        try:
            agent = Agent(
                model=self.model,
                instructions=[self._system_prompt],
                markdown=False,
            )
            images = [AgnoImage(filepath=str(screenshot_path))]
            user_prompt = f"Review this screenshot of {page_url or 'a web page'}. Identify any visual issues."
            response = agent.run(user_prompt, images=images)
            content = _clean_response(response.content or "{}")
            data = json.loads(content)
        except Exception as exc:
            log.warning("Visual review failed for %s: %s", screenshot_path, exc)
            return VisualReviewResult(
                page_url=page_url,
                screenshot_path=str(screenshot_path),
                summary=f"Review failed: {exc}",
            )
        finally:
            agno_logger.handlers = prev_handlers
            agno_logger.propagate = prev_propagate

        issues = [
            VisualIssue(
                severity=i.get("severity", "warning"),
                category=i.get("category", "visual_bug"),
                description=i.get("description", ""),
                location=i.get("location", ""),
            )
            for i in data.get("issues", [])
        ]

        return VisualReviewResult(
            page_url=page_url,
            page_assessment=data.get("page_assessment", "good"),
            issues=issues,
            summary=data.get("summary", ""),
            screenshot_path=str(screenshot_path),
        )

    def review_many(
        self, screenshots: list[tuple[str | Path, str]]
    ) -> list[VisualReviewResult]:
        """Review multiple screenshots. Each tuple is (path, page_url)."""
        results: list[VisualReviewResult] = []
        for path, url in screenshots:
            result = self.review_screenshot(path, url)
            results.append(result)
            log.info(
                "Visual review %s: %s (%d issues)",
                url, result.page_assessment, len(result.issues),
            )
        return results


def _clean_response(content: str) -> str:
    content = content.strip()
    if content.startswith("```"):
        first_newline = content.index("\n") if "\n" in content else 3
        content = content[first_newline + 1:]
    if content.endswith("```"):
        content = content[:-3]
    return content.strip()
