// 14D deep link 听写的跨进程交接（App Group UserDefaults）：
// 主 App 听写完成 → write(text)；用户手动切回原 App 调起 dudu 键盘
// → consume() 取走并 insertText 自动上屏。
// 21G：App Group pending_text 是主通道（稳定、不污染用户剪贴板），write 回报是否
// 成功写入真正的 App Group；剪贴板降级为 App Group 不可用时的兜底（见 DictationController）。
//
// 为什么是"用户手动切回"：iOS 不提供"跳回上一个 App"的公开 API，
// 键盘扩展经 extensionContext.open 调起主 App 时也无法携带可用于自动跳回的
// return 上下文 —— 平台限制，只能由用户自己切回，键盘被动消费。
// 120s 过期：防止旧听写文本在无关输入场景误上屏（过期后用户仍可手动粘贴剪贴板）。
import Foundation

public enum PendingTextStore {
    private enum Key {
        static let text = "dictation.pending_text"
        static let ts = "dictation.pending_ts" // 写入时刻（秒级 Unix 时间戳）
    }

    /// 待上屏文本有效期（秒）
    public static let maxAgeSeconds: TimeInterval = 120

    /// App Group 是否可用：无签名本地调试场景拿不到 suite，键盘扩展（另一进程）读不到，
    /// 此时主通道失效，需剪贴板兜底。
    private static var appGroupDefaults: UserDefaults? {
        UserDefaults(suiteName: AccountStore.appGroupID)
    }

    private static var defaults: UserDefaults {
        appGroupDefaults ?? .standard
    }

    /// 主 App 听写完成时写入（空文本不写）。
    /// 返回是否成功写入 App Group（主通道）；false 表示 App Group 不可用，
    /// 调用方应改用剪贴板兜底（21G：避免无条件污染用户剪贴板）。
    @discardableResult
    public static func write(_ text: String) -> Bool {
        guard !text.isEmpty else { return false }
        guard let group = appGroupDefaults else { return false } // App Group 不可用 → 主通道失效
        group.set(text, forKey: Key.text)
        group.set(Date().timeIntervalSince1970, forKey: Key.ts)
        return true
    }

    /// 键盘扩展消费：取走并立即清除（只上屏一次）。
    /// 返回文本与"写入 → 消费"的延迟（秒）；过期 / 不存在返回 nil。
    public static func consume() -> (text: String, delaySeconds: TimeInterval)? {
        guard let text = defaults.string(forKey: Key.text), !text.isEmpty else { return nil }
        let ts = defaults.double(forKey: Key.ts)
        clear()
        let age = Date().timeIntervalSince1970 - ts
        guard age >= 0, age < maxAgeSeconds else { return nil }
        return (text, age)
    }

    public static func clear() {
        defaults.removeObject(forKey: Key.text)
        defaults.removeObject(forKey: Key.ts)
    }
}
