import base64

import pytest

from servala.core.models import (
    Organization,
    OrganizationMembership,
    OrganizationOrigin,
    User,
)
from servala.core.models.service import (
    CloudProvider,
    Service,
    ServiceCategory,
    ServiceOffering,
)


@pytest.fixture
def origin():
    return OrganizationOrigin.objects.create(name="TESTORIGIN")


@pytest.fixture
def organization(origin):
    return Organization.objects.create(name="Test Org", origin=origin)


@pytest.fixture
def other_organization(origin):
    return Organization.objects.create(name="Test Org Alternate", origin=origin)


@pytest.fixture
def org_owner(organization):
    user = User.objects.create(email="user@example.org", password="example")
    OrganizationMembership.objects.create(
        organization=organization, user=user, role="owner"
    )
    return user


@pytest.fixture
def test_service_category():
    return ServiceCategory.objects.create(
        name="Databases",
        description="Database services",
    )


@pytest.fixture
def test_service(test_service_category):
    return Service.objects.create(
        name="Redis",
        slug="redis",
        category=test_service_category,
        description="Redis database service",
        osb_service_id="test-service-123",
    )


@pytest.fixture
def test_cloud_provider():
    return CloudProvider.objects.create(
        name="Exoscale",
        description="Exoscale cloud provider",
    )


@pytest.fixture
def test_service_offering(test_service, test_cloud_provider):
    return ServiceOffering.objects.create(
        service=test_service,
        provider=test_cloud_provider,
        description="Redis on Exoscale",
        osb_plan_id="test-plan-123",
    )


@pytest.fixture
def osb_client(client):
    credentials = base64.b64encode(b"testuser:testpass").decode("ascii")
    client.defaults = {"HTTP_AUTHORIZATION": f"Basic {credentials}"}
    return client


@pytest.fixture
def mock_odoo_success(mocker):
    """
    Mock Odoo client with successful responses for organization creation.
    Returns the mock object for further customization if needed.
    """
    mock_client = mocker.patch("servala.core.models.organization.CLIENT")

    # Default successful responses for organization creation
    mock_client.execute.side_effect = [
        123,  # company_id
        456,  # invoice_address_id
        789,  # sale_order_id
    ]
    mock_client.search_read.return_value = [{"name": "SO001"}]

    return mock_client


@pytest.fixture
def mock_odoo_failure(mocker):
    """
    Mock Odoo client that raises an exception to simulate failure.
    """
    mock_client = mocker.patch("servala.core.models.organization.CLIENT")
    mock_client.execute.side_effect = Exception("Odoo connection failed")
    return mock_client
