import datetime
import random
import re
import string
import time
from asyncio import sleep
from pathlib import Path

from nonebot import require, get_bot, get_driver

from .utils import get, post, load_json, save_json

require('nonebot_plugin_apscheduler')
from nonebot_plugin_apscheduler import scheduler

driver = get_driver()


async def get_address(cookie):
    address_url = 'https://api-takumi.mihoyo.com/account/address/list'
    header = {
        'Accept':          'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
        'Connection':      'keep-alive',
        'Cookie':          cookie,
        'Host':            'api-takumi.mihoyo.com',
        'Origin':          'https://user.mihoyo.com',
        'Referer':         'https://user.mihoyo.com/',
        'User-Agent':      'Mozilla/5.0 (iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.25.1'
    }
    res = await get(url=address_url, headers=header)
    res = res.json()
    if res['message'] == 'OK':
        address = res['data']['list']
        add_list = []
        for add in address:
            add_list.append({'id': add['id'],
                             '地址': f'姓名:{add["connect_name"]} 电话:{add["connect_mobile"]} 地址:{add["province_name"] + add["city_name"] + add["county_name"] + add["addr_ext"]}'})
        return add_list
    else:
        return None


async def get_goods(game):
    game_type = {'崩坏3': 'bh3', '原神': 'hk4e', '崩坏学园2': 'bh2', '未定事件簿': 'nxx', '米游社': 'bbs'}
    url = 'https://api-takumi.mihoyo.com/mall/v1/web/goods/list?app_id=1&point_sn=myb&page_size=20&page={page}&game=' + \
          game_type[game]
    goods_list = []
    goods_list_new = []
    page = 1
    while True:
        res = await get(url=url.format(page=page))
        res = res.json()
        if not res['data']['list']:
            break
        else:
            goods_list += res['data']['list']
        page += 1

    for good in goods_list:
        if good['next_time'] == 0 and good['type'] == 1:
            continue
        good_info = {}
        good_info['id'] = good['goods_id']
        good_info['name'] = good['goods_name']
        good_info['price'] = good['price']
        good_info['time'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(good['next_time']))
        goods_list_new.append(good_info)

    return goods_list_new


def save_exchange_info(user_id, state):
    info = {}
    info['user_id'] = user_id
    info['类型'] = state['商品类型']
    info['cookie'] = state['cookie']
    info['商品'] = state['goods']
    info['地址'] = state['address_id']
    if info['类型'] == '虚拟':
        info['uid'] = state['uid']

    t = f"{user_id}-{info['商品']['id']}"

    path = Path() / 'data' / 'LittlePaimon' / 'myb_exchange' / f'{t}.json'
    path.parent.mkdir(parents=True, exist_ok=True)

    save_json(data=info, path=path)

    scheduler.add_job(
        id=t,
        replace_existing=True,
        misfire_grace_time=5,
        func=exchange_action,
        trigger='date',
        args=(info,),
        next_run_time=datetime.datetime.strptime(info['商品']['time'], '%Y-%m-%d %H:%M:%S')
    )


async def get_bbs_info(info, headers):
    url = 'https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie'
    res = (await get(url=url, headers=headers)).json()
    if res['retcode'] == 0:
        data = res['data']['list']
        for d in data:
            if d['game_uid'] == info['uid']:
                return d['game_biz'], d['region']
    return None, None


async def get_stoken(cookie):
    bbs_cookie_url = 'https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket?login_ticket={}'
    bbs_cookie_url2 = 'https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}'

    login_ticket = re.search('login_ticket=[a-zA-Z0-9]{0,100}', cookie)
    data = (await get(url=bbs_cookie_url.format(login_ticket.group().split('=')[1]))).json()
    if '成功' in data['data']['msg']:
        stuid = data['data']['cookie_info']['account_id']
        data2 = (await get(url=bbs_cookie_url2.format(login_ticket.group().split('=')[1], stuid))).json()
        return data2['data']['list'][0]['token']
    else:
        return None


