import { renderHook, act } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import type { CreateFlowState } from "../../../app/(app)/create/types";
import { useTemplateReviewActions } from "../../../app/(app)/create/hooks/useTemplateReviewActions";
import { loadTemplateReviewBySlug } from "../../../lib/create/loadTemplateReviewBySlug";

vi.mock("../../../lib/create/loadTemplateReviewBySlug", () => ({
  loadTemplateReviewBySlug: vi.fn(),
}));

const templateBody = {
  sections: [
    {
      categoryName: "Communication",
      entries: [{ title: "Signal" }],
    },
  ],
};

const loadedTemplate = {
  ok: true as const,
  template: {
    id: "t1",
    slug: "mutual-aid-mondays",
    title: "Mutual Aid Mondays",
    category: null,
    description: null,
    body: templateBody,
    sortOrder: 0,
    featured: false,
  },
};

describe("useTemplateReviewActions", () => {
  const router = { push: vi.fn() };
  const updateState = vi.fn();
  const markCreateFlowInteraction = vi.fn();
  let applied: CreateFlowState | undefined;
  const replaceState = vi.fn(
    (updater: (_prev: CreateFlowState) => CreateFlowState) => {
      applied = updater({});
    },
  );

  beforeEach(() => {
    vi.mocked(loadTemplateReviewBySlug).mockReset();
    vi.mocked(loadTemplateReviewBySlug).mockResolvedValue(loadedTemplate);
    router.push.mockReset();
    updateState.mockReset();
    markCreateFlowInteraction.mockReset();
    replaceState.mockClear();
    applied = undefined;
  });

  function renderActions(
    state: CreateFlowState,
    fromCreateWizard = false,
  ) {
    return renderHook(() =>
      useTemplateReviewActions({
        pathname: "/create/review-template/mutual-aid-mondays",
        state,
        updateState,
        replaceState,
        router,
        fromCreateWizard,
        markCreateFlowInteraction,
      }),
    );
  }

  it("direct Use without changes walks identity from community-name", async () => {
    const { result } = renderActions({});

    await act(async () => {
      await result.current.handleUseWithoutChanges();
    });

    expect(markCreateFlowInteraction).toHaveBeenCalled();
    expect(router.push).toHaveBeenCalledWith("/create/community-name");
    expect(applied?.pendingTemplateAction).toEqual({
      slug: "mutual-aid-mondays",
      mode: "useWithoutChanges",
    });
  });

  it("direct Use without changes ignores a leftover draft title", async () => {
    replaceState.mockImplementation(
      (updater: (_prev: CreateFlowState) => CreateFlowState) => {
        applied = updater({
          title: "Neighborhood",
          communityContext: "Stale description",
          currentStep: "confirm-stakeholders",
        });
      },
    );
    const { result } = renderActions({ title: "Neighborhood" });

    await act(async () => {
      await result.current.handleUseWithoutChanges();
    });

    expect(router.push).toHaveBeenCalledWith("/create/community-name");
    expect(applied?.title).toBeUndefined();
    expect(applied?.communityContext).toBeUndefined();
    expect(applied?.currentStep).toBeUndefined();
    expect(applied?.pendingTemplateAction?.mode).toBe("useWithoutChanges");
  });

  it("in-flow Use without changes skips identity and keeps the community name", async () => {
    replaceState.mockImplementation(
      (updater: (_prev: CreateFlowState) => CreateFlowState) => {
        applied = updater({
          title: "Neighborhood",
          communityContext: "We meet weekly",
          templateReviewEntryFromCreateFlow: true,
        });
      },
    );
    const { result } = renderActions(
      { title: "Neighborhood", templateReviewEntryFromCreateFlow: true },
      true,
    );

    await act(async () => {
      await result.current.handleUseWithoutChanges();
    });

    expect(router.push).toHaveBeenCalledWith("/create/confirm-stakeholders");
    expect(applied?.title).toBe("Neighborhood");
    expect(applied?.communityContext).toBe("We meet weekly");
    expect(applied?.pendingTemplateAction).toBeUndefined();
    expect(applied?.templateReviewBackSlug).toBe("mutual-aid-mondays");
  });
});
