// @vitest-environment jsdom

import { renderHook } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { makeRegion } from "@/test/api-mock";
import type { PRMeta } from "./pr-meta";
import { useBumpPreview } from "./use-bump-preview";

function makeTestRegion(id: string) {
  return makeRegion({
    id,
    regionName: id,
    directoryPath: `envs/${id}`,
    currentTag: "tag",
    componentTags: { acs: "sha", vector: "v", vmagent: "m" },
  });
}

function makePRMeta(): PRMeta {
  return {
    branchName: "branch",
    commitMessage: "commit",
    prTitle: "title",
    prBody: "body",
    scope: "scope",
    shortTag: "short",
  };
}

describe("useBumpPreview", () => {
  it("blocks file-sync preview when source region is missing", async () => {
    const setError = vi.fn();
    const fetchMock = vi.fn();
    vi.stubGlobal("fetch", fetchMock);

    const { result } = renderHook(() =>
      useBumpPreview({
        mode: "file-sync",
        sourceRegionId: "",
        sourceHasDiff: true,
        selectedIds: new Set(["r1"]),
        setSelectedIds: vi.fn(),
        fileSyncTargetIds: ["r1"],
        regions: [makeTestRegion("r1")],
        component: "acs",
        targetTag: "tag",
        selectedSections: new Set(),
        updateVariants: true,
        selectedRegions: [makeTestRegion("r1")],
        selectedFiles: new Set(["config.yaml"]),
        setPreviewing: vi.fn(),
        setError,
        setFileSyncResult: vi.fn(),
        setFileSyncFailures: vi.fn(),
        setPreviewTokenId: vi.fn(),
        setFileSyncSummary: vi.fn(),
        setImageTagCheckApplicable: vi.fn(),
        setPrMeta: vi.fn(),
        setFileSyncDiffs: vi.fn(),
        setDiffs: vi.fn(),
        setSkippedRegions: vi.fn(),
        setStep: vi.fn(),
        buildImagePRMeta: () => makePRMeta(),
        buildFileSyncPRMeta: () => makePRMeta(),
      })
    );

    await result.current();

    expect(setError).toHaveBeenCalledWith("Select a source region first");
    expect(fetchMock).not.toHaveBeenCalled();
  });

  it("previews image bump successfully", async () => {
    const setPreviewing = vi.fn();
    const setError = vi.fn();
    const setDiffs = vi.fn();
    const setPrMeta = vi.fn();
    const setStep = vi.fn();

    vi.stubGlobal(
      "fetch",
      vi.fn(async () =>
        new Response(
          JSON.stringify({
            ok: true,
            data: { diffs: [{ regionId: "r1", filePath: "f", oldTag: "o", newTag: "n", patch: "p" }] },
          }),
          { status: 200, headers: { "Content-Type": "application/json" } }
        )
      )
    );

    const expectedMeta = makePRMeta();

    const { result } = renderHook(() =>
      useBumpPreview({
        mode: "image",
        sourceRegionId: "",
        sourceHasDiff: false,
        selectedIds: new Set(["r1"]),
        setSelectedIds: vi.fn(),
        fileSyncTargetIds: [],
        regions: [makeTestRegion("r1")],
        component: "acs",
        targetTag: "tag",
        selectedSections: new Set(),
        updateVariants: true,
        selectedRegions: [makeTestRegion("r1")],
        selectedFiles: new Set(),
        setPreviewing,
        setError,
        setFileSyncResult: vi.fn(),
        setFileSyncFailures: vi.fn(),
        setPreviewTokenId: vi.fn(),
        setFileSyncSummary: vi.fn(),
        setImageTagCheckApplicable: vi.fn(),
        setPrMeta,
        setFileSyncDiffs: vi.fn(),
        setDiffs,
        setSkippedRegions: vi.fn(),
        setStep,
        buildImagePRMeta: () => expectedMeta,
        buildFileSyncPRMeta: () => expectedMeta,
      })
    );

    await result.current();

    expect(setPreviewing).toHaveBeenCalledWith(true);
    expect(setError).toHaveBeenCalledWith("");
    expect(setDiffs).toHaveBeenCalled();
    expect(setPrMeta).toHaveBeenCalledWith(expectedMeta);
    expect(setStep).toHaveBeenCalledWith("preview");
    expect(setPreviewing).toHaveBeenLastCalledWith(false);
  });
});
