import json

import requests
from django.db import models
from django.utils.translation import gettext_lazy as _

from passerelle.sms.models import SMSResource
from passerelle.utils.jsonresponse import APIError


class ChoositSMSGateway(SMSResource):
    key = models.CharField(verbose_name=_('Key'), max_length=64)

    TEST_DEFAULTS = {
        'create_kwargs': {
            'key': '1234',
        },
        'test_vectors': [
            {
                'response': '',
                'result': {
                    'err': 1,
                    'err_desc': 'Choosit error: some destinations failed',
                    'data': [
                        ['0033688888888', 'Choosit error: bad JSON response'],
                        ['0033677777777', 'Choosit error: bad JSON response'],
                    ],
                },
            },
            {
                'response': {
                    'error': 'not ok',
                },
                'result': {
                    'err': 1,
                    'err_desc': 'Choosit error: some destinations failed',
                    'data': [
                        ['0033688888888', 'Choosit error: not ok'],
                        ['0033677777777', 'Choosit error: not ok'],
                    ],
                },
            },
            {
                'response': {
                    'result': 'Envoi terminé',
                    'sms_id': 1234,
                },
                'result': {
                    'err': 0,
                    'data': [
                        ['0033688888888', {'result': 'Envoi terminé', 'sms_id': 1234}],
                        ['0033677777777', {'result': '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

    def send_msg(self, text, sender, destinations, **kwargs):
        """Send a SMS using the Choosit provider"""
        # from http://sms.choosit.com/documentation_technique.html

        results = []
        for dest in destinations:
            params = {
                'key': self.key,
                'recipient': dest,
                'content': text[:160],
            }
            data = {'data': json.dumps(params)}
            try:
                r = self.requests.post(self.URL, data=data)
            except requests.RequestException as e:
                results.append('Choosit error: %s' % e)
            else:
                try:
                    output = r.json()
                except ValueError:
                    results.append('Choosit error: bad JSON response')
                else:
                    if not isinstance(output, dict):
                        results.append('Choosit error: JSON response is not a dict %r' % output)
                    elif 'error' in output:
                        results.append('Choosit error: %s' % output['error'])
                    else:
                        results.append(output)
        if any(isinstance(result, str) for result in results):
            raise APIError('Choosit error: some destinations failed', data=list(zip(destinations, results)))
        # credit consumed is unknown
