// @vitest-environment jsdom
// SPEC: PJ2026-010405 云端控制台.
// Implementation reference: draft-2026-07-13-p0-cloud-console.
// Responsibility: 验证 OpenCode frame URL 换票完成后仍等待 iframe load，并提供失败、超时与重试状态。

import { flushPromises, mount } from "@vue/test-utils";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import OpenCodeFrameView from "./OpenCodeFrameView.vue";

vi.mock("@/config/runtime", () => ({
  opencodeFrameUrl: () => "https://opencode.example.test"
}));

function successfulFrameUrlResponse(): Response {
  return new Response(JSON.stringify({ url: "/opencode/proxy/?ticket=redacted" }), {
    status: 200,
    headers: { "content-type": "application/json" }
  });
}

describe("OpenCodeFrameView", () => {
  beforeEach(() => {
    vi.stubGlobal("fetch", vi.fn(async () => successfulFrameUrlResponse()));
  });

  afterEach(() => {
    vi.useRealTimers();
    vi.unstubAllGlobals();
  });

  test("waits for iframe load before reporting ready", async () => {
    const wrapper = mount(OpenCodeFrameView);
    await flushPromises();

    expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("loading");
    expect(wrapper.get("iframe").attributes("src")).toBe("/opencode/proxy/?ticket=redacted");
    expect(wrapper.get("[role='status']").text()).toContain("OpenCode 加载中");

    await wrapper.get("iframe").trigger("load");
    expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("ready");
    expect(wrapper.find("[role='status']").exists()).toBe(false);
    wrapper.unmount();
  });

  test("shows a retry after iframe error and starts a fresh bounded load", async () => {
    const wrapper = mount(OpenCodeFrameView);
    await flushPromises();

    await wrapper.get("iframe").trigger("error");
    expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("error");
    expect(wrapper.get("[role='status']").text()).toContain("iframe 加载失败");
    expect(wrapper.find("iframe").exists()).toBe(false);

    await wrapper.get("button").trigger("click");
    await flushPromises();
    expect(fetch).toHaveBeenCalledTimes(2);
    expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("loading");
    expect(wrapper.find("iframe").exists()).toBe(true);
    wrapper.unmount();
  });

  test("fails a frame that does not load within the bounded timeout", async () => {
    vi.useFakeTimers();
    const wrapper = mount(OpenCodeFrameView);
    await flushPromises();

    await vi.advanceTimersByTimeAsync(15_000);
    expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("error");
    expect(wrapper.get("[role='status']").text()).toContain("iframe 加载超时");
    expect(wrapper.find("iframe").exists()).toBe(false);
    wrapper.unmount();
  });
});
