"""Intent Atomizer — decompose NL into atoms before plan template selection (Phase A)."""

from __future__ import annotations

import re
from dataclasses import dataclass, field
from typing import Any

from iuve_connect_agents.desktop.active.compound_intent_resolver import (
    is_compound_site_local_intent,
    is_local_file_artifact_intent,
    is_site_visual_research_intent,
    user_explicit_desktop_intent,
)
from iuve_connect_agents.desktop.active.website_resolver import extract_url_from_prompt, prompt_specifies_site
from iuve_connect_agents.desktop.ui.avatar_intent_router import wants_screen_verification

_DOMAIN_RE = re.compile(
    r"\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}\b"
)
_STUDY_TOKENS = ("изуч", "исслед", "research", "read", "прочит", "содержим", "content", "узнай", "learn about")

_FOLDER_CREATE_RE = re.compile(
    r"\b(?:создай|создать|create|make)\s+папк",
    re.IGNORECASE,
)
_DOCUMENT_CREATE_RE = re.compile(
    r"\b(?:"
    r"новый\s+документ|новом\s+документе|"
    r"create\s+(?:a\s+)?(?:new\s+)?document|"
    r"в\s+документ|в\s+новом\s+документе|"
    r"открой\s+документ|open\s+document"
    r")\b",
    re.IGNORECASE,
)
_WEB_POST_RE = re.compile(
    r"\b(?:опублик|publish|черновик\s+на\s+сайт|post\s+on|пост\s+на\s+сайт)\b",
    re.IGNORECASE,
)
_EXPLICIT_PUBLISH_RE = re.compile(
    r"\b(?:опублик|publish|черновик\s+на\s+сайт|post\s+on)\b",
    re.IGNORECASE,
)


@dataclass(frozen=True)
class IntentAtom:
    kind: str
    target: str = ""
    qualifiers: dict[str, Any] = field(default_factory=dict)


@dataclass(frozen=True)
class AtomizedIntent:
    atoms: tuple[IntentAtom, ...]
    explicit_desktop: bool = False
    has_site: bool = False
    forbid_web_post: bool = False
    requires_compound_plan: bool = False


def _has_site(text: str) -> bool:
    return (
        bool(extract_url_from_prompt(text))
        or prompt_specifies_site(text)
        or bool(_DOMAIN_RE.search(str(text or "")))
        or any(token in str(text or "").lower() for token in ("сайт", "site", "url", "браузер", "browser"))
    )


def atomize_intent(text: str) -> AtomizedIntent:
    """Split user text into minimal intent atoms for routing."""
    raw = str(text or "").strip()
    atoms: list[IntentAtom] = []
    if not raw:
        return AtomizedIntent(atoms=())

    lower = raw.lower()
    explicit_desktop = user_explicit_desktop_intent(raw)
    has_site = _has_site(raw)
    has_study = any(token in lower for token in _STUDY_TOKENS)

    if has_site:
        url = extract_url_from_prompt(raw) or ""
        atoms.append(IntentAtom("browser.open", target=url))
        if has_study:
            atoms.append(IntentAtom("browser.describe", target=url))

    if is_site_visual_research_intent(raw):
        atoms.append(IntentAtom("browser.describe", target=url if has_site else ""))

    if _FOLDER_CREATE_RE.search(raw) or ("папк" in lower and explicit_desktop):
        atoms.append(
            IntentAtom(
                "fs.mkdir",
                qualifiers={"explicit_desktop": explicit_desktop},
            )
        )

    if _DOCUMENT_CREATE_RE.search(raw) or ("новый документ" in lower):
        atoms.append(IntentAtom("document.create"))

    if wants_screen_verification(raw):
        atoms.append(IntentAtom("screenshot.capture", qualifiers={"present_to_chat": True}))

    # Web post only when explicit publish on site — not for local document goals
    local_doc = is_local_file_artifact_intent(raw) or bool(_DOCUMENT_CREATE_RE.search(raw))
    if has_site and not local_doc and _WEB_POST_RE.search(raw):
        atoms.append(IntentAtom("web.post", target=extract_url_from_prompt(raw) or ""))

    forbid_web_post = local_doc or (
        is_compound_site_local_intent(raw) and not _EXPLICIT_PUBLISH_RE.search(raw)
    )
    browser_kinds = {a.kind for a in atoms}
    has_study = any(token in lower for token in _STUDY_TOKENS)
    requires_compound = (
        is_compound_site_local_intent(raw)
        or ("browser.open" in browser_kinds and "fs.mkdir" in browser_kinds)
        or ("browser.open" in browser_kinds and "document.create" in browser_kinds)
        or ("browser.describe" in browser_kinds and "document.create" in browser_kinds)
        or (has_site and has_study and "document.create" in browser_kinds)
        or (has_site and has_study and "документ" in lower)
    )

    return AtomizedIntent(
        atoms=tuple(atoms),
        explicit_desktop=explicit_desktop,
        has_site=has_site,
        forbid_web_post=forbid_web_post,
        requires_compound_plan=requires_compound,
    )
