/**
 * @file Workspace.laneCwd.test.tsx
 * @description The console's working directory must be the selected lane's own
 * `cwd` — on first paint (the page auto-selects the first lane) and after every
 * lane switch. A stale cwd is not cosmetic: `RunSetup` submits it verbatim, so
 * the run would be started in the previously selected lane's folder.
 * @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
 */

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { render, act, screen, fireEvent } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import i18n from "i18next";

// Hoisted: `vi.mock`'s factory is lifted above the module body, so the
// fixtures it reads have to be lifted with it.
const { HOME, LANE_A, LANE_B } = vi.hoisted(() => {
  const laneStub = (id: number, cwd: string) => ({
    id,
    title: `lane-${id}`,
    cwd,
    branch: null,
    kind: "adopted",
    source_repo: null,
    pipeline: "default",
    session_id: null,
    run_id: null,
    stage: "idle",
    stage_since: null,
    status: "idle",
    gate_decision: null,
    ci_status: null,
    needs_action: null,
    links: {},
    stages: {},
    notes: null,
    pipeline_name: "Default",
    pipeline_nodes: [],
    progress: 0,
    stage_seconds: null,
    last_event_seconds: null,
    liveness: "idle",
    detected_stage: null,
    detected_signal: null,
    slot: null,
    ports: {},
    active_feature_id: null,
  });
  return {
    HOME: { kind: "home", path: "/Users/tester", label: "Home" },
    LANE_A: laneStub(1, "/workspace/alpha"),
    LANE_B: laneStub(2, "/workspace/beta"),
  };
});

vi.mock("../../lib/api", async (importOriginal) => {
  const actual = await importOriginal<Record<string, unknown>>();
  const r = (value: unknown) => vi.fn().mockResolvedValue(value);
  return {
    ...actual,
    api: {
      run: {
        list: r({ items: [] }),
        history: r({ items: [] }),
        binary: r({ found: true, path: "/usr/bin/claude" }),
        cwds: r({ items: [HOME] }),
        files: r({ items: [] }),
        start: r({ id: "run-1", status: "running" }),
        get: r({ id: "run-1", status: "running" }),
      },
      lanes: {
        list: r({
          lanes: [LANE_A, LANE_B],
          counts: { total: 2, running: 0, needs_you: 0, dead: 0 },
        }),
        pipelines: r({ pipelines: [] }),
        git: r({ available: false }),
        runtime: r({ up: false, ports: {}, lastError: null }),
        features: { list: r({ features: [] }), show: r({ feature: null }) },
        proof: { list: r({ features: [] }), imageUrl: () => "" },
      },
      sessions: { list: r({ sessions: [], total: 0, limit: 50, offset: 0 }) },
    },
  };
});

vi.mock("../../lib/eventBus", () => ({
  eventBus: {
    subscribe: () => () => {},
    publish: () => {},
    onConnection: () => () => {},
    connected: true,
    setConnected: () => {},
  },
}));

import { Workspace } from "../Workspace";

class ObserverStub {
  observe() {}
  unobserve() {}
  disconnect() {}
  takeRecords() {
    return [];
  }
}
globalThis.ResizeObserver =
  globalThis.ResizeObserver || (ObserverStub as unknown as typeof ResizeObserver);

async function settle() {
  await act(async () => {
    await new Promise((r) => setTimeout(r, 0));
    await new Promise((r) => setTimeout(r, 0));
  });
}

function cwdInput(): HTMLInputElement {
  return screen.getByPlaceholderText(i18n.t("run:fields.cwdPlaceholder")) as HTMLInputElement;
}

beforeEach(() => {
  i18n.changeLanguage("en");
});

afterEach(() => {
  vi.clearAllMocks();
});

describe("Workspace — the console cwd follows the selected lane", () => {
  it("shows the auto-selected first lane's cwd on load, not the home default", async () => {
    render(
      <MemoryRouter initialEntries={["/run"]}>
        <Workspace />
      </MemoryRouter>
    );
    await settle();
    expect(cwdInput().value).toBe(LANE_A.cwd);
  });

  it("swaps the cwd when another lane is selected in the strip", async () => {
    render(
      <MemoryRouter initialEntries={["/run"]}>
        <Workspace />
      </MemoryRouter>
    );
    await settle();

    fireEvent.click(screen.getByTestId("lane-tile-2"));
    await settle();
    expect(cwdInput().value).toBe(LANE_B.cwd);

    fireEvent.click(screen.getByTestId("lane-tile-1"));
    await settle();
    expect(cwdInput().value).toBe(LANE_A.cwd);
  });
});
