"""
Tests for RabbitMQ message producers.
"""

import pytest
from unittest.mock import Mock, patch
from datetime import datetime

from app.queues.producers import (
    publish_scraping_task,
    publish_sentiment_analysis_task,
    publish_energy_calculation_task,
    publish_result,
    publish_scraping_result,
    publish_sentiment_analysis_result,
    publish_energy_calculation_result
)


class TestPublishScrapingTask:
    """Tests for publish_scraping_task function."""
    
    @patch('app.queues.producers.datetime')
    def test_publish_scraping_task_twitter(self, mock_datetime):
        """Test publishing a Twitter scraping task."""
        # Mock datetime
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        # Create mock client
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        # Publish task
        publish_scraping_task(
            client=mock_client,
            match_id=123,
            source='twitter',
            keywords=['#MatchName', 'team1 vs team2'],
            priority='normal'
        )
        
        # Verify publish_message called
        mock_client.publish_message.assert_called_once()
        call_args = mock_client.publish_message.call_args
        
        # Check parameters
        assert call_args[1]['queue_name'] == 'scraping_tasks'
        assert call_args[1]['event_type'] == 'scraping.task.created'
        
        # Check task data
        task_data = call_args[1]['data']
        assert task_data['task_type'] == 'scraping'
        assert task_data['match_id'] == 123
        assert task_data['source'] == 'twitter'
        assert task_data['keywords'] == ['#MatchName', 'team1 vs team2']
        assert task_data['priority'] == 'normal'
        assert 'created_at' in task_data
    
    @patch('app.queues.producers.datetime')
    def test_publish_scraping_task_vip(self, mock_datetime):
        """Test publishing a VIP scraping task."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        publish_scraping_task(
            client=mock_client,
            match_id=456,
            source='reddit',
            keywords=['Ligue1'],
            priority='vip'
        )
        
        call_args = mock_client.publish_message.call_args
        task_data = call_args[1]['data']
        
        assert task_data['priority'] == 'vip'
        assert task_data['source'] == 'reddit'


class TestPublishSentimentAnalysisTask:
    """Tests for publish_sentiment_analysis_task function."""
    
    @patch('app.queues.producers.datetime')
    def test_publish_sentiment_analysis_task_twitter(self, mock_datetime):
        """Test publishing a Twitter sentiment analysis task."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        publish_sentiment_analysis_task(
            client=mock_client,
            match_id=123,
            source='twitter',
            entity_ids=['tweet1', 'tweet2', 'tweet3']
        )
        
        call_args = mock_client.publish_message.call_args
        assert call_args[1]['queue_name'] == 'sentiment_analysis_tasks'
        assert call_args[1]['event_type'] == 'sentiment_analysis.task.created'
        
        task_data = call_args[1]['data']
        assert task_data['task_type'] == 'sentiment_analysis'
        assert task_data['match_id'] == 123
        assert task_data['source'] == 'twitter'
        assert task_data['entity_ids'] == ['tweet1', 'tweet2', 'tweet3']
        assert task_data['texts'] == []
        assert 'created_at' in task_data
    
    @patch('app.queues.producers.datetime')
    def test_publish_sentiment_analysis_task_with_texts(self, mock_datetime):
        """Test publishing sentiment analysis task with texts."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        texts = ["Great match!", "Amazing goal", "What a game"]
        
        publish_sentiment_analysis_task(
            client=mock_client,
            match_id=123,
            source='reddit',
            entity_ids=['post1', 'post2', 'post3'],
            texts=texts
        )
        
        call_args = mock_client.publish_message.call_args
        task_data = call_args[1]['data']
        
        assert task_data['texts'] == texts
        assert task_data['source'] == 'reddit'


class TestPublishEnergyCalculationTask:
    """Tests for publish_energy_calculation_task function."""
    
    @patch('app.queues.producers.datetime')
    def test_publish_energy_calculation_task(self, mock_datetime):
        """Test publishing an energy calculation task."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        twitter_sentiments = [
            {'compound': 0.5, 'sentiment': 'positive'},
            {'compound': -0.3, 'sentiment': 'negative'}
        ]
        
        publish_energy_calculation_task(
            client=mock_client,
            match_id=123,
            team_id=456,
            twitter_sentiments=twitter_sentiments
        )
        
        call_args = mock_client.publish_message.call_args
        assert call_args[1]['queue_name'] == 'energy_calculation_tasks'
        assert call_args[1]['event_type'] == 'energy_calculation.task.created'
        
        task_data = call_args[1]['data']
        assert task_data['task_type'] == 'energy_calculation'
        assert task_data['match_id'] == 123
        assert task_data['team_id'] == 456
        assert task_data['twitter_sentiments'] == twitter_sentiments
        assert task_data['reddit_sentiments'] == []
        assert task_data['rss_sentiments'] == []
        assert task_data['tweets_with_timestamps'] == []
        assert 'created_at' in task_data


