"""账号绑定服务 — TG ↔ Harvest"""
import secrets
import logging

import httpx

import config
from db.models import UserBinding

logger = logging.getLogger("spam_guard")
VERIFY_URL = "https://repeat.ptools.fun/api/user/users/verify"

# 临时绑定 token 存储（token -> user_id，5分钟过期）
_pending_bindings: dict[str, dict] = {}


def generate_bind_token(tg_user_id: int, tg_username: str) -> tuple[str, str]:
    """生成绑定链接，返回 (token, url)"""
    token = secrets.token_urlsafe(16)
    _pending_bindings[token] = {
        "tg_user_id": tg_user_id,
        "tg_username": tg_username,
    }
    url = f"{config.HARVEST_SERVER_URL}/bind?token={token}&tg_user_id={tg_user_id}"
    return token, url


async def verify_binding(token: str) -> dict:
    """验证绑定（harvest-server 回调时调用）"""
    info = _pending_bindings.pop(token, None)
    if not info:
        return {"ok": False, "reason": "invalid_or_expired_token"}

    tg_user_id = info["tg_user_id"]
    tg_username = info["tg_username"]

    # 尝试调用 harvest-server verify
    try:
        async with httpx.AsyncClient(timeout=10) as client:
            resp = await client.post(
                f"{config.HARVEST_SERVER_URL}/api/verify",
                json={"token": token, "tg_user_id": tg_user_id},
            )
            if resp.status_code == 200:
                data = resp.json()
                harvest_uid = data.get("uid", "")
                harvest_token = data.get("token", "")
            else:
                harvest_uid = str(tg_user_id)
                harvest_token = token
    except Exception:
        harvest_uid = str(tg_user_id)
        harvest_token = token

    # 写入绑定
    binding, _ = await UserBinding.get_or_create(
        tg_user_id=tg_user_id,
        defaults={
            "tg_username": tg_username,
            "harvest_uid": harvest_uid,
            "harvest_token": harvest_token,
        },
    )
    logger.info(f"🔗 账号绑定成功: TG={tg_user_id} Harvest={harvest_uid}")
    return {"ok": True, "harvest_uid": harvest_uid}


async def bind_with_email_token(tg_user_id: int, tg_username: str, email: str, token: str) -> tuple[bool, dict]:
    """调用授权接口验证邮箱+Token，成功后绑定 TG 用户。"""
    try:
        async with httpx.AsyncClient(timeout=15) as client:
            resp = await client.post(VERIFY_URL, json={"email": email, "token": token})
            data = resp.json()
    except Exception as e:
        logger.warning(f"🔗 授权验证请求失败: {type(e).__name__}: {e}")
        return False, {"reason": "验证服务暂时不可用"}

    if not data.get("succeed"):
        return False, data

    auth = data.get("data") or {}
    auth_email = auth.get("email") or email
    time_expire = auth.get("time_expire")

    binding, created = await UserBinding.get_or_create(
        tg_user_id=tg_user_id,
        defaults={
            "tg_username": tg_username,
            "harvest_uid": auth_email,
            "harvest_token": token,
            "auth_email": auth_email,
            "time_expire": time_expire,
        },
    )
    if not created:
        binding.tg_username = tg_username
        binding.harvest_uid = auth_email
        binding.harvest_token = token
        binding.auth_email = auth_email
        binding.time_expire = time_expire
        await binding.save()

    logger.info(f"🔗 授权绑定成功: TG={tg_user_id} email={auth_email}")
    return True, data


async def unbind(tg_user_id: int) -> bool:
    """解绑"""
    deleted = await UserBinding.filter(tg_user_id=tg_user_id).delete()
    if deleted:
        logger.info(f"🔗 账号解绑: TG={tg_user_id}")
    return deleted > 0


async def get_binding(tg_user_id: int) -> dict | None:
    """查询绑定"""
    b = await UserBinding.filter(tg_user_id=tg_user_id).first()
    if b:
        return {"harvest_uid": b.harvest_uid, "email": b.auth_email or b.harvest_uid, "time_expire": b.time_expire, "bound_at": b.bound_at}
    return None
