"""Plan quota: max_projects and exempt workspaces."""
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4

import pytest

from src.core.exceptions import PlanLimitError
from src.domain.billing.plan_quota_service import PlanQuotaService
from src.domain.projects.service import ProjectService


@pytest.mark.asyncio
async def test_max_projects_free_defaults_when_no_plan_row():
    ws_id = uuid4()
    ws_repo = AsyncMock()
    ws_repo.get_by_id = AsyncMock(return_value=MagicMock(selected_plan_slug="free", skip_plan_quota_limits=False))
    sub_repo = AsyncMock()
    sub_repo.get_by_workspace = AsyncMock(return_value=None)
    plan_repo = AsyncMock()
    plan_repo.get_by_slug = AsyncMock(return_value=None)

    svc = PlanQuotaService(ws_repo, sub_repo, plan_repo)
    assert await svc.max_projects(ws_id) == 1


@pytest.mark.asyncio
async def test_workspace_skips_plan_quotas_when_flag_set():
    ws_id = uuid4()
    ws_repo = AsyncMock()
    ws_repo.get_by_id = AsyncMock(return_value=MagicMock(skip_plan_quota_limits=True))
    svc = PlanQuotaService(ws_repo, AsyncMock(), AsyncMock())
    assert await svc.workspace_skips_plan_quotas(ws_id) is True
    assert await svc.max_projects(ws_id) is None


@pytest.mark.asyncio
async def test_create_project_raises_when_at_max():
    ws_id = uuid4()
    facade = AsyncMock()
    facade.check_permission = AsyncMock(return_value=True)

    existing = [MagicMock()]

    project_repo = AsyncMock()
    project_repo.list_for_workspace = AsyncMock(return_value=existing)
    project_repo.slug_exists_in_workspace = AsyncMock(return_value=False)
    project_repo.acquire_workspace_advisory_xact_lock = AsyncMock()

    plan_quota = AsyncMock()
    plan_quota.max_projects = AsyncMock(return_value=1)

    job_outbox = AsyncMock()

    service = ProjectService(
        project_repo=project_repo,
        project_repo_repo=AsyncMock(),
        settings_repo=AsyncMock(),
        env_var_repo=AsyncMock(),
        workspace_facade=facade,
        plan_quota=plan_quota,
        job_outbox_repo=job_outbox,
    )

    with pytest.raises(PlanLimitError) as exc:
        await service.create_project(
            workspace_id=ws_id,
            name="Second",
            project_type="html",
            description=None,
            user_id=uuid4(),
        )
    assert exc.value.limit_code == "max_projects"
    assert exc.value.max_allowed == 1
