import datetime
import json
from xml.etree import ElementTree as etree

from pot_libs.aiohttp_util.aiohttp_utils import AioHttpUtils
from pot_libs.aredis_util.aredis_utils import RedisUtils
from pot_libs.logger import log
from pot_libs.mysql_util.mysql_util import MysqlUtil
from pot_libs.settings import SETTING


def get_current_date_time():
    """
    获取当前时间 datetime obj
    return current datetime obj
    :return:
    """
    return datetime.datetime.now()


def get_current_datetime_str(time_format="%Y-%m-%d %H:%M:00"):
    return get_current_date_time().strftime(time_format)


class WechatMpMSg:
    def __init__(self, body):
        self.message = body
        self.msgXml = etree.fromstring(self.message)

    def getType(self):
        return self.msgXml.find('MsgType').text

    def getEvent(self):
        return self.msgXml.find('Event').text

    def getEventKey(self):
        return self.msgXml.find('EventKey').text

    def getOpenId(self):
        return self.msgXml.find('FromUserName').text

    def generateResonseXml(self, content):
        value = """
            <xml>
              <ToUserName><![CDATA[%s]]></ToUserName>
              <FromUserName><![CDATA[%s]]></FromUserName>
              <CreateTime>%d</CreateTime>
              <MsgType><![CDATA[text]]></MsgType>
              <Content><![CDATA[%s]]></Content>
            </xml>
        """ % (self.msgXml.find('FromUserName').text,
               self.msgXml.find('ToUserName').text,
               int(get_current_date_time().timestamp()), content)
        return value


class wechatMp:
    app_id = SETTING.wechat_mp_app_id
    secret_key = SETTING.wechat_mp_secret_key
    # access_token = None

    async def getAccessToken(self):
        # if self.access_token:
        #     return self.access_token
        # 1.先从redis获取access_token
        access_token_byte = await RedisUtils().get("wx_access_token")
        print(f"access_token_byte:{access_token_byte}")
        if access_token_byte:
            access_token = access_token_byte.decode()
            return access_token
        # 2.发送请求获取access_token
        url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" \
              "client_credential&appid=%s&secret=%s" % (
                  self.app_id, self.secret_key)
        resp, status_code = await AioHttpUtils().get(url)
        access_token = None
        if status_code == 200:
            res = json.loads(resp)
            if 'access_token' in res:
                access_token = res['access_token']
                # 3.存access_token到redis
                expires_in = int(res.get("expires_in", 7200)) - 10
                await RedisUtils().setex("wx_access_token", expires_in,
                                          access_token)
        return access_token

    async def _get(self, url):
        resp, status_code = await AioHttpUtils().get(url)
        if status_code == 200:
            res = json.loads(resp)
            return res
        return None

    async def getUserList(self, next_open_id=''):
        access_token = await self.getAccessToken()
        url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&" \
              "next_openid=%s" % (
                  access_token, next_open_id)
        user_list = None
        res = await self._get(url)
        if res:
            if 'data' in res:
                user_list = res
        return user_list

    async def getUserInfo(self, open_id):
        access_token = await self.getAccessToken()
        print(f"access_token:{access_token}")
        url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&" \
              "openid=%s&lang=zh_CN" % (
                  access_token, open_id)
        res = await self._get(url)
        userInfo = None
        if res and 'openid' in res:
            userInfo = res
        return userInfo

    async def getUserInfoAndUpdateUser(self, open_id):
        user_data = await self.getUserInfo(open_id)
        imported_at = get_current_datetime_str('%Y-%m-%d %H:%M:%S')
        if user_data:
            open_id = user_data['openid']
            # 1. 判断open_id是否已经在wechat_mp_user表,如果存在更新subscribe为1
            # 如果不存在,插入一条记录
            open_sql = "select id from wechat_mp_user where openid = %s"
            async with MysqlUtil() as conn:
                open_res = await conn.fetchone(open_sql, (open_id,))
            if open_res:
                update_open = "UPDATE wechat_mp_user set subscribe = 1," \
                              "nickname = %s,headimgurl = %s where openid = %s"
                async with MysqlUtil() as conn:
                    await conn.execute(update_open, args=(user_data["nickname"].encode('ISO-8859-1').decode('UTF-8'),
                                                          user_data["headimgurl"],
                                                          open_id))
            else:
                # 插入数据到wechat_mp_user表
                log.info(f"user_data:{user_data}")
                insert_sql = "insert into wechat_mp_user " \
                             "(subscribe, openid, nickname, sex, city, country," \
                             " province, language, headimgurl, subscribe_time, " \
                             "unionid, remark, groupid, tagid_list, " \
                             "subscribe_scene, qr_scene, qr_scene_str, " \
                             "imported_at) values %s"
                async with MysqlUtil() as conn:
                    res = await conn.execute(insert_sql, args=(
                        (user_data["subscribe"], user_data["openid"],
                         user_data["nickname"].encode('ISO-8859-1').decode('UTF-8'),
                         user_data["sex"],
                         user_data["city"].encode('ISO-8859-1').decode('UTF-8'),
                         user_data["country"].encode('ISO-8859-1').decode('UTF-8'),
                         user_data["province"].encode('ISO-8859-1').decode('UTF-8'),
                         user_data["language"],
                         user_data["headimgurl"], user_data["subscribe_time"],
                         user_data.get("unionid"), user_data["remark"],
                         user_data["groupid"], f"{user_data['tagid_list']}",
                         user_data["subscribe_scene"], user_data["qr_scene"],
                         user_data["qr_scene_str"], imported_at
                         ),))
            # 暂时先不支持公众号注册user表
            # 2. user表如果存在数据,更新nickname字段
            # 如果不存在数据,插入数据到user表
            # uni_sql = "select unionid, nickname from wechat_mp_user where openid = %s"
            # async with MysqlUtil() as conn:
            #     open_res = await conn.fetchone(uni_sql, (open_id,))
            # unionid = open_res["unionid"]
            # nickname = open_res["nickname"]
            #
            # user_sql = "select user_id from user where wechat_id = %s"
            # async with MysqlUtil() as conn:
            #     user_res = await conn.fetchone(user_sql, (unionid,))
            # # 更新nickname字段
            # if user_res:
            #     user_update_sql = "update user set name = %s where wechat_id = %s"
            #     async with MysqlUtil() as conn:
            #         await conn.execute(user_update_sql, args=(nickname, unionid))
            # else:
            #     # 插入数据到user表
            #     insert_user_sql = "insert into user (name, wechat_id, " \
            #                       "created_at) values %s"
            #     async with MysqlUtil() as conn:
            #         await conn.execute(insert_user_sql, args=((nickname, unionid, imported_at),))
