import unittest.mock
from unittest.mock import patch, MagicMock
import pytest
from src import ai_client

def test_minimax_model_selection() -> None:
 ai_client.set_provider("minimax", "MiniMax-M2.5")
 assert ai_client._provider == "minimax"
 assert ai_client._model == "MiniMax-M2.5"

def test_minimax_default_model() -> None:
 ai_client.set_provider("minimax", "invalid-model")
 assert ai_client._model == "MiniMax-M2.5"

def test_minimax_list_models() -> None:
 models = ai_client.list_models("minimax")
 assert "MiniMax-M2.7" in models
 assert "MiniMax-M2.5" in models
 assert "MiniMax-M2.1" in models
 assert "MiniMax-M2" in models

def test_minimax_in_providers_list() -> None:
 from src.models import PROVIDERS
 assert "minimax" in PROVIDERS

def test_minimax_in_app_controller_providers() -> None:
 from src.models import PROVIDERS
 assert "minimax" in PROVIDERS

def test_minimax_credentials_template() -> None:
 try:
  ai_client._load_credentials()
 except FileNotFoundError as e:
  error_msg = str(e)
  assert "minimax" in error_msg

def test_minimax_reasoning_extractor_used_when_caps_reasoning_true() -> None:
 """caps.reasoning=True (M2.5/M2.7) should pass the reasoning_extractor to run_with_tool_loop."""
 from src import openai_compatible as oc
 captured_kwargs: list[dict] = []
 def _fake_send(client, request, *, capabilities):
  captured_kwargs.append({"model": request.model})
  return MagicMock(text="ok", tool_calls=[], usage_input_tokens=0, usage_output_tokens=0, usage_cache_read_tokens=0, usage_cache_creation_tokens=0, raw_response=None)
 from src.vendor_capabilities import register, VendorCapabilities
 register(VendorCapabilities(vendor='minimax', model='MiniMax-M2.5', reasoning=True))
 with patch.object(oc, "send_openai_compatible", side_effect=_fake_send), \
      patch("src.ai_client._ensure_minimax_client", return_value=MagicMock()), \
      patch("src.ai_client._get_deepseek_tools", return_value=[]):
  ai_client._send_minimax("system", "user", ".", None, "", False, None, None, None)
 assert len(captured_kwargs) >= 1

def test_minimax_reasoning_extractor_omitted_when_caps_reasoning_false() -> None:
 """caps.reasoning=False (M2/M2.1) should NOT pass the reasoning_extractor (avoid useless getattr)."""
 from src import openai_compatible as oc
 from src.vendor_capabilities import register, VendorCapabilities
 register(VendorCapabilities(vendor='minimax', model='MiniMax-M2', reasoning=False))
 captured_kwargs: list[dict] = []
 def _fake_send(client, request, *, capabilities):
  captured_kwargs.append({"model": request.model})
  return MagicMock(text="ok", tool_calls=[], usage_input_tokens=0, usage_output_tokens=0, usage_cache_read_tokens=0, usage_cache_creation_tokens=0, raw_response=None)
 with patch.object(oc, "send_openai_compatible", side_effect=_fake_send), \
      patch("src.ai_client._ensure_minimax_client", return_value=MagicMock()), \
      patch("src.ai_client._get_deepseek_tools", return_value=[]):
  ai_client._send_minimax("system", "user", ".", None, "", False, None, None, None)
 assert len(captured_kwargs) >= 1

def test_minimax_ensure_client_instantiation() -> None:
 """Verify that _ensure_minimax_client instantiates the OpenAI client with correct credentials and base URL."""
 mock_openai = MagicMock()
 mock_openai_module = MagicMock()
 mock_openai_module.OpenAI = mock_openai
 
 with patch("src.ai_client._require_warmed", return_value=mock_openai_module), \
      patch("src.ai_client._load_credentials", return_value={"minimax": {"api_key": "test-key-123", "base_url": "https://api.minimax.io/v1"}}):
  # Reset client state to force instantiation
  ai_client._minimax_client = None
  ai_client._ensure_minimax_client()
  
  # Assert correct arguments passed to OpenAI
  mock_openai.assert_called_once_with(api_key="test-key-123", base_url="https://api.minimax.io/v1")
  assert ai_client._minimax_client == mock_openai.return_value

def test_minimax_ensure_client_missing_key_raises_value_error() -> None:
 """Verify that _ensure_minimax_client raises ValueError if API key is missing."""
 mock_openai_module = MagicMock()
 with patch("src.ai_client._require_warmed", return_value=mock_openai_module), \
      patch("src.ai_client._load_credentials", return_value={}):
  ai_client._minimax_client = None
  with pytest.raises(ValueError, match="MiniMax API key not found in credentials.toml"):
   ai_client._ensure_minimax_client()
