"""Tests for dependency injection functions."""

import uuid
from unittest.mock import AsyncMock, MagicMock

import pytest
from fastapi import HTTPException

from mixlift.deps import check_free_tier_run_limit, require_tier
from mixlift.projects.models import User


async def test_check_free_tier_run_limit_under_limit():
    user = User(id=uuid.uuid4(), email="test@example.com", tier="free")
    mock_session = AsyncMock()
    mock_result = MagicMock()
    mock_result.scalar_one.return_value = 1
    mock_session.execute.return_value = mock_result

    result = await check_free_tier_run_limit(user=user, session=mock_session)

    assert result == user
    mock_session.execute.assert_called_once()


async def test_check_free_tier_run_limit_at_limit():
    user = User(id=uuid.uuid4(), email="test@example.com", tier="free")
    mock_session = AsyncMock()
    mock_result = MagicMock()
    mock_result.scalar_one.return_value = 2
    mock_session.execute.return_value = mock_result

    with pytest.raises(HTTPException) as exc_info:
        await check_free_tier_run_limit(user=user, session=mock_session)

    assert exc_info.value.status_code == 403
    assert "Free tier limit reached" in exc_info.value.detail


async def test_check_free_tier_run_limit_paid_user():
    user = User(id=uuid.uuid4(), email="test@example.com", tier="pro")
    mock_session = AsyncMock()

    result = await check_free_tier_run_limit(user=user, session=mock_session)

    assert result == user
    mock_session.execute.assert_not_called()


async def test_require_tier_sufficient():
    user = User(id=uuid.uuid4(), email="test@example.com", tier="pro")
    checker = require_tier("pro")

    result = await checker(user=user)

    assert result == user


async def test_require_tier_insufficient():
    user = User(id=uuid.uuid4(), email="test@example.com", tier="free")
    checker = require_tier("pro")

    with pytest.raises(HTTPException) as exc_info:
        await checker(user=user)

    assert exc_info.value.status_code == 403
