"""
知岁OS 第三方对接示例 — Python 版

使用前请确保：
1. 已在知岁OS后台注册服务商，获取 uuid 和 secretkey
2. Python >= 3.6
3. pip install requests
"""

import json
import base64
import requests
from cryptography.hazmat.primitives.ciphers.aead import AESGCM


class ZsosClient:
    def __init__(self, base_url: str, uuid: str, secret_key: str):
        """
        初始化客户端

        :param base_url: 平台基础 URL，如 https://your-domain.com
        :param uuid: 服务商标识
        :param secret_key: 服务商密钥（hex 编码）
        """
        self.base_url = base_url.rstrip('/')
        self.uuid = uuid
        self.secret_key = bytes.fromhex(secret_key)  # hex → bytes

    # ==========================================
    #  开放接口 — useToken（第三方核心接口）
    # ==========================================

    def use_token(self, token: str) -> dict:
        """
        消费数据 token，获取解密后的院校应用数据

        :param token: 用户通过知岁OS小程序获取的接口数据token
        :return: 解密后的原始数据
        """
        # 1. 构造明文：UUID + token
        plaintext = (self.uuid + token).encode('utf-8')

        # 2. AES-256-GCM 加密
        encrypted = self._aes256gcm_encrypt(plaintext)

        # 3. 发送请求
        response = self._post('/api/open/useToken', {
            'uuid': self.uuid,
            'data': encrypted,
        })

        if response.get('code') != 1:
            raise Exception(response.get('msg', '请求失败'))

        # 4. 解密响应数据
        decrypted = self._aes256gcm_decrypt(response['data'])

        return json.loads(decrypted)

    # ==========================================
    #  AES-256-GCM 加密/解密
    # ==========================================

    def _aes256gcm_encrypt(self, plaintext: bytes) -> str:
        """
        AES-256-GCM 加密

        :param plaintext: 明文 bytes
        :return: Base64(IV + TAG + CipherText)
        """
        aesgcm = AESGCM(self.secret_key)
        iv = AESGCM.generate_nonce(bit_length=96)  # 12 字节 IV

        ciphertext_and_tag = aesgcm.encrypt(iv, plaintext, None)
        # ciphertext_and_tag = ciphertext + tag(16字节)

        result = iv + ciphertext_and_tag
        return base64.b64encode(result).decode('ascii')

    def _aes256gcm_decrypt(self, encoded: str) -> str:
        """
        AES-256-GCM 解密

        :param encoded: Base64(IV + TAG + CipherText)
        :return: 明文 string
        """
        decoded = base64.b64decode(encoded)

        iv = decoded[:12]
        ciphertext_and_tag = decoded[12:]

        aesgcm = AESGCM(self.secret_key)
        plaintext = aesgcm.decrypt(iv, ciphertext_and_tag, None)

        return plaintext.decode('utf-8')

    # ==========================================
    #  HTTP 请求
    # ==========================================

    def _post(self, uri: str, data: dict) -> dict:
        """发送 POST 请求"""
        url = self.base_url + uri
        response = requests.post(url, data=data, timeout=30)
        return response.json()


# ==========================================
#  使用示例
# ==========================================

if __name__ == '__main__':
    # 配置（替换为你的实际值）
    BASE_URL = 'https://your-domain.com'
    UUID = 'your-service-uuid'           # 服务商 UUID
    SECRET_KEY = 'your-secret-key-hex'   # 服务商密钥（hex 编码）

    client = ZsosClient(BASE_URL, UUID, SECRET_KEY)

    try:
        # 用户通过知岁OS小程序获取的 token（有效期 15 分钟，一次性使用）
        token = 'user-interface-data-token'

        # 调用 use_token 获取数据
        data = client.use_token(token)

        # 根据接口类型，数据格式不同
        # data 可能是 userInfo、course、score、progress 等格式
        # 具体格式参考 API 文档第 7 节"标准数据格式"

        print('获取数据成功：')
        print(json.dumps(data, ensure_ascii=False, indent=2))

    except Exception as e:
        print(f'错误: {e}')
