"""Public template showcase contract tests."""
from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock

import pytest

from src.domain.templates.service import TemplateService
from src.domain.templates.schemas import TemplateUpdate
from src.domain.templates.repository import TemplateRepository
from uuid import uuid4


@pytest.mark.asyncio
async def test_list_showcased_returns_only_marketing_safe_fields():
    template = SimpleNamespace(
        name="Portfolio",
        ref="portfolio",
        description="A polished portfolio starter.",
        thumbnail_url="https://cdn.example/portfolio.png",
        tags=["portfolio", "react"],
        framework="react_app",
        demo_url="https://portfolio.example",
        github_repo="private-org/portfolio",
        starter_sha="not-public",
    )
    repo = MagicMock()
    repo.list_showcased = AsyncMock(return_value=[template])

    items = await TemplateService(repo).list_showcased()

    assert items[0].model_dump() == {
        "name": "Portfolio",
        "ref": "portfolio",
        "description": "A polished portfolio starter.",
        "thumbnail_url": "https://cdn.example/portfolio.png",
        "tags": ["portfolio", "react"],
        "framework": "react_app",
        "demo_url": "https://portfolio.example",
    }
    repo.list_showcased.assert_awaited_once()


@pytest.mark.asyncio
async def test_get_showcased_by_ref_returns_none_when_not_public():
    repo = MagicMock()
    repo.get_showcased_by_ref = AsyncMock(return_value=None)

    item = await TemplateService(repo).get_showcased_by_ref("draft-template")

    assert item is None
    repo.get_showcased_by_ref.assert_awaited_once_with("draft-template")


@pytest.mark.asyncio
async def test_update_can_clear_showcase_rank_when_explicitly_requested():
    repo = MagicMock()
    repo.update = AsyncMock(return_value=None)

    await TemplateService(repo).update(uuid4(), TemplateUpdate(showcase_rank=None))

    assert repo.update.await_args.kwargs["clear_showcase_rank"] is True


@pytest.mark.asyncio
async def test_repository_update_refreshes_server_managed_fields_before_returning():
    db = MagicMock()
    db.flush = AsyncMock()
    db.refresh = AsyncMock()
    repo = TemplateRepository(db)
    template = SimpleNamespace(is_showcased=False)
    repo.get_by_id = AsyncMock(return_value=template)

    updated = await repo.update(uuid4(), is_showcased=True)

    assert updated is template
    assert template.is_showcased is True
    db.refresh.assert_awaited_once_with(template)
