"""迁移码：按目标俱乐部 AppID 生成无限小程序码并上传 COS。"""
from __future__ import annotations

import io
import logging
import time
from typing import Optional, Tuple

import requests
from django.conf import settings

from jituan.services.club_migrate import SCENE_PREFIX, scene_for_token

logger = logging.getLogger(__name__)

RECEIVE_PAGE = 'pages/migrate/receive'


def generate_migrate_qrcode(*, to_club_id: str, token: str) -> Tuple[str, str]:
    """返回 (relative_url, err)。成功时 err 为空。"""
    from utils.weixin_token import get_club_mini_access_token, is_weixin_token_invalid

    club_id = (to_club_id or '').strip()
    if not club_id:
        return '', '缺少目标俱乐部'
    scene = scene_for_token(token)
    if len(scene) > 32:
        return '', 'scene 超长'
    if not scene.startswith(SCENE_PREFIX):
        return '', 'scene 非法'

    access_token = get_club_mini_access_token(club_id)
    if not access_token:
        return '', f'俱乐部 {club_id} 获取微信 token 失败'

    post_data = {
        'scene': scene,
        'page': RECEIVE_PAGE,
        'width': 430,
        'auto_color': False,
        'line_color': {'r': 0, 'g': 0, 'b': 0},
        'check_path': False,
    }

    def _req(tok: str):
        url = f'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={tok}'
        return requests.post(url, json=post_data, timeout=15)

    wx_resp = _req(access_token)
    if wx_resp.headers.get('content-type', '').startswith('application/json'):
        try:
            err = wx_resp.json()
            if is_weixin_token_invalid(err.get('errcode'), err.get('errmsg', '')):
                access_token = get_club_mini_access_token(club_id, force_refresh=True)
                if access_token:
                    wx_resp = _req(access_token)
        except Exception:
            pass

    content_type = wx_resp.headers.get('content-type', '')
    if wx_resp.status_code != 200 or 'image' not in content_type:
        errmsg = '未知错误'
        try:
            error_info = wx_resp.json()
            errmsg = error_info.get('errmsg', errmsg)
            logger.error('migrate qr fail club=%s err=%s', club_id, error_info)
        except Exception:
            logger.error('migrate qr fail club=%s status=%s', club_id, wx_resp.status_code)
        return '', f'生成小程序码失败: {errmsg}'

    from utils.oss_utils import upload_to_oss

    filename = f"migrate_{club_id}_{token}_{int(time.time())}.png"
    oss_path = f"club_migrate/{club_id}/{filename}"
    file_obj = io.BytesIO(wx_resp.content)
    try:
        full_url = upload_to_oss(file_obj, oss_path, content_type='image/png')
    except Exception as e:
        logger.exception('migrate qr upload fail: %s', e)
        return '', f'上传小程序码失败: {e}'
    if not full_url:
        return '', '上传小程序码失败'

    # 前端保存相册必须用 https 完整链；相对路径在 oss 未就绪时会保存失败
    if str(full_url).startswith('http'):
        return str(full_url), ''
    cos_domain = getattr(settings, 'COS_DOMAIN', '').rstrip('/')
    if cos_domain:
        return f'{cos_domain}/{str(full_url).lstrip("/")}', ''
    return str(full_url), ''
