# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2017-2020  Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import datetime

from django.db import models
from django.http import Http404
from django.utils.translation import gettext_lazy as _

from passerelle.base.models import BaseResource
from passerelle.utils.api import endpoint
from passerelle.utils.jsonresponse import APIError


class AirQuality(BaseResource):
    category = _('Misc')
    api_description = _(
        '''
        This API provides a unique format for the air quality data of various places.
        (But only supports the Rhône-Alpes region for now).
        '''
    )

    atmo_aura_api_token = models.CharField(
        max_length=100, verbose_name=_('ATMO AURA API token'), blank=True, null=True
    )

    class Meta:
        verbose_name = _('Air Quality')

    @endpoint(
        pattern=r'^(?P<country>\w+)/(?P<city>\w+)/$',
        example_pattern='{country}/{city}/',
        parameters={
            'country': {'description': _('Country Code'), 'example_value': 'fr'},
            'city': {'description': _('City Name'), 'example_value': 'lyon'},
        },
    )
    def details(self, request, country, city, **kwargs):
        methods = {
            ('fr', 'albertville'): 'air_rhonealpes',
            ('fr', 'annecy'): 'air_rhonealpes',
            ('fr', 'bourg-en-bresse'): 'air_rhonealpes',
            ('fr', 'chambery'): 'air_rhonealpes',
            ('fr', 'chamonix'): 'air_rhonealpes',
            ('fr', 'grenoble'): 'air_rhonealpes',
            ('fr', 'lyon'): 'air_rhonealpes',
            ('fr', 'roanne'): 'air_rhonealpes',
            ('fr', 'saint-etienne'): 'air_rhonealpes',
            ('fr', 'valence'): 'air_rhonealpes',
            ('fr', 'vienne'): 'air_rhonealpes',
        }
        local_method = methods.get((country, city))
        if not local_method:
            raise Http404()
        return getattr(self, local_method)(request, country, city, **kwargs)

    def air_rhonealpes(self, request, country, city, **kwargs):
        if not self.atmo_aura_api_token:
            raise APIError('missing access token for ATMO AURA API')
        insee_codes = {
            'albertville': '73011',
            'annecy': '74010',
            'bourg-en-bresse': '01053',
            'chambery': '73065',
            'chamonix': '74056',
            'grenoble': '38185',
            'lyon': '69381',
            'roanne': '42187',
            'saint-etienne': '42218',
            'valence': '26362',
            'vienne': '38544',
        }
        insee_code = insee_codes.get(city.lower())
        response = self.requests.get(
            'https://api.atmo-aura.fr/communes/%s/indices' % insee_code,
            params={'api_token': self.atmo_aura_api_token},
        )
        json_response = response.json()
        today = datetime.datetime.today().strftime('%Y-%m-%d')
        tomorrow = (datetime.datetime.today() + datetime.timedelta(days=1)).strftime('%Y-%m-%d')
        response_data = {}
        for indice in json_response['indices']['data']:
            if indice['date'] == today:
                response_data['latest'] = {
                    'date': today,
                    'value': indice['valeur'],
                }
            elif indice['date'] == tomorrow:
                response_data['forecast'] = {
                    'j1': {
                        'date': today,
                        'value': indice['valeur'],
                    }
                }
            if 'latest' in response_data and 'forecast' in response_data:
                break

        if 'latest' in response_data:
            comment_response = self.requests.get(
                'https://api.atmo-aura.fr/commentaire',
                params={
                    'date': response_data['latest']['date'],
                    'api_token': self.atmo_aura_api_token,
                },
            )
            if comment_response.ok:
                response_data['comment'] = comment_response.json().get('commentaire')

        return {'data': response_data, 'err': 0}
