import Foundation
import WebKit

/// 通用下载响应处理器（升级自原 PdfNavigationResponseHandler）。
///
/// **触发点**:`WKNavigationDelegate.decidePolicyFor navigationResponse`
///
/// **识别条件**(任一即视为下载):
/// - response MIME 命中可下载白名单(PDF / Office 文档 / 压缩包等)
/// - HTTP `Content-Disposition: attachment`(case-insensitive,值含 attachment 即触发)
/// - `canShowMIMEType == false`（WKWebView 无法渲染的类型）
///
/// **策略**（方案 C：统一 URLSession + Cookie 同步，design.md D23）:
/// - 全版本统一：返回 `.download`，由 `QianNavigationDelegate` 调用 `QianDownloadManager` 处理
/// - 不再区分 iOS 14.5+ / iOS < 14.5，全部走 URLSession 下载 + 分享 sheet
enum DownloadResponseHandler {

    /// 决策结果
    enum Decision {
        /// 已处理,导航应当 `.cancel`
        case cancel
        /// 不处理,导航应当 `.allow`
        case allow
        /// 应当下载：导航应当 `.cancel`，由调用方启动 URLSession 下载
        case download
    }

    // MARK: - 可下载 MIME 白名单

    /// 命中以下 MIME 类型时,即使服务器未返回 Content-Disposition: attachment,
    /// 也视为下载候选(这些类型在移动端没有"在线编辑"场景,用户点击即期望下载)。
    private static let downloadableMimeTypes: Set<String> = [
        // PDF
        "application/pdf",
        // Microsoft Office (OpenXML)
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",   // .docx
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",          // .xlsx
        "application/vnd.openxmlformats-officedocument.presentationml.presentation",  // .pptx
        // Microsoft Office (Legacy)
        "application/msword",            // .doc
        "application/vnd.ms-excel",      // .xls
        "application/vnd.ms-powerpoint", // .ppt
        // WPS Office
        "application/vnd.ms-works",      // .wps
        // CSV（text 类型,WKWebView 可能尝试渲染而非下载,必须显式声明）
        "text/csv",                      // .csv
        // OFD（中国电子文档标准,电子签场景常见）
        "application/ofd",               // .ofd
        // 压缩包
        "application/zip",
        "application/x-zip-compressed",
        "application/x-7z-compressed",   // .7z
        "application/x-rar-compressed",  // .rar (传统)
        "application/vnd.rar",           // .rar (IANA 标准)
        "application/gzip",              // .gz
        // 通用二进制流(服务器未正确配置 MIME 时常见)
        "application/octet-stream",
    ]

    static func decide(
        response: WKNavigationResponse,
        onEvent: ((SdkEvent) -> Void)?
    ) -> Decision {
        let urlResponse = response.response
        let canShow = response.canShowMIMEType

        // 判断是否为下载候选
        let isDownloadCandidate = isDownloadable(response: urlResponse) || !canShow

        guard isDownloadCandidate else { return .allow }

        // 统一返回 .download，由 QianNavigationDelegate 调用 QianDownloadManager 处理
        return .download
    }

    /// 是否符合「下载」语义（基于 MIME 白名单或 Content-Disposition）
    static func isDownloadable(response: URLResponse) -> Bool {
        let mime = (response.mimeType ?? "").lowercased()
        if downloadableMimeTypes.contains(mime) { return true }
        if let http = response as? HTTPURLResponse {
            let disposition = (HTTPHeaderCompat.value(for: "Content-Disposition", in: response) ?? "").lowercased()
            if disposition.contains("attachment") { return true }
        }
        return false
    }
}
