import Foundation
import WebKit

/// 通过 wordloop:// 协议从 App Bundle 的 www 目录提供前端资源，避免 file:// 脚本无法执行。
final class BundleWebSchemeHandler: NSObject, WKURLSchemeHandler {
    private let wwwRoot: URL
    private let queue = DispatchQueue(label: "wordloop.bundle-web-scheme")

    init(wwwRoot: URL) {
        self.wwwRoot = wwwRoot
    }

    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
        queue.async { [wwwRoot] in
            self.serve(urlSchemeTask: urlSchemeTask, wwwRoot: wwwRoot)
        }
    }

    func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
        // cancelled navigations; no response needed
    }

    private func serve(urlSchemeTask: WKURLSchemeTask, wwwRoot: URL) {
        guard let requestURL = urlSchemeTask.request.url else {
            fail(urlSchemeTask, code: 400, message: "Bad request")
            return
        }

        var path = requestURL.path
        if path.isEmpty || path == "/" {
            path = "/index.html"
        }
        if path.hasPrefix("/") {
            path.removeFirst()
        }

        let fileURL = wwwRoot.appendingPathComponent(path)
        guard fileURL.path.hasPrefix(wwwRoot.path),
              FileManager.default.fileExists(atPath: fileURL.path) else {
            fail(urlSchemeTask, code: 404, message: "Not found: \(path)")
            return
        }

        do {
            var data = try Data(contentsOf: fileURL)
            let mime = Self.mimeType(for: fileURL.pathExtension)
            guard let response = HTTPURLResponse(
                url: requestURL,
                statusCode: 200,
                httpVersion: "HTTP/1.1",
                headerFields: [
                    "Content-Type": mime,
                    "Content-Length": String(data.count),
                    "Access-Control-Allow-Origin": "*",
                ]
            ) else {
                fail(urlSchemeTask, code: 500, message: "Bad response")
                return
            }
            urlSchemeTask.didReceive(response)
            urlSchemeTask.didReceive(data)
            urlSchemeTask.didFinish()
        } catch {
            fail(urlSchemeTask, code: 500, message: error.localizedDescription)
        }
    }

    private func fail(_ task: WKURLSchemeTask, code: Int, message: String) {
        let error = NSError(
            domain: "WordLoopWeb",
            code: code,
            userInfo: [NSLocalizedDescriptionKey: message]
        )
        task.didFailWithError(error)
    }

    private static func mimeType(for ext: String) -> String {
        switch ext.lowercased() {
        case "html", "htm": return "text/html"
        case "js": return "text/javascript; charset=utf-8"
        case "css": return "text/css"
        case "json": return "application/json"
        case "png": return "image/png"
        case "jpg", "jpeg": return "image/jpeg"
        case "svg": return "image/svg+xml"
        case "woff2": return "font/woff2"
        case "woff": return "font/woff"
        default: return "application/octet-stream"
        }
    }
}

enum BundledWebEntry {
    static let schemeURL = URL(string: "wordloop://app/index.html#/")!

    static func register(in configuration: WKWebViewConfiguration, wwwRoot: URL) {
        configuration.setURLSchemeHandler(BundleWebSchemeHandler(wwwRoot: wwwRoot), forURLScheme: "wordloop")
    }
}
