//
//  BridgedWebView.swift
//  ylgamehall
//
//  WKWebView + WebViewJavascriptBridge.js 注入 + BridgeBus 一体封装。
//  详见 docs/H5-Native-Implementation-Design.md §3.3 / 契约 §4.1。
//

import UIKit
import WebKit

/// 内嵌 H5 的 WebView 组件，已挂好桥与必要配置。WebContainerViewController（Phase 1.10）
/// 通过把本 view 嵌入自己的内容区，再加上 16:9 letterbox / 生命周期管理。
@MainActor
public final class BridgedWebView: UIView {

    public let webView: WKWebView
    public let bridge: BridgeBus

    /// - Parameter label: 容器标识（`lobby` / `subGame`），仅用于桥诊断日志区分来源，
    ///   不参与任何契约行为。
    public init(label: String = "webview") {
        // ── WKWebViewConfiguration（契约 §4.1）─────────────────
        let configuration = WKWebViewConfiguration()
        configuration.defaultWebpagePreferences.allowsContentJavaScript = true
        configuration.preferences.javaScriptCanOpenWindowsAutomatically = false
        configuration.preferences.minimumFontSize = 10
        configuration.allowsInlineMediaPlayback = true
        // H5 背景音自播：默认 .all 要求该 WKWebView 实例有 user gesture 才放行媒体，
        // 大厅页用户点击过没问题；子游戏 push 后立即 loadFileURL 自播背景音被静默拦截，
        // 表现为"子游戏 webview 没声音"。设空集让所有媒体都不要求 user gesture。
        configuration.mediaTypesRequiringUserActionForPlayback = []
        configuration.processPool = SharedProcessPool.shared

        // ── 自定义 URL scheme 注册（Phase 1.F）────────────────────
        // 大厅 + 子游戏的 H5 通过 `ylgame://h5/...` 加载，由 AppSchemeHandler 反向
        // 映射到沙盒文件。理由（详见 docs/H5-Native-Implementation-Design.md §17）：
        //   - file:// origin 是 null，XHR/fetch 受限；自定义 scheme 是稳定 origin
        //   - 大厅 + 所有子游戏共用 `ylgame://h5` 单 host → same-origin →
        //     共享 localStorage（与现状 file:// 等价）
        //   - 为未来 Cocos 子游戏 H5 适配铺路
        configuration.setURLSchemeHandler(
            AppSchemeHandler.shared,
            forURLScheme: AppScheme.scheme
        )

        // ── 在 documentStart 注入 WebViewJavascriptBridge.js ─────
        // .atDocumentStart 保证 H5 业务代码运行时 window.WebViewJavascriptBridge 已就绪
        if let url = Bundle.main.url(forResource: "WebViewJavascriptBridge",
                                     withExtension: "js"),
           let source = try? String(contentsOf: url, encoding: .utf8) {
            let userScript = WKUserScript(
                source: source,
                injectionTime: .atDocumentStart,
                forMainFrameOnly: true
            )
            configuration.userContentController.addUserScript(userScript)
        } else {
            // 编译期保证文件存在；运行时若缺，留 print 便于排查
            print("[BridgedWebView] ERROR: WebViewJavascriptBridge.js 未在 Bundle 找到")
        }

        // ── H5 错误中继（Phase 9.2，原则 A 零修改 H5）─────────────
        // 把 console.error / window.onerror / unhandledrejection 通过独立
        // 的 webkit.messageHandlers.h5error 桥到原生 print，开发期减少盲点。
        H5ErrorRelay.shared.install(into: configuration.userContentController)

        // ── 创建 WKWebView + BridgeBus ─────────────────────────
        let webView = WKWebView(frame: .zero, configuration: configuration)
        #if DEBUG
        if #available(iOS 16.4, *) {
            webView.isInspectable = true
        }
        #endif
        let bridge = BridgeBus(webView: webView,
                                controller: configuration.userContentController,
                                label: label)

        self.webView = webView
        self.bridge = bridge

        super.init(frame: .zero)

        // ── ScrollView 配置（契约 §4.1，禁手势滚动 / 弹性 / 自动 inset）──
        let scroll = webView.scrollView
        scroll.bounces = false
        scroll.isScrollEnabled = false   // ⚠️ 漏则 H5 上下滑动失控（契约硬约束）
        scroll.contentInsetAdjustmentBehavior = .never
        scroll.showsVerticalScrollIndicator = false
        scroll.showsHorizontalScrollIndicator = false

        // ── 布局：WebView 撑满 self ─────────────────────────────
        webView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(webView)
        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: topAnchor),
            webView.bottomAnchor.constraint(equalTo: bottomAnchor),
            webView.leadingAnchor.constraint(equalTo: leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])

        backgroundColor = .black
    }

    @available(*, unavailable)
    public required init?(coder: NSCoder) {
        fatalError("BridgedWebView does not support init(coder:)")
    }
}

// MARK: - 跨 WebView 共享的进程池

/// 大厅 / 子游戏 / 弹层共用同一 WKProcessPool，共享 Cookie / 资源缓存，
/// 启动加速。详见 Design §3.5。
@MainActor
public enum SharedProcessPool {
    public static let shared = WKProcessPool()
}
