import pytest
from unittest.mock import MagicMock, patch
import os
import sys

# Resolve paths
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))

from superoffice_client import SuperOfficeClient

@pytest.fixture
def mock_client():
    # We mock the client to avoid real API calls during test
    # Mocking environment variables to prevent initialization errors
    env_vars = {
        "SO_CLIENT_ID": "mock_id",
        "SO_CLIENT_SECRET": "mock_secret",
        "SO_REFRESH_TOKEN": "mock_token",
        "SO_ENVIRONMENT": "online",
        "SO_CONTEXT_IDENTIFIER": "Cust12345"
    }
    with patch.dict(os.environ, env_vars):
        with patch("superoffice_client.SuperOfficeClient._refresh_access_token", return_value="fake_token"):
            client = SuperOfficeClient()
            # Mocking the base methods so we don't hit the network
            client._get = MagicMock()
            client._post = MagicMock()
            client._patch = MagicMock()
            client._put = MagicMock()
            client.search = MagicMock()
            return client

def test_demo_workflow_logic(mock_client):
    """
    Verifies the integration workflow logic using production IDs.
    Targets Contact ID 171132 and Person ID 193036.
    """
    target_contact_id = 171132
    target_person_id = 193036
    
    # 1. Search for demo company (simulate not found)
    mock_client.search.return_value = []
    contact = mock_client.find_contact_by_criteria(name="Gemini Test Company")
    assert contact is None
    
    # 2. Create demo company
    mock_client._post.return_value = {"ContactId": target_contact_id, "Name": "Gemini Test Company"}
    new_contact = mock_client.create_contact(name="Gemini Test Company", url="https://test.com")
    assert new_contact["ContactId"] == target_contact_id
    
    # 3. Create Person
    mock_client._post.return_value = {"PersonId": target_person_id, "Firstname": "Max"}
    new_person = mock_client.create_person(first_name="Max", last_name="Mustermann", contact_id=target_contact_id)
    assert new_person["PersonId"] == target_person_id
    
    # 4. Create Sale
    mock_client._post.return_value = {"SaleId": 555, "Heading": "Test Sale"}
    new_sale = mock_client.create_sale(title="Test Sale", contact_id=target_contact_id, person_id=target_person_id, amount=100.0)
    assert new_sale["SaleId"] == 555
    
    # 5. Create Project
    mock_client._post.return_value = {"ProjectId": 777, "Name": "Test Project"}
    new_project = mock_client.create_project(name="Test Project", contact_id=target_contact_id, person_id=target_person_id)
    assert new_project["ProjectId"] == 777
    
    # 6. Update UDFs
    mock_client._patch.return_value = True
    success = mock_client.update_entity_udfs(target_contact_id, "Contact", {"SuperOffice:1": "Val"})
    assert success is True

def test_find_existing_contact(mock_client):
    """Verifies that find_contact_by_criteria returns the found contact."""
    target_contact_id = 171132
    mock_client.search.return_value = [{"contactId": target_contact_id, "nameDepartment": "Existing Corp"}]
    
    contact = mock_client.find_contact_by_criteria(name="Existing Corp")
    assert contact["contactId"] == target_contact_id
