from krrkt.engine.splitter import split_text
from krrkt.engine.fast_layer import FastLayer
from krrkt.engine.deep_layer import DeepLayer
from krrkt.engine.dedup import merge_findings
from krrkt.engine.scorer import calculate_score, score_color, count_words
from krrkt.models import Finding, ProofreadResult
from collections import Counter


_fast_layer = None


def _get_fast_layer():
    global _fast_layer
    if _fast_layer is None:
        _fast_layer = FastLayer()
    return _fast_layer


def _get_provider(model: str | None = None):
    """Get the best available LLM provider.

    Tries Agent SDK first (uses Claude subscription), falls back to Anthropic API.
    """
    resolved_model = model or "claude-sonnet-4-6"

    try:
        from krrkt.providers.agent_sdk_provider import AgentSDKProvider
        return AgentSDKProvider(model=resolved_model)
    except ImportError:
        pass

    try:
        from krrkt.providers.anthropic_provider import AnthropicProvider
        return AnthropicProvider(model=resolved_model)
    except ImportError:
        pass

    raise RuntimeError(
        "No LLM provider available. Install claude-agent-sdk (for subscription) "
        "or set ANTHROPIC_API_KEY (for API)."
    )


def _build_summary(findings: list[dict]) -> dict:
    sections = [
        f.get("section") or f.get("rule", "")
        for f in findings
        if (f.get("section") or f.get("rule")) and f.get("weight", 0) > 0
    ]
    return dict(Counter(sections).most_common())


async def proofread(text: str, skip_llm: bool = False,
                    model: str | None = None) -> ProofreadResult:
    if not text or not text.strip():
        return ProofreadResult(
            score=0, score_color="red", text=text, words=0,
            sentences=0, findings=[], stopwords=0, summary={}
        )

    sentences = split_text(text)

    # Fast layer
    fast_findings = _get_fast_layer().analyze(text)

    # Deep layer (optional)
    deep_findings = []
    if not skip_llm:
        provider = _get_provider(model)
        deep = DeepLayer(provider=provider)
        deep_findings = await deep.analyze(text, already_found=fast_findings)

    # Merge and dedup
    all_findings_raw = merge_findings(fast_findings, deep_findings)

    # Convert to Finding objects
    findings = [Finding(**{k: v for k, v in f.items() if k in Finding.__dataclass_fields__}) for f in all_findings_raw]

    # Score
    score_val = calculate_score(text, [{"weight": f.weight, "penalty": 0} for f in findings])

    return ProofreadResult(
        score=score_val,
        score_color=score_color(score_val),
        text=text,
        words=count_words(text),
        sentences=len(sentences),
        findings=findings,
        stopwords=len([f for f in findings if f.weight > 0]),
        summary=_build_summary(all_findings_raw),
    )
