from __future__ import annotations

from app.modules.rag.webhook_service import RepoWebhookService


class FakeStoryWriter:
    def __init__(self) -> None:
        self.calls: list[dict] = []

    def record_story_commit(self, **kwargs) -> None:
        self.calls.append(kwargs)


class FakeCacheWriter:
    def __init__(self) -> None:
        self.calls: list[dict] = []

    def record_repo_cache(self, **kwargs) -> None:
        self.calls.append(kwargs)


def test_gitea_webhook_binds_story() -> None:
    writer = FakeStoryWriter()
    cache = FakeCacheWriter()
    service = RepoWebhookService(writer, cache)

    result = service.process(
        provider="gitea",
        payload={
            "repository": {"full_name": "acme/proj"},
            "ref": "refs/heads/feature/AAAA-1234",
            "pusher": {"username": "alice"},
            "commits": [
                {
                    "id": "abc123",
                    "message": "FEAT-1 update docs",
                    "added": ["docs/new.md"],
                    "modified": ["docs/api.md"],
                    "removed": [],
                }
            ],
        },
    )

    assert result["accepted"] is True
    assert result["story_bound"] is True
    assert result["story_id"] == "FEAT-1"
    assert result["cache_recorded"] is True
    assert len(writer.calls) == 1
    assert len(cache.calls) == 1
    assert writer.calls[0]["project_id"] == "acme/proj"


def test_webhook_without_story_id_is_non_fatal() -> None:
    writer = FakeStoryWriter()
    cache = FakeCacheWriter()
    service = RepoWebhookService(writer, cache)

    result = service.process(
        provider="bitbucket",
        payload={
            "repository": {"full_name": "acme/proj"},
            "push": {
                "changes": [
                    {
                        "new": {
                            "name": "feature/no-story",
                            "target": {"hash": "abc123", "message": "update docs"},
                        }
                    }
                ]
            },
        },
    )

    assert result["accepted"] is True
    assert result["story_bound"] is False
    assert result["cache_recorded"] is True
    assert len(cache.calls) == 1
    assert writer.calls == []


def test_provider_autodetect_by_headers() -> None:
    writer = FakeStoryWriter()
    service = RepoWebhookService(writer)

    result = service.process(
        headers={"X-Gitea-Event": "push"},
        payload={
            "repository": {"full_name": "acme/proj"},
            "ref": "refs/heads/feature/AAAA-1234",
            "commits": [{"id": "abc123", "message": "AAAA-1234 update"}],
        },
    )

    assert result["accepted"] is True
    assert result["story_bound"] is True
    assert result["story_id"] == "AAAA-1234"
