import UIKit
import UserNotifications

// APNs 设备令牌的交汇点：解耦 AppDelegate（经 UIKit 回调拿到令牌）与 EngineController（持
// 新鲜会话 token，经引擎桥把令牌上报后端 POST /api/push/apns/register）。令牌走引擎桥注册
// ——与剪贴板 / 吊销同范式，避免原生直连用陈旧 token。
//
// 真机 / 账号门控：真正收到推送需 Push Notifications 能力（aps-environment entitlement；真机
// 须付费 ADP 配 profile）与后端 .p8。模拟器（iOS 16+ / Apple Silicon）可注册取令牌、并经
// `simctl push` 验原生处理；真发真测随付费账号落地。
@MainActor
final class PushRegistry: NSObject
{
    static let shared = PushRegistry()
    private override init() { super.init() }

    weak var engine: EngineController?
    private(set) var deviceTokenHex: String?
    private var requested = false

    // 登录后调用：请求通知授权，授权通过即注册远程通知（触发 AppDelegate didRegister 回调）。
    // 幂等——重复调用只在首次生效。
    func requestAuthorizationAndRegister()
    {
        guard !requested else { return }
        requested = true
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge])
        { granted, _ in
            guard granted else { return }
            Task { @MainActor in UIApplication.shared.registerForRemoteNotifications() }
        }
    }

    // AppDelegate 回调（主线程）：APNs 下发设备令牌（Data）→ 十六进制 → 经引擎桥上报。
    func didRegister(tokenData: Data)
    {
        deviceTokenHex = tokenData.map { String(format: "%02x", $0) }.joined()
        engine?.flushPushRegistration()
    }

    // 登出复位：清状态，允许下次登录重新请求授权 / 注册（令牌按会话归属）。
    func reset()
    {
        requested = false
        deviceTokenHex = nil
    }
}

extension PushRegistry: UNUserNotificationCenterDelegate
{
    // 前台收到推送也展示横幅 + 声音（系统默认前台不展示），与「收到文件」即时提示一致。
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification
    ) async -> UNNotificationPresentationOptions
    {
        return [ .banner, .sound ]
    }
}
