// @vitest-environment jsdom

import { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { MemoryRouter } from "@/lib/router";

// Mock all generator panels — Phase 10 does not rewrite any generator
// internals, and the real panels hit network. We only care that the
// StudioWorkshopDetail shell maps slugs to the right generator.
vi.mock("../components/DiagramGeneratePanel", () => ({
  DiagramGeneratePanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-diagram-panel">diagram:{companyId}</div>
  ),
}));
vi.mock("../components/IconGeneratePanel", () => ({
  IconGeneratePanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-icon-panel">icon:{companyId}</div>
  ),
}));
vi.mock("../components/WallpaperGeneratePanel", () => ({
  WallpaperGeneratePanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-wallpaper-panel">wallpaper:{companyId}</div>
  ),
}));
vi.mock("../components/SocialPostPanel", () => ({
  SocialPostPanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-social-panel">social:{companyId}</div>
  ),
}));
vi.mock("../components/DocumentGeneratePanel", () => ({
  DocumentGeneratePanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-document-panel">document:{companyId}</div>
  ),
}));
vi.mock("../components/BrandKitPanel", () => ({
  BrandKitPanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-brand-panel">brand:{companyId}</div>
  ),
}));
vi.mock("../components/ConvertPanel", () => ({
  ConvertPanel: ({ companyId }: { companyId: string }) => (
    <div data-testid="mock-convert-panel">convert:{companyId}</div>
  ),
}));
vi.mock("../components/ThemeSeedInput", () => ({
  ThemeSeedInput: () => <div data-testid="mock-theme-seed">seed</div>,
}));
vi.mock("../components/ThemePaletteGrid", () => ({
  ThemePaletteGrid: () => <div />,
}));
vi.mock("../components/ThemePreviewPanel", () => ({
  ThemePreviewPanel: () => <div />,
}));
vi.mock("../components/ThemeExportTabs", () => ({
  ThemeExportTabs: () => <div />,
}));
vi.mock("../components/ThemeApplyConfirmDialog", () => ({
  ThemeApplyConfirmDialog: () => <div />,
}));
vi.mock("../hooks/useContentJob", () => ({
  useContentJob: () => ({
    status: "idle",
    resultAssetId: null,
    submit: () => {},
  }),
}));

// Stub CompanyContext so the router's Link/useNavigate wrappers work
// without a CompanyProvider — IconRail's test uses the same stub.
vi.mock("@/context/CompanyContext", () => ({
  useCompany: () => ({
    companies: [],
    selectedCompanyId: "acme",
    selectedCompany: { id: "acme", issuePrefix: "NEX" },
    selectionSource: "bootstrap" as const,
    loading: false,
    error: null,
    setSelectedCompanyId: () => {},
    reloadCompanies: async () => {},
    createCompany: async () => {
      throw new Error("not implemented in test stub");
    },
  }),
}));

// Load after the mocks are wired.
import { StudioWorkshopDetail } from "./StudioWorkshopDetail";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;

describe("StudioWorkshopDetail", () => {
  let container: HTMLDivElement;
  let root: ReturnType<typeof createRoot> | null = null;

  beforeEach(() => {
    container = document.createElement("div");
    document.body.appendChild(container);
    root = null;
  });

  afterEach(() => {
    if (root) {
      act(() => {
        root!.unmount();
      });
      root = null;
    }
    if (container.parentNode) container.remove();
  });

  function render(slug: string, initialPath = `/NEX/content-studio/${slug}`) {
    root = createRoot(container);
    act(() => {
      root!.render(
        <MemoryRouter initialEntries={[initialPath]}>
          <StudioWorkshopDetail slug={slug} />
        </MemoryRouter>,
      );
    });
  }

  it("renders the diagrams workshop with the diagram generator in the params column", () => {
    render("diagrams");
    expect(container.querySelector("[data-testid='mock-diagram-panel']")).not.toBeNull();
    expect(container.textContent).toContain("STUDIO");
    expect(container.textContent).toContain("DIAGRAMS");
  });

  it("renders the convert workshop with the ConvertPanel folded in", () => {
    render("convert");
    expect(container.querySelector("[data-testid='mock-convert-panel']")).not.toBeNull();
    expect(container.textContent).toContain("CONVERT");
  });

  it("renders each non-theme generator for its corresponding slug", () => {
    const cases = [
      ["diagrams", "mock-diagram-panel"],
      ["icons", "mock-icon-panel"],
      ["wallpapers", "mock-wallpaper-panel"],
      ["documents", "mock-document-panel"],
      ["brand-kits", "mock-brand-panel"],
      ["social", "mock-social-panel"],
      ["convert", "mock-convert-panel"],
    ] as const;
    for (const [slug, testid] of cases) {
      render(slug);
      expect(
        container.querySelector(`[data-testid='${testid}']`),
        `slug ${slug} should render ${testid}`,
      ).not.toBeNull();
      act(() => {
        root!.unmount();
      });
      root = null;
    }
  });

  it("renders the theme workshop body (theme seed input visible)", () => {
    render("themes");
    expect(container.querySelector("[data-testid='mock-theme-seed']")).not.toBeNull();
  });

  it("renders a 404 fallback for an unknown slug", () => {
    render("not-a-real-workshop", "/NEX/content-studio/not-a-real-workshop");
    expect(container.querySelector("[data-testid='workshop-not-found']")).not.toBeNull();
    expect(container.textContent).toContain("Unknown workshop");
    expect(container.textContent).toContain("not-a-real-workshop");
  });

  it("renders the action bar with Save, Export, and Send to Assistant", () => {
    render("diagrams");
    const bar = container.querySelector("[data-testid='workshop-action-bar']") as HTMLElement;
    expect(bar).not.toBeNull();
    const labels = Array.from(bar.querySelectorAll("button")).map((b) => b.textContent?.trim());
    expect(labels).toContain("Save");
    expect(labels).toContain("Export");
    expect(labels).toContain("Send to Assistant");
  });

  it("uses the two-column grid layout on large screens", () => {
    render("diagrams");
    const grid = container.querySelector("[data-testid='workshop-detail-grid']") as HTMLElement;
    expect(grid).not.toBeNull();
    expect(grid.className).toContain("lg:grid-cols-");
  });

  it("surfaces a ?prompt=... query param as a visible chip", () => {
    render("wallpapers", "/NEX/content-studio/wallpapers?prompt=forest%20at%20dusk");
    const chip = container.querySelector("[data-testid='workshop-prefilled-prompt']");
    expect(chip).not.toBeNull();
    expect(chip?.textContent).toContain("forest at dusk");
  });

  it("renders a back button with a 'Back to Studio' aria-label", () => {
    render("diagrams");
    const back = container.querySelector("button[aria-label='Back to Studio']");
    expect(back).not.toBeNull();
  });
});
