"""Проверка расхода и подсказки скиллов (R01, R09).

Рычаги порчи:
1. Игнорировать --tokens в `task set` — покраснеет `test_task_set_tokens_updates_spend`.
2. Потерять --model в `task done` — покраснеет `test_task_done_model_updates_spend_model`.
3. Требовать совпадение в имени скилла — покраснеет `test_russian_task_gets_skills_by_description`.
"""

from __future__ import annotations

import os
import subprocess
import sys
from pathlib import Path

import pytest

ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))

from chekan import proof, skills  # noqa: E402
from chekan.__main__ import main  # noqa: E402
from chekan.store import Run  # noqa: E402


@pytest.fixture
def repo(tmp_path: Path) -> Path:
    subprocess.run(["git", "init", "-q"], cwd=tmp_path, check=True)
    subprocess.run(["git", "config", "user.email", "t@t"], cwd=tmp_path, check=True)
    subprocess.run(["git", "config", "user.name", "t"], cwd=tmp_path, check=True)
    (tmp_path / "app.py").write_text("print('ok')\n", encoding="utf-8")
    subprocess.run(["git", "add", "-A"], cwd=tmp_path, check=True)
    subprocess.run(["git", "commit", "-qm", "init"], cwd=tmp_path, check=True)
    r = Run.create(tmp_path, "Тестовый прогон", "normal", "T1")
    r.add_requirement("R01", "цитата", "причина")
    r.add_task("01", "Первая задача", ["R01"], zone="app.py", verify="true")
    r.add_task("02", "Вторая задача", ["R01"], zone="app.py", verify="true")
    return tmp_path


def _cli(repo: Path, *args: str) -> int:
    cwd = Path.cwd()
    try:
        os.chdir(repo)
        return main(list(args))
    finally:
        os.chdir(cwd)


def test_task_set_tokens_updates_spend(repo: Path, capsys):
    """`chekan task set --tokens N` не теряет расход и обновляет spend.tokens."""
    code = _cli(repo, "task", "set", "01", "--tokens", "1500")
    printed = capsys.readouterr().out
    assert code == 0
    assert "tokens" in printed
    run = Run.load(repo)
    t = run.task("01")
    assert t is not None
    spend = t.get("spend")
    assert isinstance(spend, dict)
    assert spend["tokens"] == 1500
    assert spend["tokens_source"] == "со слов исполнителя"


def test_task_set_negative_tokens_fails(repo: Path, capsys):
    code = _cli(repo, "task", "set", "01", "--tokens", "-50")
    assert code == 1
    err = capsys.readouterr().err
    assert "отрицательным" in err


def test_task_done_model_updates_spend_model(repo: Path, capsys):
    """`chekan task done --model` передаёт модель в расход."""
    run = Run.load(repo)
    proof.run_command(run, "true", task="02")
    code = _cli(repo, "task", "done", "02", "--model", "claude-opus-5", "--tokens", "3200")
    printed = capsys.readouterr().out
    assert code == 0
    assert "claude-opus-5" in printed
    assert "модель не названа" not in printed
    assert "3200" in printed

    run = Run.load(repo)
    t = run.task("02")
    assert t is not None
    assert t["model"] == "claude-opus-5"
    assert t["spend"]["model"] == "claude-opus-5"
    assert t["spend"]["tokens"] == 3200


def test_russian_task_gets_skills_by_description():
    """Русские названия задач находят скиллы по описанию без совпадения в slug."""
    task = {"title": "Проверить Telegram-бота после доработки хендлеров", "zone": "bot.py"}
    suggested = [s.name for s in skills.suggest(task)]
    assert any("tg" in name or "bot" in name for name in suggested)
    assert len(suggested) <= 3


def test_unrelated_task_gets_no_skills():
    """Случайные советы отсутствуют: тишина при отсутствии совпадений."""
    task = {"title": "Рефакторинг внутреннего хранилища", "zone": "chekan/store.py"}
    assert skills.suggest(task) == []
