"""Tests for app.api.v1.captcha — captcha generate and verify"""

import pytest
from unittest.mock import AsyncMock, patch, MagicMock


@pytest.mark.asyncio
async def test_generate_captcha():
    from app.api.v1.captcha import generate_captcha
    result = await generate_captcha()
    assert "id" in result
    assert "question" in result
    assert "expires_in" in result
    assert result["expires_in"] == 300
    assert "=" in result["question"]


@pytest.mark.asyncio
async def test_generate_captcha_stores_in_cache():
    from app.api.v1.captcha import generate_captcha
    with patch("app.api.v1.captcha.cache.set", AsyncMock(return_value=True)):
        result = await generate_captcha()
        assert result["id"] is not None


@pytest.mark.asyncio
async def test_generate_captcha_fallback_memory():
    """When Redis fails, falls back to _mem_store"""
    from app.api.v1.captcha import generate_captcha, _mem_store
    _mem_store.clear()
    with patch("app.api.v1.captcha.cache.set", AsyncMock(return_value=False)):
        result = await generate_captcha()
    # _mem_store should have entry
    assert len(_mem_store) > 0


@pytest.mark.asyncio
async def test_verify_captcha_valid():
    from app.api.v1.captcha import verify_captcha, _mem_store
    from app.api.v1.captcha import CAPTCHA_PREFIX
    _mem_store.clear()
    # Store a test captcha
    _mem_store[CAPTCHA_PREFIX + "test-id"] = {"answer": 42, "_expires": 9999999999}
    req = MagicMock()
    req.captcha_id = "test-id"
    req.captcha_answer = 42
    with patch("app.api.v1.captcha.cache.pop", AsyncMock(return_value=None)):
        result = await verify_captcha(req)
    assert result["status"] == "ok"
    assert "verify_token" in result


@pytest.mark.asyncio
async def test_verify_captcha_wrong_answer():
    from app.api.v1.captcha import verify_captcha
    from app.api.v1.captcha import CAPTCHA_PREFIX, _mem_store
    _mem_store.clear()
    _mem_store[CAPTCHA_PREFIX + "test-id"] = {"answer": 42, "_expires": 9999999999}
    req = MagicMock()
    req.captcha_id = "test-id"
    req.captcha_answer = 99  # wrong
    with patch("app.api.v1.captcha.cache.pop", AsyncMock(return_value=None)):
        with pytest.raises(Exception) as exc:
            await verify_captcha(req)
    assert exc.value.status_code == 400


@pytest.mark.asyncio
async def test_verify_captcha_expired():
    from app.api.v1.captcha import verify_captcha
    req = MagicMock()
    req.captcha_id = "expired-id"
    req.captcha_answer = 42
    with patch("app.api.v1.captcha.cache.pop", AsyncMock(return_value=None)):
        with patch("app.api.v1.captcha._mem_store", {"captcha:expired-id": {"_expires": 1}}):
            with pytest.raises(Exception) as exc:
                await verify_captcha(req)
    assert exc.value.status_code == 400
