"""Pytest fixtures for Platform-2Step MCP tests."""

from datetime import datetime, timedelta

import pytest
import respx
from httpx import Response

from platform_2step_mcp.auth import AuthClient, TokenData
from platform_2step_mcp.client import Platform2StepClient


# =============================================================================
# Base URL and Token Fixtures
# =============================================================================


@pytest.fixture
def base_url() -> str:
    """Base URL for testing."""
    return "https://platform-2step.test.agendapro.com"


@pytest.fixture
def bff_url() -> str:
    """BFF URL for testing."""
    return "https://plt-2steps-bff.test.agendapro.com"


# =============================================================================
# Auth Fixtures
# =============================================================================


@pytest.fixture
def temp_token_storage(tmp_path) -> str:
    """Temporary token storage path."""
    return str(tmp_path / "tokens.json")


@pytest.fixture
def sample_token_data() -> TokenData:
    """Sample token data for testing (Cognito-style with id_token)."""
    return TokenData(
        access_token="test-access-token",
        refresh_token="test-refresh-token",
        expires_at=datetime.utcnow() + timedelta(hours=1),
        id_token="test-id-token",
    )


@pytest.fixture
def expired_token_data() -> TokenData:
    """Expired token data for testing."""
    return TokenData(
        access_token="expired-access-token",
        refresh_token="test-refresh-token",
        expires_at=datetime.utcnow() - timedelta(hours=1),
        id_token="expired-id-token",
    )


@pytest.fixture
def completion_code_callback():
    """Mock completion code callback for testing."""
    return lambda: "COMPLETE-test-completion-code"


@pytest.fixture
def auth_client(bff_url: str, temp_token_storage: str) -> AuthClient:
    """Create an AuthClient for testing."""
    return AuthClient(
        bff_url=bff_url,
        token_storage_path=temp_token_storage,
    )


@pytest.fixture
def auth_client_with_callback(
    bff_url: str, temp_token_storage: str, completion_code_callback
) -> AuthClient:
    """Create an AuthClient with completion code callback for testing."""
    return AuthClient(
        bff_url=bff_url,
        token_storage_path=temp_token_storage,
        completion_code_callback=completion_code_callback,
    )


@pytest.fixture
def auth_client_with_valid_tokens(
    bff_url: str, temp_token_storage: str, sample_token_data: TokenData
) -> AuthClient:
    """Create an AuthClient with pre-loaded valid tokens for testing."""
    client = AuthClient(
        bff_url=bff_url,
        token_storage_path=temp_token_storage,
    )
    # Pre-load tokens
    client.storage.save(sample_token_data)
    return client


@pytest.fixture
def device_auth_response() -> dict:
    """Sample device auth response from BFF."""
    return {
        "device_code": "test-device-code-12345",
        "user_code": "ABCD-1234",
        "verification_uri": "https://auth.agendapro.com/device",
        "verification_uri_complete": "https://auth.agendapro.com/device?user_code=ABCD-1234",
        "expires_in": 1800,
        "interval": 5,
    }


@pytest.fixture
def token_response() -> dict:
    """Sample token response from BFF (Cognito-style with id_token, no scope)."""
    return {
        "access_token": "new-access-token",
        "id_token": "new-id-token",
        "refresh_token": "new-refresh-token",
        "token_type": "Bearer",
        "expires_in": 3600,
    }


# =============================================================================
# Client Fixtures
# =============================================================================


@pytest.fixture
def client(base_url: str, auth_client_with_valid_tokens: AuthClient) -> Platform2StepClient:
    """Create a test client with auth_client."""
    return Platform2StepClient(base_url=base_url, auth_client=auth_client_with_valid_tokens)


@pytest.fixture
def mock_api(base_url: str):
    """Create a respx mock for the API."""
    with respx.mock(base_url=base_url, assert_all_called=False) as mock:
        yield mock


@pytest.fixture
def mock_bff(bff_url: str):
    """Create a respx mock for the BFF."""
    with respx.mock(base_url=bff_url, assert_all_called=False) as mock:
        yield mock


# =============================================================================
# Sample Response Data
# =============================================================================


@pytest.fixture
def sample_category() -> dict:
    """Sample category data."""
    return {
        "id": 123,
        "name": "Cortes de Pelo",
        "company_id": 1238,
        "order": 1,
        "services_count": 5,
    }


@pytest.fixture
def sample_categories_response(sample_category: dict) -> dict:
    """Sample list categories response."""
    return {
        "data": [sample_category],
        "meta": {
            "current_page": 1,
            "per_page": 25,
            "total_pages": 1,
            "total_count": 1,
        },
    }


@pytest.fixture
def sample_pending_operation() -> dict:
    """Sample pending operation response."""
    return {
        "confirmation_id": "abc-123-def-456",
        "operation": "create",
        "resource": "category",
        "resource_id": None,
        "preview": {"name": "Nueva Categoria", "company_id": 1238},
        "expires_at": "2024-01-15T10:05:00Z",
        "confirm_url": "/api/v1/confirmations/abc-123-def-456",
    }


@pytest.fixture
def sample_batch_response() -> dict:
    """Sample batch response."""
    return {
        "batch_id": "batch-123-456",
        "status": "pending",
        "description": "Import categories",
        "operations_count": 3,
        "executed_count": 0,
        "failed_count": 0,
        "expires_at": "2024-01-15T10:30:00Z",
        "confirmable": True,
        "confirm_url": "/api/v1/batches/batch-123-456/confirm",
        "operations": [
            {
                "position": 1,
                "confirmation_id": "op-1",
                "operation": "create",
                "resource": "category",
                "status": "pending",
            },
            {
                "position": 2,
                "confirmation_id": "op-2",
                "operation": "create",
                "resource": "category",
                "status": "pending",
            },
            {
                "position": 3,
                "confirmation_id": "op-3",
                "operation": "create",
                "resource": "category",
                "status": "pending",
            },
        ],
    }


@pytest.fixture
def sample_service() -> dict:
    """Sample service data."""
    return {
        "id": 456,
        "name": "Corte de Pelo",
        "service_category_id": 123,
        "duration": 30,
        "price": 15000,
        "active": True,
        "description": "Corte profesional",
    }


@pytest.fixture
def sample_booking() -> dict:
    """Sample booking data."""
    return {
        "id": 789,
        "service_id": 456,
        "provider_id": 10,
        "client_id": 20,
        "start": "2024-01-15T10:00:00Z",
        "end": "2024-01-15T10:30:00Z",
        "status": "confirmed",
        "notes": "Cliente regular",
    }