async def exchange_action(info):
    url = 'https://api-takumi.mihoyo.com/mall/v1/web/goods/exchange'
    headers = {
        'Accept':             'application/json, text/plain, */*',
        'Accept-Encoding':    'gzip, deflate, br',
        'Accept-Language':    'zh-CN,zh-Hans;q=0.9',
        'Connection':         'keep-alive',
        # 'Content-Length':     '88',
        'Content-Type':       'application/json;charset=utf-8',
        'Cookie':             info['cookie'],
        'Host':               'api-takumi.mihoyo.com',
        'Origin':             'https://webstatic.mihoyo.com',
        'Referer':            'https://webstatic.mihoyo.com/',
        'User-Agent':         'Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHtimeL, like Gecko) miHoYoBBS/2.14.1',
        'x-rpc-app_version':  '2.14.1',
        'x-rpc-channel':      'appstore',
        'x-rpc-client_type':  '1',
        'x-rpc-device_id':    ''.join(random.sample(string.ascii_letters + string.digits, 32)).upper(),
        'x-rpc-device_model': 'iPhone10,2',
        'x-rpc-device_name':  ''.join(random.sample(string.ascii_letters + string.digits, random.randrange(5))).upper(),
        'x-rpc-sys_version':  '15.1'
    }
    data = {
        "app_id":       1,
        "point_sn":     "myb",
        "goods_id":     info['商品']['id'],
        "exchange_num": 1,
        "address_id":   info['地址']['id']
    }
    if info['类型'] == '虚拟':
        game_biz, region = await get_bbs_info(info, headers)
        data['uid'] = info['uid']
        data['game_biz'] = game_biz
        data['region'] = region
        if 'stoken' not in info['cookie']:
            stoken = await get_stoken(info['cookie'])
            info['cookie'] += f'stoken={stoken};'

    exchange_url = 'https://api-takumi.mihoyo.com/mall/v1/web/goods/exchange'
    flag = False
    for _ in range(3):
        exchange_res = (await post(url=exchange_url, headers=headers, json=data)).json()
        if exchange_res['retcode'] == 0:
            await get_bot().send_private_msg(user_id=info['user_id'],
                                             message=f'你的米游币商品{info["商品"]["name"]}的兑换成功，结果为:\n{exchange_res["message"]}')
            flag = True
            break
        await sleep(0.2)
    try:
        if not flag:
            await get_bot().send_private_msg(user_id=info['user_id'],
                                             message=f'你的米游币商品{info["商品"]["name"]}兑换失败:\n{exchange_res["message"]}')
    except:
        pass

    path = Path() / 'data' / 'LittlePaimon' / 'myb_exchange' / f"{info['user_id']}-{info['商品']['id']}.json"
    path.unlink()


@driver.on_startup
async def _():
    path = Path() / 'data' / 'LittlePaimon' / 'myb_exchange'
    path.mkdir(parents=True, exist_ok=True)
    for exchange_data in path.iterdir():
        info = load_json(path=exchange_data)
        t = str(exchange_data).replace('data\\LittlePaimon\\myb_exchange\\', '').replace(
            'data/LittlePaimon/myb_exchange/', '').replace(
            '.json', '')
        scheduler.add_job(
            id=t,
            replace_existing=True,
            misfire_grace_time=5,
            func=exchange_action,
            trigger='date',
            args=(info,),
            next_run_time=datetime.datetime.strptime(info['商品']['time'], '%Y-%m-%d %H:%M:%S')
        )


def get_exchange_info(user_id):
    result = ''
    path = Path() / 'data' / 'LittlePaimon' / 'myb_exchange'
    path.mkdir(parents=True, exist_ok=True)
    i = 1
    for exchange_data in path.iterdir():
        file_name = str(exchange_data).replace('data\\LittlePaimon\\myb_exchange\\', '').replace(
            'data/LittlePaimon/myb_exchange/', '')
        if file_name.startswith(user_id):
            info = load_json(path=exchange_data)
            result += f"{i}.{info['商品']['name']} {info['商品']['time']}\n"
            if info['类型'] == '虚拟':
                result += f"兑换至uid{info['uid']}\n"
            else:
                result += f"兑换至{info['地址']['地址']}\n"
            i += 1
    return result or '你还没有米游币兑换计划哦'


def delete_exchange_info(user_id):
    path = Path() / 'data' / 'LittlePaimon' / 'myb_exchange'
    path.mkdir(parents=True, exist_ok=True)
    for exchange_data in path.iterdir():
        file_name = str(exchange_data).replace('data\\LittlePaimon\\myb_exchange\\', '').replace(
            'data/LittlePaimon/myb_exchange/', '')
        if file_name.startswith(user_id):
            exchange_data.unlink()
