import UIKit
import WebKit

/// SDK 内置 ``WKUIDelegate``。
///
/// **职责**:
/// - iOS 15+ `requestMediaCapturePermissionFor` → `.grant`(无域名校验)
/// - JS `alert` / `confirm`:WKWebView 默认行为已经是原生 alert,SDK 仍提供自定义实现以保证主标题一致
/// - `createWebViewWith`:WebView 内 `target=_blank` → 用同一 webView 加载,避免新窗口逻辑
final class QianUIDelegate: NSObject, WKUIDelegate {

    private let onEvent: ((SdkEvent) -> Void)?
    private weak var hostingController: UIViewController?

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

    // MARK: - 媒体权限(iOS 15+)

    @available(iOS 15.0, *)
    func webView(
        _ webView: WKWebView,
        requestMediaCapturePermissionFor origin: WKSecurityOrigin,
        initiatedByFrame frame: WKFrameInfo,
        type: WKMediaCaptureType,
        decisionHandler: @escaping (WKPermissionDecision) -> Void
    ) {
        // 直接 grant,无域名校验(详见 design.md)
        decisionHandler(.grant)
        let perms: [String]
        switch type {
        case .camera: perms = ["camera"]
        case .microphone: perms = ["microphone"]
        case .cameraAndMicrophone: perms = ["camera", "microphone"]
        @unknown default: perms = []
        }
        onEvent?(.permissionGranted(permissions: perms))
    }

    // MARK: - target=_blank 处理

    func webView(
        _ webView: WKWebView,
        createWebViewWith configuration: WKWebViewConfiguration,
        for navigationAction: WKNavigationAction,
        windowFeatures: WKWindowFeatures
    ) -> WKWebView? {
        // 用当前 webView 加载,避免新窗口
        if let url = navigationAction.request.url {
            webView.load(URLRequest(url: url))
        }
        return nil
    }

    // MARK: - JS alert / confirm / prompt

    func webView(
        _ webView: WKWebView,
        runJavaScriptAlertPanelWithMessage message: String,
        initiatedByFrame frame: WKFrameInfo,
        completionHandler: @escaping () -> Void
    ) {
        let host = hostingController ?? topViewController(of: webView)
        guard let host = host, canPresent(on: host) else { completionHandler(); return }
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: L10n.jsOK, style: .default) { _ in completionHandler() })
        host.present(alert, animated: true)
    }

    func webView(
        _ webView: WKWebView,
        runJavaScriptConfirmPanelWithMessage message: String,
        initiatedByFrame frame: WKFrameInfo,
        completionHandler: @escaping (Bool) -> Void
    ) {
        let host = hostingController ?? topViewController(of: webView)
        guard let host = host, canPresent(on: host) else { completionHandler(false); return }
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: L10n.jsCancel, style: .cancel) { _ in completionHandler(false) })
        alert.addAction(UIAlertAction(title: L10n.jsOK, style: .default) { _ in completionHandler(true) })
        host.present(alert, animated: true)
    }

    func webView(
        _ webView: WKWebView,
        runJavaScriptTextInputPanelWithPrompt prompt: String,
        defaultText: String?,
        initiatedByFrame frame: WKFrameInfo,
        completionHandler: @escaping (String?) -> Void
    ) {
        let host = hostingController ?? topViewController(of: webView)
        guard let host = host, canPresent(on: host) else { completionHandler(nil); return }
        let alert = UIAlertController(title: nil, message: prompt, preferredStyle: .alert)
        alert.addTextField { $0.text = defaultText }
        alert.addAction(UIAlertAction(title: L10n.jsCancel, style: .cancel) { _ in completionHandler(nil) })
        alert.addAction(UIAlertAction(title: L10n.jsOK, style: .default) { _ in
            completionHandler(alert.textFields?.first?.text)
        })
        host.present(alert, animated: true)
    }

    // MARK: - utils

    /// 检查 ViewController 是否可以安全地 present 弹窗。
    ///
    /// **背景**:当 host 不为 nil 但其 view 已不在 window 层级中时
    /// (例如正在 dismiss 动画中、或已被 pop),`present` 会抛出 warning
    /// 或在 iOS 13 以下 crash。Android 端已有 `isFinishing/isDestroyed` 检查,
    /// 此处为 iOS 等价保护。
    private func canPresent(on vc: UIViewController) -> Bool {
        if vc.isBeingDismissed || vc.isBeingPresented { return false }
        if vc.view.window == nil { return false }
        return true
    }

    private func topViewController(of view: UIView) -> UIViewController? {
        var responder: UIResponder? = view
        while let r = responder {
            if let vc = r as? UIViewController { return vc }
            responder = r.next
        }
        return nil
    }
}
