"""
Tests for weather API fetcher.
"""

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

from soracli.api.weather_fetcher import (
    WeatherData, WeatherFetcher, WeatherFetchError,
    get_demo_weather, DEMO_WEATHER
)


class TestWeatherData:
    """Tests for WeatherData dataclass."""
    
    def test_from_api_response(self):
        """Test creating WeatherData from API response."""
        api_response = {
            'weather': [{'main': 'Rain', 'description': 'light rain', 'icon': '10d'}],
            'main': {'temp': 15.5, 'humidity': 80},
            'wind': {'speed': 5.0, 'deg': 180},
            'visibility': 8000,
            'clouds': {'all': 75},
            'sys': {'sunrise': 0, 'sunset': 999999999999}
        }
        
        weather = WeatherData.from_api_response(api_response, 'London')
        
        assert weather.condition == 'Rain'
        assert weather.description == 'light rain'
        assert weather.temperature == 15.5
        assert weather.humidity == 80
        assert weather.wind_speed == 5.0
        assert weather.location == 'London'
    
    def test_get_intensity_rain(self):
        """Test intensity calculation for rain."""
        weather = WeatherData(
            condition='Rain',
            description='rain',
            temperature=15,
            humidity=80,
            wind_speed=5.0,
            wind_direction=180,
            visibility=5000,
            clouds=75,
            is_night=False,
            location='Test',
            timestamp=datetime.utcnow(),
            icon='10d',
            raw_data={}
        )
        intensity = weather.get_intensity()
        assert intensity > 0
    
    def test_get_intensity_thunder(self):
        """Test intensity calculation for thunderstorm."""
        weather = WeatherData(
            condition='Thunderstorm',
            description='thunderstorm',
            temperature=22,
            humidity=90,
            wind_speed=15.0,
            wind_direction=270,
            visibility=2000,
            clouds=100,
            is_night=False,
            location='Test',
            timestamp=datetime.utcnow(),
            icon='11d',
            raw_data={}
        )
        intensity = weather.get_intensity()
        assert intensity >= 1.5
    
    def test_get_intensity_fog(self):
        """Test intensity calculation for fog."""
        weather = WeatherData(
            condition='Fog',
            description='fog',
            temperature=10,
            humidity=100,
            wind_speed=1.0,
            wind_direction=0,
            visibility=200,
            clouds=100,
            is_night=False,
            location='Test',
            timestamp=datetime.utcnow(),
            icon='50d',
            raw_data={}
        )
        intensity = weather.get_intensity()
        # Low visibility should result in high intensity
        assert intensity > 1.5


class TestWeatherFetcher:
    """Tests for WeatherFetcher class."""
    
    def test_init_without_api_key(self):
        """Test initialization without API key."""
        with patch.dict('os.environ', {}, clear=True):
            fetcher = WeatherFetcher()
            assert fetcher.api_key is None
    
    def test_init_with_api_key(self):
        """Test initialization with API key."""
        fetcher = WeatherFetcher(api_key='test_key')
        assert fetcher.api_key == 'test_key'
    
    def test_init_from_environment(self):
        """Test API key from environment variable."""
        with patch.dict('os.environ', {'OPENWEATHERMAP_API_KEY': 'env_key'}):
            fetcher = WeatherFetcher()
            assert fetcher.api_key == 'env_key'
    
    def test_fetch_without_api_key_raises(self):
        """Test that fetch raises error without API key."""
        with patch.dict('os.environ', {}, clear=True):
            fetcher = WeatherFetcher()
            with pytest.raises(WeatherFetchError):
                fetcher.fetch('London')
    
    def test_build_url(self):
        """Test URL building."""
        fetcher = WeatherFetcher(api_key='test_key', units='metric')
        url = fetcher._build_url('London')
        assert 'London' in url
        assert 'test_key' in url
        assert 'metric' in url


class TestDemoWeather:
    """Tests for demo weather data."""
    
    def test_get_demo_rain(self):
        """Test getting demo rain data."""
        weather = get_demo_weather('rain')
        assert weather.condition == 'Rain'
    
    def test_get_demo_snow(self):
        """Test getting demo snow data."""
        weather = get_demo_weather('snow')
        assert weather.condition == 'Snow'
    
    def test_get_demo_storm(self):
        """Test getting demo storm data."""
        weather = get_demo_weather('storm')
        assert weather.condition == 'Thunderstorm'
    
    def test_get_demo_fog(self):
        """Test getting demo fog data."""
        weather = get_demo_weather('fog')
        assert weather.condition == 'Fog'
    
    def test_get_demo_clear(self):
        """Test getting demo clear data."""
        weather = get_demo_weather('clear')
        assert weather.condition == 'Clear'
    
    def test_get_demo_unknown(self):
        """Test getting demo data for unknown condition."""
        weather = get_demo_weather('unknown')
        assert weather.condition == 'Clear'  # Defaults to clear
    
    def test_demo_weather_completeness(self):
        """Test that all demo weather entries are complete."""
        for key, weather in DEMO_WEATHER.items():
            assert weather.condition
            assert weather.description
            assert weather.location == 'Demo'
