import requests
from django.core.cache import cache
from django.core.signing import TimestampSigner, BadSignature, SignatureExpired
from .models import WeChatPayConfig, WeChatUser

import logging

logger = logging.getLogger(__name__)

def get_current_wechat_user(request):
    """
    根据 Authorization 头获取当前微信用户
    增强逻辑：如果 Token 解析出的 OpenID 对应的用户不存在（可能已被合并删除），
    但该 OpenID 是 Web 虚拟 ID (web_phone)，尝试通过手机号查找现有的主账号。
    """
    auth_header = request.headers.get('Authorization')
    if not auth_header or not auth_header.startswith('Bearer '):
        return None
    token = auth_header.split(' ')[1]
    signer = TimestampSigner()
    try:
        # 签名包含 openid
        openid = signer.unsign(token, max_age=86400 * 30) # 30天有效
        user = WeChatUser.objects.filter(openid=openid).first()
        
        if user:
            return user
            
        # 如果没找到用户，检查是否是 Web 虚拟 OpenID
        # 场景：Web 用户已被合并到小程序账号，旧 Web Token 依然有效，指向合并后的账号
        if openid.startswith('web_'):
            try:
                # 格式: web_13800138000
                parts = openid.split('_', 1)
                if len(parts) == 2:
                    phone = parts[1]
                    # 尝试通过手机号查找（查找合并后的主账号）
                    user = WeChatUser.objects.filter(phone_number=phone).first()
                    if user:
                        return user
            except Exception:
                pass
                
        return None
    except (BadSignature, SignatureExpired):
        return None

def get_access_token(config=None, force_refresh=False):
    """
    获取微信接口调用凭证 (client_credential)
    """
    # 尝试从缓存获取
    cache_key = 'wechat_access_token'
    if config:
        cache_key = f'wechat_access_token_{config.app_id}'
        
    if not force_refresh:
        token = cache.get(cache_key)
        if token:
            return token

    if not config:
        # 优先查找指定 AppID
        config = WeChatPayConfig.objects.filter(app_id='wxdf2ca73e6c0929f0').first()
        if not config:
            config = WeChatPayConfig.objects.filter(is_active=True).first()
            
    if not config or not config.app_id or not config.app_secret:
        logger.error("No active WeChatPayConfig found or missing app_id/app_secret")
        return None

    url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={config.app_id}&secret={config.app_secret}"
    try:
        response = requests.get(url, timeout=10)
        data = response.json()

        if 'access_token' in data:
            token = data['access_token']
            expires_in = data.get('expires_in', 7200)
            # 缓存 Token，留出 200 秒缓冲时间
            cache.set(cache_key, token, expires_in - 200)
            return token
        else:
            logger.error(f"获取 AccessToken 失败: {data}")
    except Exception as e:
        logger.error(f"获取 AccessToken 异常: {str(e)}", exc_info=True)
    
    return None
