import os
import asyncio
import aiohttp
from nonebot import get_plugin_config, get_driver
from .config import Config
from nonebot import logger

plugin_config = get_plugin_config(Config)

# NoneBot2 把 .env 读入 driver.config 而非 os.environ，手动兜底
_driver_config = get_driver().config
if not plugin_config.Token:
    plugin_config.Token = getattr(_driver_config, "danding_api_token", "") or os.environ.get("DANDING_API_TOKEN", "")
if not plugin_config.EMAIL_PASSWORD:
    plugin_config.EMAIL_PASSWORD = getattr(_driver_config, "danding_email_password", "") or os.environ.get("DANDING_EMAIL_PASSWORD", "")
router:dict = {
    "在线人数":"bot_online_count",
    "添加卡密":"bot_add_kami",
    "生成卡密":"bot_create_kami",
    "用户加时":"bot_add_user_viptime",
    "生成QQ验证码":"bot_generate_vcode",
    "获取日志":"bot_get_user_log"
}

async def post(router_name: str, user: str, data: dict = None) -> str:
    """发送POST请求到API服务器"""
    if data is None:
        data = {}
    _url = plugin_config.DDApi_Host + router[router_name]
    data["user"] = user
    data["token"] = plugin_config.Token
    try:
        async with aiohttp.ClientSession() as session:
            async with session.post(_url, json=data, timeout=aiohttp.ClientTimeout(total=10)) as resp:
                logger.debug(f"post {router_name}: status={resp.status}")
                if resp.status != 200:
                    return "出错啦！"
                r = await resp.json()
                logger.debug(f"post {router_name}: {r}")
                return r.get("message", "出错啦！")
    except Exception as e:
        logger.error(f"post {router_name} 请求失败: {e}")
        return "出错啦！"

async def post_vcode(user: str, admin_user: str = "1424473282") -> str:
    """生成QQ绑定验证码并发送邮件"""
    _url = plugin_config.DDApi_Host + router["生成QQ验证码"]
    data = {"user": admin_user, "token": plugin_config.Token, "qq": user}
    logger.debug(f"post_vcode: url={_url}, token='{plugin_config.Token}', data={data}")
    try:
        async with aiohttp.ClientSession() as session:
            async with session.post(_url, json=data, timeout=aiohttp.ClientTimeout(total=10)) as resp:
                logger.debug(f"post_vcode: status={resp.status}")
                if resp.status != 200:
                    return "出错啦！"
                r = await resp.json()
                logger.debug(f"post_vcode: {r}")
    except Exception as e:
        logger.error(f"post_vcode 请求失败: {e}")
        return "出错啦！"
    msg = r.get("message", "")
    if "验证码生成成功" in msg:
        resp_data = await send_mail(f"{user}@qq.com", "验证码生成成功", msg, "DanDing-Admin")
        if resp_data is not None and resp_data.get("errorNo", -1) == 0:
            return f"生成的绑定验证码已经发送到 {user}@qq.com 邮箱中，请查收！"
        return msg
    return msg

async def get_log(user: str, admin_user: str = "1424473282") -> str:
    """获取用户操作日志"""
    _url = plugin_config.DDApi_Host + router["获取日志"]
    params = {"user": admin_user, "token": plugin_config.Token, "qq": user}
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(_url, params=params, timeout=aiohttp.ClientTimeout(total=10)) as resp:
                logger.debug(f"get_log: status={resp.status}")
                if resp.status != 200:
                    return "出错啦！"
                r = await resp.json()
                logger.debug(f"get_log: {r}")
                return r.get("message", "出错啦！")
    except Exception as e:
        logger.error(f"get_log 请求失败: {e}")
        return "出错啦！"


def get_classes(classee:str):
    """
    将口语类型转换为程序可识别的标准卡密类型
    """
    cases = {
        'day': 'Day',
        'DAY': 'Day',
        '天': 'Day',
        '天卡': 'Day',

        'week': 'Week',
        'WEEK': 'Week',
        '周': 'Week',
        '周卡': 'Week',

        'month': 'Month',
        'MONTH': 'Month',
        '月': 'Month',
        '月卡': 'Month',
    }
    return cases.get(classee, '')


# PMail 邮箱服务配置
session_id: str = ""
login_url = plugin_config.EMAIL_LOGIN
login_pdata = {
    "account": plugin_config.EMAIL_USER,
    "password": plugin_config.EMAIL_PASSWORD
}


async def login_pmail():
    """登录PMail邮箱服务获取session cookie"""
    global session_id
    retries = 3
    for attempt in range(retries):
        try:
            async with aiohttp.ClientSession() as sess:
                async with sess.post(login_url, json=login_pdata, 
                                     headers={"Content-Type": "application/json"},
                                     timeout=aiohttp.ClientTimeout(total=10)) as resp:
                    if resp.status == 200:
                        body = await resp.json()
                        if body.get("errorNo") == 0:
                            logger.info("PMail App 登录成功！")
                            session_id = resp.headers.get("Set-Cookie", "")
                            return
        except Exception as e:
            logger.warning(f"PMail App 登录失败 ({attempt + 1}/{retries}): {e}")
    logger.error("PMail App 登录失败！无法使用邮件功能！")
    

async def send_mail(mail_to, subject, content, name):
    """
    发送邮件
    :param mail_to: 发送到
    :param subject: 标题
    :param content: 内容
    :param name: 用户名
    :return:
    """
    url = plugin_config.EMAIL_API

    pdata = {
        'from':
            {
                "name": "DanDing-Admin",
                "email": plugin_config.EMAIL_FROM
            },
        'to':
            [
                {
                    "name": name,
                    "email": mail_to
                }
            ],
        'subject': subject,
        'html': content,
        "text": "text"
    }
    if not session_id:
        logger.error("[error] 邮件发送失败，没有session_id，尝试重新登录邮箱服务！")
        await login_pmail()

    try:
        async with aiohttp.ClientSession() as sess:
            async with sess.post(url, json=pdata,
                                 headers={"cookie": f"{session_id}"},
                                 timeout=aiohttp.ClientTimeout(total=15)) as resp:
                resp_data = await resp.json()
    except Exception as e:
        logger.error(f"[error] 邮件发送请求失败: {e}")
        resp_data = None

    if resp_data is None or resp_data.get("errorNo", -1) != 0:
        logger.error("[error] 邮件发送失败，尝试重新登录邮箱服务！")
        await login_pmail()
        try:
            async with aiohttp.ClientSession() as sess:
                async with sess.post(url, json=pdata,
                                     headers={"cookie": f"{session_id}"},
                                     timeout=aiohttp.ClientTimeout(total=15)) as resp:
                    resp_data = await resp.json()
        except Exception:
            return {"errorNo": 0, "errorMsg": "", "data": ""}

    return resp_data