"""Tests for service registration and management."""

import pytest
from datetime import datetime
from httpx import Response
from pytest_httpx import HTTPXMock

from vikdata import VikdataClient
from vikdata.models import Service, ServiceRegistration, ServiceHealth
from vikdata.exceptions import ServiceRegistrationError


@pytest.mark.asyncio
async def test_register_service(httpx_mock: HTTPXMock, mock_service_registration):
    """Test service registration."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/register",
        method="POST",
        json=mock_service_registration,
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        registration = await client.services.register(
            name="test-service",
            service_url="https://test-service.example.com",
            health_endpoint="/health",
            description="Test service",
            permissions=["test:read", "test:write"],
        )

        assert isinstance(registration, ServiceRegistration)
        assert registration.id == "service-123"
        assert registration.name == "test-service"
        assert registration.api_key == "test-api-key-456"
        assert registration.status == "active"


@pytest.mark.asyncio
async def test_register_service_without_health_endpoint(httpx_mock: HTTPXMock, mock_service_registration):
    """Test service registration without health endpoint."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/register",
        method="POST",
        json=mock_service_registration,
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        registration = await client.services.register(
            name="test-service",
            service_url="https://test-service.example.com",
        )

        assert isinstance(registration, ServiceRegistration)
        assert registration.id == "service-123"


@pytest.mark.asyncio
async def test_register_service_failure(httpx_mock: HTTPXMock):
    """Test service registration failure."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/register",
        method="POST",
        status_code=400,
        json={"message": "Invalid service configuration"},
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        with pytest.raises(ServiceRegistrationError):
            await client.services.register(
                name="test-service",
                service_url="https://test-service.example.com",
            )


@pytest.mark.asyncio
async def test_unregister_service(httpx_mock: HTTPXMock):
    """Test service unregistration."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/service-123",
        method="DELETE",
        status_code=204,
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        await client.services.unregister("service-123")
        # Should not raise an exception


@pytest.mark.asyncio
async def test_list_services(httpx_mock: HTTPXMock, mock_service):
    """Test listing services."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services",
        method="GET",
        json={"data": [mock_service]},
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        services = await client.services.list()

        assert len(services) == 1
        assert isinstance(services[0], Service)
        assert services[0].id == "service-123"
        assert services[0].name == "test-service"


@pytest.mark.asyncio
async def test_get_service(httpx_mock: HTTPXMock, mock_service):
    """Test getting a specific service."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/service-123",
        method="GET",
        json=mock_service,
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        service = await client.services.get("service-123")

        assert isinstance(service, Service)
        assert service.id == "service-123"
        assert service.name == "test-service"
        assert service.base_url == "https://test-service.example.com"


@pytest.mark.asyncio
async def test_health_status_single_service(httpx_mock: HTTPXMock, mock_health_status):
    """Test getting health status for a specific service."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/service-123/health",
        method="GET",
        json=mock_health_status,
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        health = await client.services.health_status("service-123")

        assert isinstance(health, ServiceHealth)
        assert health.service_id == "service-123"
        assert health.status == "healthy"
        assert "database" in health.checks
        assert "redis" in health.checks


@pytest.mark.asyncio
async def test_health_status_all_services(httpx_mock: HTTPXMock, mock_health_status):
    """Test getting health status for all services."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/health",
        method="GET",
        json={"data": [mock_health_status]},
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        health_list = await client.services.health_status()

        assert isinstance(health_list, list)
        assert len(health_list) == 1
        assert isinstance(health_list[0], ServiceHealth)
        assert health_list[0].status == "healthy"


@pytest.mark.asyncio
async def test_report_health(httpx_mock: HTTPXMock):
    """Test reporting health status."""
    httpx_mock.add_response(
        url="http://localhost:8000/api/v1/services/service-123/health",
        method="POST",
        status_code=204,
    )

    async with VikdataClient(base_url="http://localhost:8000", api_key="test-key") as client:
        await client.services.report_health(
            service_id="service-123",
            status="healthy",
            checks={"database": {"healthy": True}},
            details={"uptime": "24h"},
        )
        # Should not raise an exception
