import Foundation
import UIKit

/// `qianapp://` scheme 拦截器,与 Android `SchemeInterceptor` 1:1 对齐。
final class SchemeInterceptor {

    private let onSignResult: ((SignResult) -> Void)?
    private let onEvent: ((SdkEvent) -> Void)?

    init(onSignResult: ((SignResult) -> Void)?, onEvent: ((SdkEvent) -> Void)?) {
        self.onSignResult = onSignResult
        self.onEvent = onEvent
    }

    /// 尝试拦截 URL。
    /// - Returns: `true` 已识别并处理(导航应 `.cancel`),`false` 未识别
    func handle(_ urlString: String?) -> Bool {
        guard SignResultParser.isQianAppScheme(urlString) else { return false }
        let result = SignResultParser.parse(urlString)
        DispatchQueue.main.async { [weak self] in
            self?.onSignResult?(result)
            self?.onEvent?(.schemeIntercepted(scheme: "qianapp", url: urlString ?? ""))
        }
        return true
    }
}

/// 外部 scheme(微信 / 支付宝 / 自定义)处理器。
final class ExternalSchemeHandler {

    private let externalSchemes: [String]
    private let onEvent: ((SdkEvent) -> Void)?

    init(externalSchemes: [String], onEvent: ((SdkEvent) -> Void)?) {
        self.externalSchemes = externalSchemes
        self.onEvent = onEvent
    }

    /// 尝试启动外部 App。
    /// - Returns: `true` 已识别(无论启动成功失败均消费此次导航),`false` 未识别
    func tryOpen(_ urlString: String?) -> Bool {
        guard let s = urlString, !s.isEmpty,
              let url = URL(string: s),
              let scheme = url.scheme?.lowercased()
        else { return false }

        if scheme == "http" || scheme == "https" { return false }
        if scheme == "qianapp" { return false }

        let matched = externalSchemes.contains { $0.lowercased() == scheme }
        if !matched {
            onEvent?(.schemeNotMatched(url: s))
            return true
        }

        // 主线程调用 UIApplication.open
        if Thread.isMainThread {
            doOpen(url, scheme: scheme, urlString: s)
        } else {
            DispatchQueue.main.async { [weak self] in
                self?.doOpen(url, scheme: scheme, urlString: s)
            }
        }
        return true
    }

    private func doOpen(_ url: URL, scheme: String, urlString: String) {
        guard UIApplication.shared.canOpenURL(url) else {
            onEvent?(.schemeNotMatched(url: urlString))
            return
        }
        UIApplication.shared.open(url, options: [:]) { [weak self] ok in
            if ok {
                self?.onEvent?(.schemeIntercepted(scheme: scheme, url: urlString))
            } else {
                self?.onEvent?(.schemeNotMatched(url: urlString))
            }
        }
    }
}
