import { render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { KEYS } from "../data/mock/keys";
import type { Member } from "../domain/types";
import { I18nProvider } from "../i18n/I18nContext";
import { FirstRunBar } from "../components/layout/FirstRunBar";
import { SidebarNav } from "../components/layout/SidebarNav";
import { FirstRunProvider } from "./FirstRunContext";
import { isFirstRunAllowedPath } from "./paths";

const harness = vi.hoisted(() => ({
  member: null as Member | null,
  updateProfile: vi.fn(async (patch: { onboarding_status?: string }) => {
    if (harness.member) {
      harness.member = { ...harness.member, ...patch };
    }
    return harness.member;
  }),
  accounts: [] as { id: string; is_usable: boolean }[],
}));

vi.mock("../auth/AuthContext", () => ({
  useAuth: () => ({
    member: harness.member,
    loading: false,
    updateProfile: harness.updateProfile,
  }),
}));

vi.mock("../data/DataContext", () => ({
  useRepos: () => ({
    accounts: { list: async () => harness.accounts },
  }),
}));

function member(over: Partial<Member> = {}): Member {
  return {
    tenant_id: "default",
    uid: "1000001",
    email: "n@example.com",
    display_name: "New",
    roles: ["member"],
    email_verified: true,
    ...over,
  };
}

function renderBar(path = "/app/today") {
  return render(
    <MemoryRouter initialEntries={[path]}>
      <I18nProvider>
        <FirstRunProvider>
          <FirstRunBar />
          <SidebarNav />
          <Routes>
            <Route path="/app/today" element={<div>today-page</div>} />
            <Route path="/app/crew" element={<div>crew-page</div>} />
            <Route path="/app/studio" element={<div>studio-page</div>} />
          </Routes>
        </FirstRunProvider>
      </I18nProvider>
    </MemoryRouter>,
  );
}

describe("FirstRunBar", () => {
  beforeEach(() => {
    localStorage.setItem(KEYS.uiPrefs, JSON.stringify({ locale: "zh-TW", currency: "TWD", theme: "system" }));
    harness.member = member();
    harness.updateProfile.mockClear();
    harness.accounts = [];
  });

  it("only asks a new member to connect Threads", async () => {
    renderBar();
    expect(await screen.findByRole("region", { name: "第一次設定" })).toBeTruthy();
    expect(screen.getByRole("link", { name: "連 Threads 帳號" }).getAttribute("href")).toBe("/app/crew");
    expect(screen.queryByText("整理品牌與產品")).toBeNull();
    expect(screen.queryByText("建立每日巡邏")).toBeNull();
    expect(screen.queryByText("看第一筆商機")).toBeNull();
    expect(screen.getByRole("link", { name: "今日" })).toBeTruthy();
    expect(screen.getByRole("link", { name: "帳號" })).toBeTruthy();
    expect(screen.queryByRole("link", { name: "品牌" })).toBeNull();
    expect(screen.queryByRole("link", { name: "創作" })).toBeNull();
  });

  it("lets a new member open patrol setup without being sent back", () => {
    expect(isFirstRunAllowedPath("/app/radar/watches")).toBe(true);
    expect(isFirstRunAllowedPath("/app/radar/opportunities")).toBe(true);
    expect(isFirstRunAllowedPath("/app/studio")).toBe(false);
  });

  it("sends people back to connect if they open another feature", async () => {
    renderBar("/app/studio");
    expect(await screen.findByText("crew-page")).toBeTruthy();
    expect(screen.queryByText("studio-page")).toBeNull();
  });

  it("completes after a Threads account is connected", async () => {
    harness.accounts = [{ id: "acc-1", is_usable: true }];
    renderBar();
    await waitFor(() => expect(harness.updateProfile).toHaveBeenCalledWith({ onboarding_status: "completed" }));
  });

  it("does not show for members who already finished", () => {
    harness.member = member({ onboarding_status: "completed" });
    renderBar();
    expect(screen.queryByRole("region", { name: "第一次設定" })).toBeNull();
    expect(screen.getByRole("link", { name: "名單" })).toBeTruthy();
    expect(screen.getByRole("link", { name: "今日" })).toBeTruthy();
  });
});
