import { readFile } from "node:fs/promises";
import { expect } from "e2e";
import { test, IOS } from "./t3-mobile.ts";
import { makeState, runPromise } from "./t3.ts";
import { MOBILE, MOBILE_T3_HOME } from "../e2e.config.ts";

test("iOS project models in existing threads and new-task drafts", IOS, async ({t3, app, screen, device}) => {
  await device.setAppearance("light");
  const a = await t3.project("Project A", {"opencode.jsonc": JSON.stringify({
    $schema: "https://opencode.ai/config.json",
    provider: {proof: {npm: "@ai-sdk/openai-compatible", name: "Project proof",
      options: {baseURL: "http://127.0.0.1:9/v1", apiKey: "synthetic"},
      models: {"project-only": {name: "Project Only Model", limit: {context: 32000, output: 4000}}}}}
  })});
  const b = await t3.project("Project B");
  await t3.thread({project: a, title: "A thread", messages: ["Fixture ready"]});
  await t3.thread({project: b, title: "B thread", messages: ["Fixture ready"]});
  const {cli} = makeState(MOBILE_T3_HOME, {T3CODE_PORT: String(MOBILE.serverPort)});
  await runPromise(cli(["thread", "start", a, "Fixture ready", "--title", "A worktree", "--provider", "devReplay", "--model", "multi-turn", "--worktree", "main", "--branch", "proof-worktree", "--wait", "--json"]));
  await t3.open();
  await screen.getByText("A thread", {exact: false}).first().waitFor({state: "visible", timeout: 120000});
  await app.screenshot("home-projects-and-threads");
  const pause = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
  const capture = async (label: string) => {
    for (let attempt = 0; attempt < 8; attempt++) {
      const first = await app.screenshot(label + "-stability-1");
      await pause(500);
      const second = await app.screenshot(label + "-stability-2");
      if ((await readFile(first)).equals(await readFile(second))) {
        await app.screenshot(label);
        return;
      }
    }
    throw new Error("Capture did not settle: " + label);
  };
  const outcomes: boolean[] = [];
  const search = async (label: string) => {
    await screen.getByRole("button", /Model and reasoning settings/).tap();
    await pause(1500);
    await screen.getByRole("button", /^(Model filters|Filter|Filters)$/i).tap();
    await screen.getByText("Provider", {exact: true}).tap();
    await screen.getByText("OpenCode", {exact: true}).tap();
    await pause(3000);
    await capture(label + "-opening-catalog");
    await screen.getByPlaceholder("Find a model").fill("Project Only Model");
    await pause(3000);
    await screen.getByPlaceholder("Find a model").press("Enter");
    await capture(label + "-model-search");
    outcomes.push((await screen.getByRole("button", /Project Only Model/).count()) > 0);
    await screen.getByRole("button", "Cancel thread settings").tap();
  };
  for (const [title, label] of [["A thread", "project-a-thread"], ["B thread", "project-b-isolation"], ["A worktree", "project-a-worktree"]]) {
    await screen.getByText(title, {exact: false}).first().tap();
    await pause(1000);
    await capture(label + "-context");
    await search(label);
    await device.back();
  }
  await screen.getByRole("button", "New chat").tap();
  await capture("new-task-project-chooser");
  await screen.getByRole("button", "Project A", {exact: true}).tap();
  await pause(1500);
  if ((await screen.getByText("Choose project", {exact: true}).count()) > 0) {
    await screen.getByRole("button", "Project A", {exact: true}).tap();
  }
  await screen.getByText("New thread", {exact: true}).waitFor({state: "visible"});
  await capture("project-a-new-task-draft-context");
  await search("project-a-new-task-draft");
  console.log("A thread, B isolation, A worktree, A new-task draft model present:", outcomes);
  await expect(outcomes).toEqual([true, false, true, true]);
});
