import { describe, expect, it } from "vitest";

if (!(globalThis as any).document) {
  const { Window } = await import("happy-dom");
  const window = new Window();
  (globalThis as any).window = window;
  (globalThis as any).document = window.document;
  Object.defineProperty(globalThis, "navigator", {
    configurable: true,
    value: window.navigator,
  });
  (globalThis as any).Node = window.Node;
  (globalThis as any).Element = window.Element;
  (globalThis as any).HTMLElement = window.HTMLElement;
  (globalThis as any).SVGElement = window.SVGElement;
  (globalThis as any).Event = window.Event;
  (globalThis as any).CustomEvent = window.CustomEvent;
  (globalThis as any).MouseEvent = window.MouseEvent;
  (globalThis as any).KeyboardEvent = window.KeyboardEvent;
  (globalThis as any).getComputedStyle = window.getComputedStyle.bind(window);
}

globalThis.requestAnimationFrame = ((cb: FrameRequestCallback) => {
  cb(0);
  return 1;
}) as typeof globalThis.requestAnimationFrame;
globalThis.cancelAnimationFrame = (() => {}) as typeof globalThis.cancelAnimationFrame;

const { nextTick } = await import("vue");
const { createTerminalApp } = await import("@simon_he/vue-tui");
const { DimSdkShell, createDimSdkRouter } = await import("../src/dimsdk/index.ts");
const { createErrorGoatChainAgent: createErrorDimSdkAgent } =
  await import("../src/dimsdk/core/agents/error.ts");

async function flushApp(app: { scheduler: { flush: () => void } }) {
  await nextTick();
  await nextTick();
  app.scheduler.flush();
}

function snapshotText(app: { terminal: { snapshot: () => { lines: string[] } } }): string {
  return app.terminal.snapshot().lines.join("\n");
}

describe("dimsdk chat chrome e2e", () => {
  it("renders updated token usage and context percent when the chat store changes", async () => {
    const previousDimcodeTest = process.env.DIMCODE_TEST;
    let storeRef: any;
    const app = createTerminalApp({
      cols: 120,
      rows: 36,
      component: DimSdkShell as never,
      props: {
        toolRunner: async () => ({
          id: "tool",
          output: "disabled",
          status: "error" as const,
        }),
        context: {
          system: "You are best-agent running in a chrome update test.",
          cwd: ".",
          env: { DIMCODE_VERSION: "0.0.0", DIMCODE_TEST: "1" },
        },
        agent: createErrorDimSdkAgent(new Error("Agent disabled in chrome update test.")),
        onStoreCreated: (store: any) => {
          storeRef = store;
          store.state.sessionId = "thread_chat_chrome";
          store.state.config.context_window = 4000;
          store.state.messages = [
            {
              id: "assistant_seed",
              role: "assistant",
              parts: [{ type: "markdown", markdown: "Seed assistant reply" }],
            },
          ];
        },
      },
      defaultStyle: { bg: "black", fg: "whiteBright" },
    });

    try {
      process.env.DIMCODE_TEST = "1";
      app.app.use(createDimSdkRouter({ initialRoute: "chat", mode: "cli" }) as never);
      app.mount();
      await flushApp(app);

      expect(snapshotText(app)).toContain("0 tok");

      storeRef.applyUsageFromSession({
        promptTokens: 1260,
        completionTokens: 71,
        totalTokens: 1331,
      });
      storeRef.applyLastRequestBudget({
        autoBudgetOutcome: "not-needed",
        estimatedInputTokens: 1331,
        inputBudgetTokens: 4000,
        thresholdTokens: 4000,
        maxInputTokens: 4000,
        triggerRatio: 1,
        updatedAtMs: Date.now(),
        usedAutoCompaction: false,
      });
      await flushApp(app);
      await flushApp(app);

      const screen = snapshotText(app);
      expect(screen).toContain("1,331 tok");
      expect(screen).toContain("33%");
    } finally {
      if (previousDimcodeTest == null) {
        delete process.env.DIMCODE_TEST;
      } else {
        process.env.DIMCODE_TEST = previousDimcodeTest;
      }
      app.dispose();
    }
  });
});
