"""
Unit tests for AI framework
Tests get_model_config() and AICore.run_ai_request() functions
"""
from django.test import TestCase
from igny8_core.auth.models import Account, User, Plan
from igny8_core.modules.system.models import IntegrationSettings
from igny8_core.ai.settings import get_model_config
from igny8_core.ai.ai_core import AICore


class GetModelConfigTestCase(TestCase):
    """Test cases for get_model_config() function"""
    
    def setUp(self):
        """Set up test data"""
        # Create plan first
        self.plan = Plan.objects.create(
            name="Test Plan",
            slug="test-plan",
            price=0,
            credits_per_month=1000
        )
        
        # Create user first (Account needs owner)
        self.user = User.objects.create_user(
            username='testuser',
            email='test@test.com',
            password='testpass123',
            role='owner'
        )
        
        # Create account with owner
        self.account = Account.objects.create(
            name='Test Account',
            slug='test-account',
            plan=self.plan,
            owner=self.user,
            status='active'
        )
        
        # Update user to have account
        self.user.account = self.account
        self.user.save()
    
    def test_get_model_config_with_valid_settings(self):
        """Test get_model_config() with valid IntegrationSettings"""
        IntegrationSettings.objects.create(
            integration_type='openai',
            account=self.account,
            is_active=True,
            config={
                'model': 'gpt-4o',
                'max_tokens': 4000,
                'temperature': 0.7,
                'apiKey': 'test-key'
            }
        )
        
        config = get_model_config('auto_cluster', self.account)
        
        self.assertEqual(config['model'], 'gpt-4o')
        self.assertEqual(config['max_tokens'], 4000)
        self.assertEqual(config['temperature'], 0.7)
        self.assertIn('response_format', config)
    
    def test_get_model_config_without_account(self):
        """Test get_model_config() without account - should raise ValueError"""
        with self.assertRaises(ValueError) as context:
            get_model_config('auto_cluster', None)
        
        self.assertIn('Account is required', str(context.exception))
    
    def test_get_model_config_without_integration_settings(self):
        """Test get_model_config() without IntegrationSettings - should raise ValueError"""
        with self.assertRaises(ValueError) as context:
            get_model_config('auto_cluster', self.account)
        
        self.assertIn('OpenAI IntegrationSettings not configured', str(context.exception))
        self.assertIn(str(self.account.id), str(context.exception))
    
    def test_get_model_config_without_model_in_config(self):
        """Test get_model_config() without model in config - should raise ValueError"""
        IntegrationSettings.objects.create(
            integration_type='openai',
            account=self.account,
            is_active=True,
            config={
                'max_tokens': 4000,
                'temperature': 0.7,
                'apiKey': 'test-key'
                # No 'model' key
            }
        )
        
        with self.assertRaises(ValueError) as context:
            get_model_config('auto_cluster', self.account)
        
        self.assertIn('Model not configured in IntegrationSettings', str(context.exception))
        self.assertIn(str(self.account.id), str(context.exception))
    
    def test_get_model_config_with_inactive_settings(self):
        """Test get_model_config() with inactive IntegrationSettings - should raise ValueError"""
        IntegrationSettings.objects.create(
            integration_type='openai',
            account=self.account,
            is_active=False,
            config={
                'model': 'gpt-4o',
                'max_tokens': 4000,
                'temperature': 0.7
            }
        )
        
        with self.assertRaises(ValueError) as context:
            get_model_config('auto_cluster', self.account)
        
        self.assertIn('OpenAI IntegrationSettings not configured', str(context.exception))
    
    def test_get_model_config_with_function_alias(self):
        """Test get_model_config() with function alias"""
        IntegrationSettings.objects.create(
            integration_type='openai',
            account=self.account,
            is_active=True,
            config={
                'model': 'gpt-4o-mini',
                'max_tokens': 2000,
                'temperature': 0.5
            }
        )
        
        # Test with alias
        config1 = get_model_config('cluster_keywords', self.account)
        config2 = get_model_config('auto_cluster', self.account)
        
        # Both should return the same config
        self.assertEqual(config1['model'], config2['model'])
        self.assertEqual(config1['model'], 'gpt-4o-mini')
    
    def test_get_model_config_json_mode_models(self):
        """Test get_model_config() sets response_format for JSON mode models"""
        json_models = ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo-preview', 'gpt-5.1', 'gpt-5.2']
        
        for model in json_models:
            IntegrationSettings.objects.filter(account=self.account).delete()
            IntegrationSettings.objects.create(
                integration_type='openai',
                account=self.account,
                is_active=True,
                config={
                    'model': model,
                    'max_tokens': 4000,
                    'temperature': 0.7
                }
            )
            
            config = get_model_config('auto_cluster', self.account)
            self.assertIn('response_format', config)
            self.assertEqual(config['response_format'], {'type': 'json_object'})


class AICoreTestCase(TestCase):
    """Test cases for AICore.run_ai_request() function"""
    
    def setUp(self):
        """Set up test data"""
        # Create plan first
        self.plan = Plan.objects.create(
            name="Test Plan",
            slug="test-plan",
            price=0,
            credits_per_month=1000
        )
        
        # Create user first (Account needs owner)
        self.user = User.objects.create_user(
            username='testuser',
            email='test@test.com',
            password='testpass123',
            role='owner'
        )
        
        # Create account with owner
        self.account = Account.objects.create(
            name='Test Account',
            slug='test-account',
            plan=self.plan,
            owner=self.user,
            status='active'
        )
        
        # Update user to have account
        self.user.account = self.account
        self.user.save()
        
        self.ai_core = AICore(account=self.account)
    
    def test_run_ai_request_without_model(self):
        """Test run_ai_request() without model - should return error dict"""
        result = self.ai_core.run_ai_request(
            prompt="Test prompt",
            model=None,
            function_name='test_function'
        )
        
        self.assertIn('error', result)
        self.assertIn('Model is required', result['error'])
        self.assertEqual(result['content'], None)
        self.assertEqual(result['total_tokens'], 0)
    
    def test_run_ai_request_with_empty_model(self):
        """Test run_ai_request() with empty model string - should return error dict"""
        result = self.ai_core.run_ai_request(
            prompt="Test prompt",
            model="",
            function_name='test_function'
        )
        
        self.assertIn('error', result)
        self.assertIn('Model is required', result['error'])
        self.assertEqual(result['content'], None)
        self.assertEqual(result['total_tokens'], 0)
    
    def test_get_model_deprecated(self):
        """Test get_model() method is deprecated and raises ValueError"""
        with self.assertRaises(ValueError) as context:
            self.ai_core.get_model('openai')
        
        self.assertIn('deprecated', str(context.exception).lower())
        self.assertIn('run_ai_request', str(context.exception))

