"""LLM provider using Claude Agent SDK (works via Claude subscription, no API key needed)."""

import json
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
from krrkt.providers.base import LLMProvider


class AgentSDKProvider(LLMProvider):
    """Uses Claude Agent SDK to analyze text via Claude Code subscription."""

    def __init__(self, model: str = "claude-sonnet-4-6"):
        self.model = model

    async def analyze(self, text: str, system_prompt: str,
                      already_found: list[dict]) -> list[dict]:
        already_desc = ""
        if already_found:
            items = [f'- "{f.get("word", "")}" ({f.get("rule", "")})' for f in already_found]
            already_desc = "\n\nУже найденные проблемы (НЕ дублируй их):\n" + "\n".join(items)

        user_prompt = (
            f"{system_prompt}\n\n---\n\n"
            f"Проанализируй текст и верни ТОЛЬКО JSON в формате "
            f'{{"findings": [{{...}}]}}:\n\n'
            f"{text}{already_desc}"
        )

        result_text = ""
        async for message in query(
            prompt=user_prompt,
            options=ClaudeAgentOptions(
                model=self.model,
                max_turns=1,
            ),
        ):
            if isinstance(message, ResultMessage):
                result_text = message.result

        if not result_text:
            return []

        # Parse JSON from result — may be wrapped in markdown or have text before it
        data = None
        try:
            # Try 1: direct JSON parse
            data = json.loads(result_text.strip())
        except json.JSONDecodeError:
            pass

        if data is None:
            # Try 2: extract from markdown code fence
            import re
            fence_match = re.search(r'```(?:json)?\s*\n(.*?)\n```', result_text, re.DOTALL)
            if fence_match:
                try:
                    data = json.loads(fence_match.group(1))
                except json.JSONDecodeError:
                    pass

        if data is None:
            # Try 3: find first { ... } block
            import re
            brace_match = re.search(r'\{.*"findings".*\}', result_text, re.DOTALL)
            if brace_match:
                try:
                    data = json.loads(brace_match.group(0))
                except json.JSONDecodeError:
                    pass

        if data is None:
            return []

        findings = data.get("findings", [])

        # Normalize and validate
        valid_styles = {"red", "blue", "orange"}
        valid_tabs = {"red", "blue"}

        for f in findings:
            f["source"] = "deep"
            f.setdefault("section", "")
            f.setdefault("description", "")
            # Normalize style/tab to valid values
            if f.get("style") not in valid_styles:
                f["style"] = "orange"
            if f.get("tab") not in valid_tabs:
                f["tab"] = "red"

        return findings