class TestPublishResult:
    """Tests for publish_result function."""
    
    @patch('app.queues.producers.datetime')
    def test_publish_scraping_result_wrapper(self, mock_datetime):
        """Test publishing a scraping result."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        publish_scraping_result(
            client=mock_client,
            match_id=123,
            source='twitter',
            collected_count=100,
            metadata={'keywords': ['#MatchName']}
        )
        
        call_args = mock_client.publish_message.call_args
        assert call_args[1]['queue_name'] == 'results'
        assert call_args[1]['event_type'] == 'result.published'
        
        result_data = call_args[1]['data']
        assert result_data['result_type'] == 'scraping'
        assert result_data['data']['match_id'] == 123
        assert result_data['data']['source'] == 'twitter'
        assert result_data['data']['collected_count'] == 100
        assert result_data['data']['status'] == 'success'
        assert result_data['data']['metadata'] == {'keywords': ['#MatchName']}
    
    @patch('app.queues.producers.datetime')
    def test_publish_sentiment_analysis_result_wrapper(self, mock_datetime):
        """Test publishing a sentiment analysis result."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        metrics = {
            'total_count': 100,
            'positive_count': 60,
            'negative_count': 20,
            'neutral_count': 20,
            'average_compound': 0.35
        }
        
        publish_sentiment_analysis_result(
            client=mock_client,
            match_id=123,
            source='twitter',
            analyzed_count=100,
            metrics=metrics
        )
        
        call_args = mock_client.publish_message.call_args
        result_data = call_args[1]['data']
        
        assert result_data['result_type'] == 'sentiment'
        assert result_data['data']['match_id'] == 123
        assert result_data['data']['source'] == 'twitter'
        assert result_data['data']['analyzed_count'] == 100
        assert result_data['data']['metrics'] == metrics
        assert result_data['data']['status'] == 'success'
    
    @patch('app.queues.producers.datetime')
    def test_publish_energy_calculation_result_wrapper(self, mock_datetime):
        """Test publishing an energy calculation result."""
        mock_datetime.utcnow.return_value.isoformat.return_value = "2026-01-17T10:00:00"
        
        mock_client = Mock()
        mock_client.publish_message = Mock()
        
        publish_energy_calculation_result(
            client=mock_client,
            match_id=123,
            team_id=456,
            energy_score=78.5,
            confidence=0.82,
            sources_used=['twitter', 'reddit']
        )
        
        call_args = mock_client.publish_message.call_args
        result_data = call_args[1]['data']
        
        assert result_data['result_type'] == 'energy'
        assert result_data['data']['match_id'] == 123
        assert result_data['data']['team_id'] == 456
        assert result_data['data']['energy_score'] == 78.5
        assert result_data['data']['confidence'] == 0.82
        assert result_data['data']['sources_used'] == ['twitter', 'reddit']
        assert result_data['data']['status'] == 'success'
