# -*- coding: utf-8 -*-
"""微信小程序登录服务。

``code2session`` 用小程序 ``wx.login`` 的 code 换取 openid。
未配置 ``WECHAT_APPID`` / ``WECHAT_SECRET`` 时走「测试直通」：直接把 code 当
openid 返回，便于无真实微信 appid 的环境联调（生产必须配置真实凭据）。
"""
from __future__ import annotations

import httpx

from .. import config

_WX_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session"


class WechatError(Exception):
    """微信登录异常（code 无效 / 网络错误等）。"""


async def code2session(code: str) -> str:
    """用登录 code 换取 openid。未配置 appid 时直通：``openid = code``。"""
    code = code.strip()
    if not config.WECHAT_APPID or not config.WECHAT_SECRET:
        return code

    try:
        async with httpx.AsyncClient(timeout=10) as client:
            resp = await client.get(
                _WX_SESSION_URL,
                params={
                    "appid": config.WECHAT_APPID,
                    "secret": config.WECHAT_SECRET,
                    "js_code": code,
                    "grant_type": "authorization_code",
                },
            )
            data = resp.json()
    except Exception as exc:  # noqa: BLE001
        raise WechatError(f"wechat code2session request failed: {exc}") from exc

    errcode = data.get("errcode", 0)
    if errcode:
        raise WechatError(
            f"wechat code2session error {errcode}: {data.get('errmsg', '')}"
        )
    openid = data.get("openid")
    if not openid:
        raise WechatError("wechat code2session returned no openid")
    return openid
