# weather.py
#
# author: deng
# date: 20251127

import requests


class WeatherFetcher:
    """Fetch weather data for hiking locations."""

    def __init__(self):
        """Initialize weather fetcher."""
        self.api_url = 'https://api.open-meteo.com/v1/forecast'
        self.request_timeout = 8  # unit: second

    def convert_wind_degrees_to_flow_direction(self, degrees):
        """Convert wind direction from degrees to flow direction emoji.

        Args:
            degrees: Wind direction in degrees (0-360)

        Returns:
            str: Flow direction as emoji arrow (pointing where wind is blowing to)
        """
        if degrees is None:
            return 'N/A'
        directions = ['⬇️', '↙️', '⬅️', '↖️', '⬆️', '↗️', '➡️', '↘️']
        index = round(degrees / 45) % 8
        return directions[index]

    def get_wind_speed_indicator(self, wind_speed):
        """Get wind speed level indicator based on speed.

        Args:
            wind_speed: Wind speed in km/h

        Returns:
            str: Emoji indicator (🟢/🟡/🟠/🔴)
        """
        if wind_speed is None:
            return ''

        if wind_speed < 20:
            return '🟢'  # Safe
        elif wind_speed < 40:
            return '🟡'  # Caution
        elif wind_speed < 60:
            return '🟠'  # Alert
        else:
            return '🔴'  # Dangerous

    def get_weather(self, latitude, longitude):
        """Fetch weather data for given coordinates.

        Args:
            latitude: Latitude of the location
            longitude: Longitude of the location

        Returns:
            dict: Weather data with temperature, humidity, precipitation, etc.
                  Returns None if request fails.
        """
        try:
            params = {
                'latitude': latitude,
                'longitude': longitude,
                'current': 'temperature_2m,relative_humidity_2m,precipitation,wind_speed_10m,wind_direction_10m',
                'daily': 'temperature_2m_max,temperature_2m_min,precipitation_probability_max',
                'timezone': 'auto',
                'forecast_days': 3,
            }

            response = requests.get(self.api_url, params=params, timeout=self.request_timeout)
            response.raise_for_status()

            data = response.json()

            # Parse weather data
            current = data.get('current', {})
            daily = data.get('daily', {})

            weather_info = {
                'current_temperature': current.get('temperature_2m'),
                'current_humidity': current.get('relative_humidity_2m'),
                'current_precipitation': current.get('precipitation'),
                'current_precipitation_prob': daily.get('precipitation_probability_max', [None])[0],  # Today's rain probability
                'current_wind_speed': current.get('wind_speed_10m'),
                'current_wind_direction': current.get('wind_direction_10m'),
                'daily_temp_max': daily.get('temperature_2m_max', []),
                'daily_temp_min': daily.get('temperature_2m_min', []),
                'daily_precipitation_prob': daily.get('precipitation_probability_max', []),
                'daily_time': daily.get('time', []),
            }

            return weather_info

        except requests.exceptions.RequestException as e:
            print(f'天氣資料獲取失敗: {str(e)}')
            return None
        except Exception as e:
            print(f'天氣資料處理失敗: {str(e)}')
            return None

    def format_weather_display(self, weather_info):
        """Format weather data for display.

        Args:
            weather_info: Weather data dictionary from get_weather()

        Returns:
            dict: Formatted weather data for UI display
        """
        if not weather_info:
            return None

        formatted = {
            'temperature': f'{weather_info.get("current_temperature", "N/A")}°C',
            'humidity': f'{weather_info.get("current_humidity", "N/A")}%',
            'precipitation': f'{weather_info.get("current_precipitation", 0)} mm',
            'wind_speed': f'{weather_info.get("current_wind_speed", "N/A")} km/h',
            'forecast': [],
        }

        # Add 3-day forecast
        times = weather_info.get('daily_time', [])
        temp_max = weather_info.get('daily_temp_max', [])
        temp_min = weather_info.get('daily_temp_min', [])
        precip_prob = weather_info.get('daily_precipitation_prob', [])

        for i in range(min(3, len(times))):
            formatted['forecast'].append(
                {
                    'date': times[i],
                    'temp_max': temp_max[i] if i < len(temp_max) else 'N/A',
                    'temp_min': temp_min[i] if i < len(temp_min) else 'N/A',
                    'precip_prob': precip_prob[i] if i < len(precip_prob) else 'N/A',
                }
            )

        return formatted
