# -*- coding: utf-8 -*-
import json
import requests

from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.core.urlresolvers import reverse

from passerelle.utils.jsonresponse import APIError
from passerelle.base.models import BaseResource
from passerelle.sms import SMSGatewayMixin

from .choosit import ChoositRegisterWS


class ChoositSMSGateway(BaseResource, SMSGatewayMixin):
    key = models.CharField(max_length=64)
    default_country_code = models.CharField(max_length=3, default=u'33')
    # FIXME: add regexp field, to check destination and from format

    TEST_DEFAULTS = {
        'create_kwargs': {
            'key': '1234',
        },
        'test_vectors': [
            {
                'response': '',
                'result': {
                    'err': 1,
                    'err_desc': 'Choosit error: some destinations failed',
                    'data': [
                        [u'33688888888', u'Choosit error: bad JSON response No JSON object '
                         'could be decoded'],
                        [u'33677777777', u'Choosit error: bad JSON response No JSON object '
                         'could be decoded'],
                    ]
                }
            },
            {
                'response': {
                    'error': 'not ok',
                },
                'result': {
                    'err': 1,
                    'err_desc': 'Choosit error: some destinations failed',
                    'data': [
                        [u'33688888888', u'Choosit error: not ok'],
                        [u'33677777777', u'Choosit error: not ok'],
                    ],
                }
            },
            {
                'response': {
                    'result': u'Envoi terminé',
                    'sms_id': 1234,
                },
                'result': {
                    'err': 0,
                    'data': [
                        [u'33688888888', {'result': u'Envoi terminé', 'sms_id': 1234}],
                        [u'33677777777', {'result': u'Envoi terminé', 'sms_id': 1234}],
                    ],
                }
            }

        ],
    }
    URL = 'http://sms.choosit.com/webservice'

    class Meta:
        verbose_name = 'Choosit'
        db_table = 'sms_choosit'

    @classmethod
    def get_verbose_name(cls):
        return cls._meta.verbose_name

    @classmethod
    def get_icon_class(cls):
        return 'phone'

    def send_msg(self, text, sender, destinations):
        """Send a SMS using the Choosit provider"""
        # from http://sms.choosit.com/documentation_technique.html
        # unfortunately it lacks a batch API...
        destinations = self.clean_numbers(destinations, self.default_country_code, prefix='')
        results = []
        for dest in destinations:
            params = {
                'key': self.key,
                'recipient': dest,
                'content': text[:160],
            }
            data = {'data': json.dumps(params)}
            try:
                r = requests.post(self.URL, data=data)
            except requests.RequestException as e:
                results.append('Choosit error: %s' % e)
            else:
                try:
                    output = r.json()
                except ValueError as e:
                    results.append('Choosit error: bad JSON response %s' % e)
                else:
                    if not isinstance(output, dict):
                        results.append('Choosit error: JSON response is not a dict %r' % output)
                    elif 'error' in output:
                        results.append(u'Choosit error: %s' % output['error'])
                    else:
                        results.append(output)
        if any(isinstance(result, basestring) for result in results):
            raise APIError('Choosit error: some destinations failed',
                           data=zip(destinations, results))
        return zip(destinations, results)


class ChoositRegisterNewsletter(models.Model):
    name = models.CharField(max_length=16)
    description = models.CharField(max_length=128, blank=True)

    class Meta:
        verbose_name = 'Choosit Registration'
        db_table = 'newsletter_choosit'

    def __unicode__(self):
        return u'%s: %s' % (self.name, self.description or u'<unnamed>')


class ChoositRegisterGateway(BaseResource):
    category = _('Newsletter registration')

    url = models.CharField(max_length=200)
    key = models.CharField(max_length=64)
    newsletters = models.ManyToManyField(ChoositRegisterNewsletter, blank=True)

    class Meta:
        verbose_name = 'Choosit Registration'
        db_table = 'registration_choosit'

    @classmethod
    def get_verbose_name(cls):
        return cls._meta.verbose_name

    @classmethod
    def get_icon_class(cls):
        return 'ressources'

    def get_absolute_url(self):
        return reverse('choosit-register-view', kwargs={'slug': self.slug})

    @classmethod
    def get_add_url(cls):
        return reverse('choosit-register-add')

    def get_edit_url(self):
        return reverse('choosit-register-edit', kwargs={'slug': self.slug})

    def get_delete_url(self):
        return reverse('choosit-register-delete', kwargs={'slug': self.slug})

    def get_list(self, user):
        reg = ChoositRegisterWS(self.url, self.key)

        ws = reg.subscriptions(email=user or '')
        if 'error' in ws:
            raise APIError(ws['error'])
        newsletters = ws['newsletter']
        subscriptions = ws['subscriptions']

        filters = dict([(n.name, n.description) for n in self.newsletters.all()])
        if filters:
            for name in newsletters.copy():
                if name not in filters:
                    del newsletters[name]
                elif filters[name]:
                    newsletters[name] = filters[name]

        ret = []
        for id, name in newsletters.items():
            newsletter = {
                'name': id,
                'description': name,
                'transports': {'available': ['mail']}
            }
            if user:
                if id in subscriptions:
                    newsletter['transports']['defined'] = ['mail']
                else:
                    newsletter['transports']['defined'] = []
            ret.append(newsletter)

        return ret

    def post(self, user, data):
        subscriptions = [row['name'] for row in data if row['transports']]
        reg = ChoositRegisterWS(self.url, self.key)
        ws = reg.update(subscriptions, user)
        return {"message": ws['status']}
