import logging
from xml.etree import ElementTree

from staff.lib import requests
from django.conf import settings
from phonenumbers import (
    format_number,
    NumberParseException,
    parse,
    PhoneNumberFormat,
)

from staff.lib import tvm2
from staff.lib.utils.ordered_choices import OrderedChoices


logger = logging.getLogger(__name__)

SEND_SMS_RETRIES = 3


RESPONSES = OrderedChoices(
    ('OK', 'ok'),
    ('CONNECTION_ERROR', 'connection_error'),
    ('UNKNOWN_ERROR', 'unknown_error'),
    ('INCORRECT_YASMS_ANSWER', 'incorrect_yasms_answer'),
    ('BADPHONE', 'badphone'),
    ('INTERROR', 'interror'),
)


def send(number, text):
    """
    Available responses:
        one of RESPONSES
        all from https://doc.yandex-team.ru/Passport/YaSMSDevGuide/reference/sendsms.html#request__from-uid
        RESPONSES.BADPHONE - can be returned by yasms and this function as well
    :param number: str
    :param text: str
    :return: str. status code
    """

    try:
        number = format_number(
            parse(number, 'RU'),
            PhoneNumberFormat.E164,
        )
    except NumberParseException:
        return RESPONSES.BADPHONE

    had_conn_err = False
    errcode = None

    for _ in range(SEND_SMS_RETRIES):
        try:
            response = _send_request(text, number)
            answer = ElementTree.fromstring(response)
            if answer.find('message-sent') is not None:
                return RESPONSES.OK
            errcode = answer.find('errorcode').text.lower()
            if errcode != RESPONSES.INTERROR:
                return errcode
        except ElementTree.ParseError as err:
            logger.exception(str(err))
            had_conn_err = False
            errcode = RESPONSES.INCORRECT_YASMS_ANSWER
        except (requests.ConnectionError, requests.ConnectTimeout):
            had_conn_err = True
        except Exception as err:
            had_conn_err = False
            logger.exception(str(err))
            pass
    if errcode is not None:
        return errcode
    elif had_conn_err:
        return RESPONSES.CONNECTION_ERROR
    else:
        return RESPONSES.UNKNOWN_ERROR


def _send_request(text, number):
    return requests.get(
        'https://{host}/sendsms'.format(host=settings.YASMS_HOST),
        params={
            'sender': 'staff',
            'text': text,
            'phone': number,
        },
        headers={tvm2.TVM_SERVICE_TICKET_HEADER: tvm2.get_tvm_ticket_by_deploy('yasms', 'yasms')},
    ).content
