"""
智联招聘签名算法 (crawler_core)
职责：参数构造 + 签名算法，不涉及 HTTP 请求
"""

from __future__ import annotations

import math
import random
from typing import Optional


class ZhilianSign:
    """
    智联招聘请求签名

    功能 1: 生成请求所需的签名参数（device_id, action_id, at, rt 等）
    功能 2: 根据接口类型（cgate / capi）构造对应的签名头或签名参数

    参数说明:
        at:        Access Token（登录后获得，未登录为空）
        rt:        Refresh Token（登录后获得，未登录为空）
        device_id: 设备 ID（自动生成 UUID，也可手动指定）
        version:   小程序版本号
        channel:   渠道标识
        platform:  平台 ID（12 = 微信小程序）
    """

    def __init__(
        self,
        *,
        at: str = "",
        rt: str = "",
        device_id: Optional[str] = None,
        version: str = "4.1.259",
        channel: str = "wxxiaochengxu",
        platform: str = "12",
    ):
        self.at = at
        self.rt = rt
        self.device_id = device_id or self.generate_uuid()
        self.version = version
        self.channel = channel
        self.platform = platform

    # ── 算法: UUID 生成（与小程序一致）────────

    @staticmethod
    def generate_uuid() -> str:
        chars = "0123456789ABCDEF"
        uuid = [""] * 36
        for i in range(36):
            uuid[i] = chars[math.floor(16 * random.random())]
        uuid[14] = "4"
        uuid[19] = chars[(int(uuid[19], 16) & 0x3) | 0x8]
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-"
        return "".join(uuid)

    # ── cgate 签名头 ─────────────────────────

    def sign_headers(self, page_code: str = "0") -> dict:
        """构造 cgate 接口的签名请求头"""
        return {
            "x-zp-at": self.at,
            "x-zp-rt": self.rt,
            "x-zp-action-id": self.generate_uuid(),
            "x-zp-page-code": page_code,
            "x-zp-version": self.version,
            "x-zp-channel": self.channel,
            "x-zp-platform": self.platform,
            "x-zp-device-id": self.device_id,
            "x-zp-business-system": "73",
        }

    # ── capi 签名参数 ────────────────────────

    def sign_params(self) -> dict:
        """构造 capi 接口的签名查询参数"""
        return {
            "at": self.at,
            "rt": self.rt,
            "channel": self.channel,
            "platform": self.platform,
            "version": self.version,
            "d": self.device_id,
        }
