import json

from alibabacloud_dysmsapi20170525 import models as dysmsapi_20170525_models
from alibabacloud_dysmsapi20170525.client import Client as Dysmsapi20170525Client
from alibabacloud_tea_openapi import models as open_api_models
from flask import Blueprint, request

from app.utils import log_util, config_util, cache_util

mod = Blueprint('sms', __name__)
logger = log_util.logger()


@mod.route('/send', methods=['POST'])
def send():
    data = request.json
    phone = data.get("phone","")
    sign = data.get("sign","")
    template_code = data.get("template_code","")
    template_param = data.get("template_param",{})
    if not phone or not sign or not template_code:
        return json.dumps({
            "code": 400,
            "message": "缺失必填参数",
            "data": None
        })

    try:
        logger.info("sms send param: {}".format(json.dumps(data)))
        if _rate_limit(phone):
            return json.dumps({
                "code": 400,
                "message": "发送过于频繁，请等待1分钟后再试",
                "data": None
            })

        repo = _send_sms(phone, sign, template_code, template_param)

        logger.info("sms send response: {}".format(repo))
        if hasattr(repo, "code"):
            success = repo.code.lower() == "ok"
            msg = repo.message
        else:
            success = repo.body.code.lower() == "ok"
            msg = "{},{}".format(repo.body.code, repo.body.message)
        if success:
            cache_util.set("sms#code#{}".format(phone), template_param.get("code"), ttl=600)
            return json.dumps({
                "code": 200,
                "message": "",
                "data": None
            })
        else:
            return json.dumps({
                "code": 500,
                "message": msg,
                "data": None
            })
    except BaseException as e:
        logger.exception("sms send fail ")
        return json.dumps({
            "code": 500,
            "message": str(e),
            "data": None
        })


def _create_client(sign: str) -> Dysmsapi20170525Client:
    """
    使用AK&SK初始化账号Client
    @return: Client
    @throws Exception
    """
    items = config_util.get("sms")
    for it in items:
        for si in it.get("signs"):
            if sign == si:
                config = open_api_models.Config(
                    endpoint=it.get("endpoint"),
                    access_key_id=it.get("access_key_id"),
                    access_key_secret=it.get("access_key_secret")
                )
                return Dysmsapi20170525Client(config)
    return None


def _send_sms(phone: str, sign: str, template_code: str,
              template_param: dict) -> dysmsapi_20170525_models.SendSmsResponse:
    client = _create_client(sign)
    if client is None:
        raise RuntimeError("不允许使用该签名：" + sign)
    send_sms_request = dysmsapi_20170525_models.SendSmsRequest(
        phone_numbers=phone,
        sign_name=sign,
        template_code=template_code,
        template_param=json.dumps(template_param)
    )
    return client.send_sms(send_sms_request)

def _rate_limit(phone: str) -> bool:
    key = "sms#limit#{}".format(phone)
    if cache_util.get(key,False):
        return True
    cache_util.set(key,True, ttl=60)
    return False
