# coding: utf-8

import logging
import re
import requests

from django.conf import settings


wu_base_url = 'http://api.wunderground.com/api/{0:s}/'.format(settings.WEATHER_WEATHER_UNDERGROUND_API_KEY)
log = logging.getLogger('weather.lib')


def get_conditions_for_query(queryitems):
    """Make a wunderground conditions call, return as string."""

    # recombine the query into a string
    query = ' '.join(queryitems)
    query = query.replace(' ', '_')

    try:
        url = wu_base_url + ('{0:s}/q/{1:s}.json'.format('conditions', query))
        log.debug("calling %s", url)
        resp = requests.get(url)
        condition_data = resp.json()
    except IOError as e:
        log.error("error while making conditions query")
        log.exception(e)
        raise

    # condition data is loaded. the rest of this is obviously specific to
    # http://www.wunderground.com/weather/api/d/docs?d=data/conditions
    log.debug(condition_data)

    try:
        # just see if we have current_observation data
        current = condition_data['current_observation']
    except KeyError as e:
        # ok, try to see if the ambiguous results stuff will help
        log.debug(e)
        log.debug("potentially ambiguous results, checking")
        try:
            results = condition_data['response']['results']
            reply = "Multiple results, try one of the following zmw codes:"
            for res in results[:-1]:
                q = res['l'].strip('/q/')
                reply += " {0:s} ({1:s}, {2:s}),".format(q, res['name'], res['country_name'])
            q = results[-1]['l'].strip('/q/')
            reply += " or {0:s} ({1:s}, {2:s}).".format(q, results[-1]['name'], results[-1]['country_name'])
            return reply
        except KeyError as e:
            # now we really know something is wrong
            log.error("error or bad query in conditions lookup")
            log.exception(e)
            return "No results."
    else:
        try:
            location = current['display_location']['full']
            reply = "Conditions for {0:s}: ".format(location)

            weather_str = current['weather']
            if weather_str != '':
                reply += "{0:s}, ".format(weather_str)

            temp_f = current['temp_f']
            temp_c = current['temp_c']
            temp_str = current['temperature_string']
            if temp_f != '' and temp_c != '':
                reply += "{0:.1f}°F ({1:.1f}°C)".format(temp_f, temp_c)
            elif temp_str != '':
                reply += "{0:s}".format(temp_str)

            # append feels like if we have it
            feelslike_f = current['feelslike_f']
            feelslike_c = current['feelslike_c']
            feelslike_str = current['feelslike_string']
            if feelslike_f != '' and feelslike_c != '':
                reply += ", feels like {0:s}°F ({1:s}°C)".format(feelslike_f, feelslike_c)
            elif feelslike_str != '':
                reply += ", feels like {0:s}".format(feelslike_str)

            # whether this is current or current + feelslike, terminate sentence
            reply += ". "

            humidity_str = current['relative_humidity']
            if humidity_str != '':
                reply += "Humidity: {0:s}. ".format(humidity_str)

            wind_str = current['wind_string']
            if wind_str != '':
                reply += "Wind: {0:s}. ".format(wind_str)

            pressure_in = current['pressure_in']
            pressure_trend = current['pressure_trend']
            if pressure_in != '':
                reply += "Pressure: {0:s}\"".format(pressure_in)
                if pressure_trend != '':
                    reply += " and {0:s}".format("dropping" if pressure_trend == '-' else "rising")
                reply += ". "

            heat_index_str = current['heat_index_string']
            if heat_index_str != '' and heat_index_str != 'NA':
                reply += "Heat index: {0:s}. ".format(heat_index_str)

            windchill_str = current['windchill_string']
            if windchill_str != '' and windchill_str != 'NA':
                reply += "Wind chill: {0:s}. ".format(windchill_str)

            visibility_mi = current['visibility_mi']
            if visibility_mi != '':
                reply += "Visibility: {0:s} miles. ".format(visibility_mi)

            precip_in = current['precip_today_in']
            if precip_in != '':
                reply += "Precipitation today: {0:s}\". ".format(precip_in)

            observation_time = current['observation_time']
            if observation_time != '':
                reply += "{0:s}. ".format(observation_time)

            return _prettify_weather_strings(reply.rstrip())
        except KeyError as e:
            log.error("error or unexpected results in conditions reply")
            log.exception(e)
            return "Error parsing results."


def get_forecast_for_query(queryitems):
    """Make a wunderground forecast call, return as string."""

    # recombine the query into a string
    query = ' '.join(queryitems)
    query = query.replace(' ', '_')

    try:
        url = wu_base_url + ('{0:s}/q/{1:s}.json'.format('forecast', query))
        resp = requests.get(url)
        forecast_data = resp.json()
    except IOError as e:
        log.error("error while making forecast query")
        log.exception(e)
        raise

    # forecast data is loaded. the rest of this is obviously specific to
    # http://www.wunderground.com/weather/api/d/docs?d=data/forecast
    log.debug(forecast_data)

    try:
        # just see if we have forecast data
        forecasts = forecast_data['forecast']['txt_forecast']
    except KeyError as e:
        # ok, try to see if the ambiguous results stuff will help
        log.debug(e)
        log.debug("potentially ambiguous results, checking")
        try:
            results = forecast_data['response']['results']
            reply = "Multiple results, try one of the following zmw codes:"
            for res in results[:-1]:
                q = res['l'].strip('/q/')
                reply += " {0:s} ({1:s}, {2:s}),".format(q, res['name'],
                                                         res['country_name'])
            q = results[-1]['l'].strip('/q/')
            reply += " or {0:s} ({1:s}, {2:s}).".format(q, results[-1]['name'],
                                                        results[-1]['country_name'])
            return reply
        except KeyError as e:
            # now we really know something is wrong
            log.error("error or bad query in forecast lookup")
            log.exception(e)
            return "No results."
    else:
        try:
            reply = "Forecast: "
            for forecast in forecasts['forecastday'][0:5]:
                reply += "{0:s}: {1:s} ".format(forecast['title'],
                                                  forecast['fcttext'])

            return _prettify_weather_strings(reply.rstrip())
        except KeyError as e:
            log.error("error or unexpected results in forecast reply")
            log.exception(e)
            return "Error parsing results."


def _prettify_weather_strings(weather_str):
    """
    Clean up output strings.

    For example, turn 32F into 32°F in input string.

    Input:
        weather_str --- the string to clean up

    """

    return re.sub(r'(\d+)\s*([FC])', r'\1°\2', weather_str)