package com.tencent.qian.webview.model

import androidx.annotation.ColorInt

/**
 * Tencent Qian H5 容器配置。
 *
 * **设计要点**:
 * - 全部字段带默认值,客户最少 0 配置即可跑通签署流程
 * - 与 iOS `TencentQianWebViewConfig` struct 字段 1:1 对齐(命名、默认值、语义)
 * - **不开放** DOM Storage / Cookie / 第三方 Cookie 开关 —— 详见 design.md D4
 *
 * **typical usage**:
 * ```kotlin
 * val config = TencentQianWebViewConfig(
 *     topBarTitle = "电子签署",
 *     externalSchemes = listOf("weixin", "alipays", "mqqapi"),
 *     userAgentExtra = "myapp/3.2.1"
 * )
 * TencentQianWebView.open(context, signUrl, config, callback)
 * ```
 */
public data class TencentQianWebViewConfig(

    // ────────── 顶栏 ──────────

    /** 容器模式下是否显示顶栏。配置模式 (Configurator) 下此字段忽略。 */
    val showTopBar: Boolean = true,

    /** 顶栏标题文案。空字符串则使用默认「电子签署」。 */
    val topBarTitle: String = "",

    /** 顶栏背景色(ARGB)。`null` 走默认白色。 */
    @ColorInt val topBarBackgroundColor: Int? = null,

    /** 顶栏文字色(ARGB,含返回箭头与标题)。`null` 走默认黑色。 */
    @ColorInt val topBarTextColor: Int? = null,

    /** 顶栏右上角是否显示「关闭」按钮。 */
    val showCloseButton: Boolean = true,

    /**
     * 状态栏样式。
     * - [StatusBarStyle.LIGHT_CONTENT] 状态栏文字白色(深色背景)
     * - [StatusBarStyle.DARK_CONTENT] 状态栏文字黑色(浅色背景,默认)
     */
    val statusBarStyle: StatusBarStyle = StatusBarStyle.DARK_CONTENT,

    // ────────── User-Agent ──────────

    /**
     * 是否注入 SDK UA 标识(`qianwv/<version>`)。
     *
     * H5 端通过此标识启用 SDK 专属兼容逻辑并关联日志；
     * 关闭后相关兼容功能将降级，且问题排查难度增大。默认开启。
     */
    val injectUserAgent: Boolean = true,

    /**
     * 客户附加的 UA 段,会拼接在 `qianwv/x.x.x` 之后。
     *
     * 例:`"myapp/3.2.1"` → 最终 UA = `<system-ua> qianwv/1.0.0 myapp/3.2.1`
     */
    val userAgentExtra: String = "",

    // ────────── 内容混合(http / https)──────────

    /**
     * 是否允许在 https 页面加载 http 子资源。
     *
     * 人脸核身跨域 https,默认 [MixedContentPolicy.NEVER](`MIXED_CONTENT_NEVER_ALLOW`)。
     */
    val allowMixedContent: MixedContentPolicy = MixedContentPolicy.NEVER,

    // ────────── 关闭确认 ──────────

    /**
     * 用户在容器模式下点关闭/返回时,是否弹「确认离开?」二次确认。
     *
     * 推荐场景:防止用户在签署中误退出。
     */
    val confirmBeforeClose: Boolean = false,

    /** 二次确认 dialog 的标题文案,空走默认。 */
    val confirmCloseTitle: String = "",

    /** 二次确认 dialog 的正文文案,空走默认。 */
    val confirmCloseMessage: String = "",

    // ────────── Scheme 拦截白名单 ──────────

    /**
     * 允许跳出本 App 的外部 scheme 白名单。
     *
     * **覆盖语义**:传入即整体覆盖,默认 = `["weixin", "alipays"]`。
     * 客户传 `emptyList()` = 禁止所有外部 scheme 跳出。
     *
     * **Android 11+ (API 30) Package Visibility 注意**:
     * 自定义 scheme 时,客户**必须**在 `AndroidManifest.xml` 中声明对应的 `<queries>` 条目,
     * 否则 `startActivity` 会因包可见性限制而抛 `ActivityNotFoundException`(即使目标 App 已安装)。
     * 示例:
     * ```xml
     * <queries>
     *     <intent>
     *         <action android:name="android.intent.action.VIEW" />
     *         <data android:scheme="mqqapi" />
     *     </intent>
     * </queries>
     * ```
     */
    val externalSchemes: List<String> = listOf("weixin", "alipays"),

    // ────────── 自检页 URL ──────────

    /**
     * 自检页地址。`null` 时走 SDK 默认 URL
     * (`https://quick.beta.qian.tencent.cn/compatibilityTest`,SDK 默认 beta 环境,兼容性测试无需切生产)。
     */
    val compatibilityTestUrl: String? = null,

    // ────────── JS 弹窗样式 ──────────

    /**
     * JS `alert` / `confirm` 弹窗样式。
     * - [JsDialogStyle.SYSTEM] 系统 [android.app.AlertDialog] 默认样式
     * - [JsDialogStyle.MATERIAL] Material `MaterialAlertDialogBuilder`(默认)
     */
    val jsDialogStyle: JsDialogStyle = JsDialogStyle.MATERIAL,

    // ────────── 下载 Cookie 同步 ──────────

    /**
     * 下载文件时是否从 WebView 同步 Cookie 到下载请求头。
     *
     * - `false`(默认):不携带 Cookie。电子签签署场景的下载链接通常为
     *   CDN 公开链接或带签名 token 的 URL,无需 Cookie 鉴权。
     * - `true`:从 [android.webkit.CookieManager] 获取与下载 URL 匹配的 Cookie,
     *   注入到下载请求的 `Cookie` header。适用于客户自有业务中
     *   需要 Cookie 鉴权才能下载的场景。
     */
    val downloadWithCookies: Boolean = false,

    // ────────── 文件选择:人脸核身老录制模式兜底 ──────────

    /**
     * H5 `<input accept="...">` 命中此列表中任一 MIME 时,SDK 改用系统相机录像
     * ([android.provider.MediaStore.ACTION_VIDEO_CAPTURE])兜底人脸核身老录制模式。
     *
     * **设计背景**:
     * - 当前(2025+)电子签 / 人脸核身主流走 TRTC(WebRTC),不命中此列表
     * - 仅当设备 / 网络异常导致 H5 端降级到 `<input type=file accept=video/kyc>` 老协议时,
     *   走此兜底拉起系统相机,避免「文件选择器只能挑已有视频」导致活体失败
     * - 默认值 = [com.tencent.qian.webview.filechooser.FileChooserLauncher.DEFAULT_LEGACY_FACE_CAPTURE_MIME_TYPES],
     *   含 `video/kyc`、`video/faceid`
     * - 客户传 `emptyList()` 完全关闭兜底(`<input>` 一律走普通文件选择器)
     * - 客户可追加私有 MIME(如未来 H5 协议演进新增 `video/livecheck`)
     */
    val legacyFaceCaptureMimeTypes: List<String> =
        com.tencent.qian.webview.filechooser.FileChooserLauncher.DEFAULT_LEGACY_FACE_CAPTURE_MIME_TYPES,

    // ────────── 文件选择:HTML Media Capture(`<input capture>`)处理 ──────────

    /**
     * H5 `<input capture>` 属性的处理策略。
     *
     * **背景**:Android `WebChromeClient.FileChooserParams` 默认行为完全忽略 `capture` 属性,
     * H5 写 `<input type="file" accept="image/star" capture="environment">`(此处 star 代指 `*`)
     * 时,系统只弹出普通文件选择器(用户只能"挑已有文件"),无法直接拉系统相机 ——
     * 这是 Android `WebView` 与 iOS `WKWebView`(iOS 14+ 内核原生支持)的关键差异。
     *
     * 本字段控制 SDK 在检测到 `params.isCaptureEnabled == true` 时是否帮 H5 拉系统相机:
     * - [CameraCaptureBehavior.PREFER_FRONT](默认):拉相机,镜头偏好前置(自拍 / 头像 / 活体)
     * - [CameraCaptureBehavior.PREFER_BACK]:拉相机,镜头偏好后置(扫证件 / 营业执照)
     * - [CameraCaptureBehavior.SYSTEM_DEFAULT]:拉相机,不指定镜头,由系统决定
     * - [CameraCaptureBehavior.DISABLED]:忽略 `capture` 属性,一律走普通文件选择器
     *
     * **匹配逻辑**:
     * - `accept` 命中 `image/` 前缀 → `MediaStore.ACTION_IMAGE_CAPTURE`
     * - `accept` 命中 `video/` 前缀(或留空)→ `MediaStore.ACTION_VIDEO_CAPTURE`
     *
     * **镜头偏好的局限**:Android 通过 `MediaStore.EXTRA_USE_FRONT_CAMERA` 等私有 extra 暗示
     * 系统相机镜头方向,但属于**尽力而为**(不同 OEM 行为不一致),不强保命中。
     *
     * **优先级**:本字段优先级**高于** [legacyFaceCaptureMimeTypes];命中 `capture` 属性时
     * 不会再走老协议 MIME 兜底。
     *
     * **iOS 等价**:无。WKWebView 内核 iOS 14+ 原生处理 `<input capture>`,无需 SDK 干预。
     */
    val cameraCaptureBehavior: CameraCaptureBehavior = CameraCaptureBehavior.PREFER_FRONT,
) {

    public enum class StatusBarStyle { LIGHT_CONTENT, DARK_CONTENT }

    /**
     * `<input capture>` 处理策略。
     *
     * 详见 [TencentQianWebViewConfig.cameraCaptureBehavior] KDoc。
     */
    public enum class CameraCaptureBehavior {
        /** 拉系统相机,镜头偏好前置(自拍 / 活体 / 头像)。**默认值**,电子签自拍场景占多数。 */
        PREFER_FRONT,

        /** 拉系统相机,镜头偏好后置(扫证件 / 营业执照)。 */
        PREFER_BACK,

        /** 拉系统相机,不指定镜头,由系统决定。 */
        SYSTEM_DEFAULT,

        /** 忽略 `capture` 属性,一律走普通文件选择器(等价 SDK 1.0 之前行为)。 */
        DISABLED,
    }

    public enum class MixedContentPolicy {
        /** WebSettings.MIXED_CONTENT_NEVER_ALLOW */
        NEVER,

        /** WebSettings.MIXED_CONTENT_ALWAYS_ALLOW */
        ALWAYS,

        /** WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE */
        COMPATIBILITY,
    }

    public enum class JsDialogStyle { SYSTEM, MATERIAL }

    public companion object {
        /** 默认配置(全部默认值)。 */
        @JvmField
        public val DEFAULT: TencentQianWebViewConfig = TencentQianWebViewConfig()

        /**
         * SDK 内置自检页 URL(SDK 默认 beta 环境,兼容性测试无需切生产)。
         */
        public const val DEFAULT_COMPATIBILITY_TEST_URL: String =
            "https://quick.beta.qian.tencent.cn/compatibilityTest"
    }
}
