import type webview from "@ohos:web.webview";
import type { TencentQianWebViewHandlers } from '../../TencentQianWebViewConfigurator';
class BjcCov {
    coverage: {
        [key: string]: string | number;
    };
    constructor(covData: object) {
        const gcv = "__coverage__";
        let coverage = globalThis[gcv] || (globalThis[gcv] = {});
        if (!coverage[covData.path] && true) {
            coverage[covData.path] = covData;
        }
        this.coverage = coverage[covData.path];
    }
    instrumentFunction(func: number) {
        this.coverage.functions[func].count++;
        this.coverage.functions[func].regions[0].count++;
    }
    instrumentRegion(func: number, region: number) {
        this.coverage.functions[func].regions[region].count++;
    }
    instrumentReturn(func: number, retIdx: number) {
        this.coverage.functions[func].returnes[retIdx].count++;
    }
    instrumentBranch(func: number, branch: number, trueOrFalse: boolean) {
        if (trueOrFalse) {
            this.coverage.functions[func].branches[branch].trueCount++;
            for (let r of Object.values(this.coverage.functions[func].branches[branch].group)) {
                if (r !== branch) {
                    this.coverage.functions[func].branches[r as number].falseCount++;
                }
            }
        }
        else {
            this.coverage.functions[func].branches[branch].falseCount++;
        }
    }
}
let bjccovms5u83u2 = new BjcCov({ version: "bjc v1.0.0", versionCode: 10000, path: "tencentqianwebview/src/main/ets/internal/prewarm/WebHostModel.ets", hash: "9d599ad87b7f62f515fb9ce8845a4e33512028cbfff041172cf23506027b404b", lineCnt: 131, count: 0, projectPath: "", functions: { 0: { name: "anonymous_0", count: 0, regions: { 0: { startLoc: { line: 5, col: 35 }, endLoc: { line: 5, col: 79 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 0 }, 1: { name: "anonymous_1", count: 0, regions: { 0: { startLoc: { line: 7, col: 32 }, endLoc: { line: 7, col: 75 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 1 }, 2: { name: "anonymous_2", count: 0, regions: { 0: { startLoc: { line: 81, col: 34 }, endLoc: { line: 81, col: 44 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 2 }, 3: { name: "anonymous_3", count: 0, regions: { 0: { startLoc: { line: 91, col: 36 }, endLoc: { line: 91, col: 46 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 3 }, 4: { name: "WebHostModel.constructor", count: 0, regions: { 0: { startLoc: { line: 102, col: 3 }, endLoc: { line: 104, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 103, col: 5 }, endLoc: { line: 104, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 4 }, 5: { name: "WebHostModel.clearContainerListeners", count: 0, regions: { 0: { startLoc: { line: 114, col: 3 }, endLoc: { line: 121, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 116, col: 5 }, endLoc: { line: 121, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 5 }, 6: { name: "WebHostModel.cancelPendingRecover", count: 0, regions: { 0: { startLoc: { line: 124, col: 3 }, endLoc: { line: 129, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 125, col: 44 }, endLoc: { line: 128, col: 6 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 125, col: 9 }, endLoc: { line: 125, col: 42 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 6 } }, exeLine: { 0: 1, 1: 2, 2: 5, 3: 7, 4: 20, 5: 21, 6: 23, 7: 25, 8: 27, 9: 30, 10: 31, 11: 32, 12: 33, 13: 34, 14: 42, 15: 45, 16: 53, 17: 60, 18: 66, 19: 72, 20: 74, 21: 81, 22: 91, 23: 100, 24: 102, 25: 103, 26: 114, 27: 116, 28: 117, 29: 118, 30: 119, 31: 120, 32: 124, 33: 125, 34: 126, 35: 127 } });
/** 进度联动回调类型。 */
export type WebProgressListener = (progress: number, visible: boolean) => void;
/** 标题 / 可后退联动回调类型。 */
export type WebTitleListener = (title: string, canGoBack: boolean) => void;
/**
 * 离线 Web 组件（`BuilderNode`）与容器 struct 之间的**共享状态 + 回调载体**。
 *
 * 由于 `@Builder` 是全局函数、无法访问 struct 的 `this`/`@State`，容器与 Web 组件
 * 的联动（进度条、标题、canGoBack、渲染恢复）统一通过本 `@Observed` 对象完成：
 * - Web 组件（在 `@Builder` 内）写入这些字段；
 * - 容器 struct 以 `@ObjectLink`/`@State` 引用同一实例，响应式读取渲染顶栏/进度条。
 *
 * 复用关键：预热池与真实页共用同一 `@Builder`，通过替换本 model 的 `url`/`handlers`
 * 即可把「预热态」切换为「真实签署态」，无需重建 Web 组件。
 */
@Observed
export class WebHostModel {
    /** 当前主框架 URL。 */
    public url: string = 'about:blank';
    /** Web 组件 controller（与容器持有的同一实例）。 */
    public controller: webview.WebviewController;
    /** Configurator 生成的事件处理器集合（controller attach 前可为 null）。 */
    public handlers: TencentQianWebViewHandlers | null = null;
    // ── 联动状态（Page 顶栏/进度条读；Component 忽略）──
    public progress: number = 0;
    public progressVisible: boolean = false;
    public title: string = '';
    public canGoBack: boolean = false;
    public isPageLoading: boolean = false;
    /**
     * 一次性「清历史」标志。池复用（HEAVY 预热）借出后，容器 `loadUrl(signingUrl)` 前置为 true；
     * 首个 `onPageEnd`（signingUrl 加载完成）时执行一次 `clearHistory()`，清掉预热残留
     * （warmupUrl / about:blank），使 signingUrl 成为唯一历史项 —— 第一次返回即触发退出而非回到预热页。
     * 清后立即复位，保证不影响签署页内部的多级前进/后退。自建 node（首页即 signingUrl）无需置位。
     */
    public clearHistoryOnce: boolean = false;
    /** 最近一次主框架导航 URL，用于渲染进程异常兜底重载。 */
    public lastVisitedUrl: string = '';
    /**
     * 渲染进程崩溃连续恢复计数，防止"必崩页面"死循环 reload。
     * 每次崩溃恢复 +1，页面成功加载完成（onPageEnd）时清零；连续崩溃达
     * `MAX_RENDER_RECOVERY` 次仍未成功 → 判定不可恢复，触发 onRenderUnrecoverable 关闭容器。
     * 对齐 Android renderRecoveryCount。
     */
    public renderRecoveryCount: number = 0;
    /**
     * 上次渲染进程崩溃的时间戳（毫秒）。用于冷却窗口重置：距上次崩溃超过
     * `RENDER_RECOVERY_RESET_WINDOW` 视为页面已稳定运行过，本次按全新问题处理并重置
     * `renderRecoveryCount`，避免长时间运行中的偶发（非连续）崩溃累计触顶被误判为不可恢复。
     */
    public lastRenderTerminateAtMs: number = 0;
    /**
     * 本实例是否借自预热池。渲染进程崩溃时用于决定是否作废池实例
     * （避免僵尸实例被后续 `obtain` 复用），对齐 Android `fromPool`。
     */
    public fromPool: boolean = false;
    /**
     * 进度联动回调（容器 struct 设置，用于把 `@Builder` 内的进度事件驱动到 struct `@State`）。
     * 采用回调而非 `@Observed` 深层响应式，规避跨 `BuilderNode` 属性观察的不确定性。
     */
    public onProgressChanged: WebProgressListener | null = null;
    /** 标题 / 可后退联动回调（同上）。 */
    public onTitleChanged: WebTitleListener | null = null;
    /**
     * 渲染进程崩溃且无法恢复时的回调（容器 struct 设置）。
     * `RenderRecovery` 的 `refresh()` + `loadUrl()` 均失败时触发，容器据此关闭页面，
     * 避免用户停留在持久白屏。对齐 Android `recoverFromRenderProcessGone` 恢复失败时 `finish()`。
     */
    public onRenderUnrecoverable: (() => void) | null = null;
    /**
     * 请求作废预热池实例的回调（容器在池复用时绑定为 `HarmonyWebViewPool.invalidate`）。
     *
     * 借出态实例渲染进程崩溃时，即便 `RenderRecovery` reload 成功，该实例也已是"渲染进程死过的"
     * 僵尸，归还后会污染池、被后续 `open` 复用致白屏。故崩溃即作废池（避免僵尸复用），
     * 关闭时不再归还。通过回调解耦，规避 `TencentQianWebNode` ↔ `HarmonyWebViewPool` 循环依赖。
     * 对齐 Android 借出态 `invalidatePooledWebView`。
     */
    public onPoolInvalidateRequest: (() => void) | null = null;
    /**
     * 待执行的延迟恢复 timer id（`RenderRecovery.recover` 返回），-1 表示无。
     *
     * 崩溃恢复延迟 1s 执行，若用户在此窗口内关闭页面（`aboutToDisappear`），必须
     * `clearTimeout` 取消，否则回调会访问已销毁/已归还的 controller，造成无效 reload
     * 或污染已归还的池实例（野指针）。
     */
    public pendingRecoverTimerId: number = -1;
    constructor(controller: webview.WebviewController) {
        bjccovms5u83u2.instrumentFunction(4);
        bjccovms5u83u2.instrumentRegion(4, 1);
        this.controller = controller;
    }
    /**
     * 断开全部指向容器 struct 的联动回调（容器 `aboutToDisappear` 时调用）。
     *
     * **防泄漏关键**：池 model 生命周期跟随池单例（长），容器 struct 生命周期短。
     * 归还池后若不清这些捕获了容器 `this` 的闭包，池 model 会一直持有已销毁容器的引用，
     * 在"归还后 ~ 下次借出前"窗口内造成内存泄漏（上个 Page/Component 无法被回收）。
     * 自建 node 归还前一并清理也无副作用（随后即 dispose）。
     */
    public clearContainerListeners(): void {
        bjccovms5u83u2.instrumentFunction(5);
        bjccovms5u83u2.instrumentRegion(5, 1);
        // 取消未执行的延迟恢复，避免回调访问已销毁/已归还的 controller（野指针）。
        this.cancelPendingRecover();
        this.onProgressChanged = null;
        this.onTitleChanged = null;
        this.onRenderUnrecoverable = null;
        this.onPoolInvalidateRequest = null;
    }
    /** 取消待执行的延迟恢复 timer（若有）。容器销毁/归还池、或恢复重新调度前调用。 */
    public cancelPendingRecover(): void {
        bjccovms5u83u2.instrumentFunction(6);
        if (this.pendingRecoverTimerId !== -1) {
            bjccovms5u83u2.instrumentBranch(6, 0, true);
            bjccovms5u83u2.instrumentRegion(6, 1);
            clearTimeout(this.pendingRecoverTimerId);
            this.pendingRecoverTimerId = -1;
        }
        else {
            bjccovms5u83u2.instrumentBranch(6, 0, false);
        }
    }
}
