import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { afterEach, expect, test, vi } from "vitest";

import { ReviewWorkbenchDetailScreen } from "@/features/reviews/review-workbench-detail";

const pushMock = vi.fn();

vi.mock("next/navigation", () => ({
  useRouter: () => ({
    push: pushMock,
  }),
}));

function createOrderDetailPayload(
  orderId = 101,
  options: { pendingManualConfirm?: boolean } = {},
) {
  return {
    mode: "proxy",
    data: {
      orderId,
      workflowId: `wf-${orderId}`,
      customerLevel: "mid",
      serviceMode: "semi_pro",
      status: "waiting_review",
      statusMeta: {
        label: "待审核",
        tone: "warning",
      },
      currentStep: "review",
      currentStepLabel: "人工审核",
      modelId: 101,
      poseId: 202,
      garmentAssetId: 303,
      sceneRefAssetId: 404,
      currentRevisionAssetId: null,
      currentRevisionVersion: null,
      latestRevisionAssetId: null,
      latestRevisionVersion: null,
      revisionCount: 0,
      reviewTaskStatus: "pending",
      pendingManualConfirm: options.pendingManualConfirm ?? false,
      createdAt: "2026-03-27T00:00:00Z",
      updatedAt: "2026-03-27T00:10:00Z",
      finalAsset: null,
      finalAssetState: {
        kind: "business-empty",
        title: "最终图暂未生成",
        description: "当前订单还没有可展示的最终结果。",
      },
      assets: [
        {
          id: 11,
          orderId,
          type: "fusion",
          stepName: "fusion",
          stepLabel: "融合",
          label: "融合产物",
          uri: "mock://fusion-preview",
          metadata: null,
          createdAt: "2026-03-27T00:09:00Z",
          isMock: true,
        },
      ],
      assetGalleryState: {
        kind: "ready",
      },
      hasMockAssets: true,
    },
  };
}

function createWorkflowPayload(
  orderId = 101,
  options: { pendingManualConfirm?: boolean } = {},
) {
  return {
    mode: "proxy",
    data: {
      orderId,
      workflowId: `wf-${orderId}`,
      workflowType: "mid_end",
      status: "waiting_review",
      currentRevisionAssetId: null,
      currentRevisionVersion: null,
      latestRevisionAssetId: null,
      latestRevisionVersion: null,
      revisionCount: 0,
      reviewTaskStatus: "pending",
      pendingManualConfirm: options.pendingManualConfirm ?? false,
      statusMeta: {
        label: "待审核",
        tone: "warning",
      },
      currentStep: "review",
      currentStepLabel: "人工审核",
      createdAt: "2026-03-27T00:00:00Z",
      updatedAt: "2026-03-27T00:10:00Z",
      steps: [
        {
          id: 1,
          workflowRunId: 9001,
          name: "review",
          label: "人工审核",
          status: "waiting",
          statusMeta: {
            label: "等待人工处理",
            tone: "warning",
          },
          input: null,
          output: null,
          errorMessage: null,
          startedAt: "2026-03-27T00:09:00Z",
          endedAt: null,
          containsMockAssets: true,
          mockAssetUris: ["mock://fusion-preview"],
          isCurrent: true,
          isFailed: false,
        },
      ],
      stepTimelineState: {
        kind: "ready",
      },
      failureCount: 0,
      hasMockAssets: true,
    },
  };
}

function createFetchMock(options: { pendingManualConfirm?: boolean } = {}) {
  return vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
    const url = typeof input === "string" ? input : input.toString();

    if (url === "/api/orders/101") {
      return new Response(JSON.stringify(createOrderDetailPayload(101, options)), {
        status: 200,
        headers: { "content-type": "application/json" },
      });
    }

    if (url === "/api/workflows/101") {
      return new Response(JSON.stringify(createWorkflowPayload(101, options)), {
        status: 200,
        headers: { "content-type": "application/json" },
      });
    }

    if (url === "/api/reviews/101/submit" && init?.method === "POST") {
      return new Response(
        JSON.stringify({
          mode: "proxy",
          data: {
            orderId: 101,
            workflowId: "wf-101",
            decision: "approve",
            decisionMeta: {
              label: "通过",
              tone: "success",
            },
            status: "queued",
          },
        }),
        {
          status: 200,
          headers: { "content-type": "application/json" },
        },
      );
    }

    if (url === "/api/orders/101/revisions" && init?.method === "POST") {
      return new Response(
        JSON.stringify({
          mode: "proxy",
          data: {
            orderId: 101,
            workflowId: "wf-101",
            assetId: 501,
            parentAssetId: 11,
            rootAssetId: 11,
            versionNo: 1,
            reviewTaskStatus: "revision_uploaded",
            latestRevisionAssetId: 501,
            revisionCount: 1,
          },
        }),
        {
          status: 201,
          headers: { "content-type": "application/json" },
        },
      );
    }

    if (url === "/api/reviews/101/confirm-revision" && init?.method === "POST") {
      return new Response(
        JSON.stringify({
          mode: "proxy",
          data: {
            orderId: 101,
            workflowId: "wf-101",
            revisionAssetId: 501,
            decision: "approve",
            decisionMeta: {
              label: "通过",
              tone: "success",
            },
            status: "submitted",
          },
        }),
        {
          status: 200,
          headers: { "content-type": "application/json" },
        },
      );
    }

    throw new Error(`Unhandled fetch: ${url}`);
  });
}

afterEach(() => {
  vi.unstubAllGlobals();
  pushMock.mockReset();
});

test("requires a comment before rerun_face submission in detail view", async () => {
  const fetchMock = createFetchMock();
  vi.stubGlobal("fetch", fetchMock);

  render(<ReviewWorkbenchDetailScreen orderId={101} />);

  await screen.findByRole("heading", { level: 1, name: "订单 #101" });

  fireEvent.click(screen.getByRole("button", { name: "重跑 Face" }));

  expect(await screen.findByText("请填写审核备注")).toBeInTheDocument();
  expect(fetchMock).not.toHaveBeenCalledWith(
    "/api/reviews/101/submit",
    expect.anything(),
  );
});

test("submits approve then returns to the workbench list", async () => {
  const fetchMock = createFetchMock();
  vi.stubGlobal("fetch", fetchMock);

  render(<ReviewWorkbenchDetailScreen orderId={101} />);

  await screen.findByRole("heading", { level: 1, name: "订单 #101" });

  fireEvent.click(screen.getByRole("button", { name: "审核通过" }));

  await waitFor(() => {
    expect(fetchMock).toHaveBeenCalledWith(
      "/api/reviews/101/submit",
      expect.objectContaining({
        method: "POST",
      }),
    );
  });

  await waitFor(() => {
    expect(pushMock).toHaveBeenCalledWith("/reviews/workbench");
  });
});

test("registers a manual revision asset from detail view", async () => {
  const fetchMock = createFetchMock();
  vi.stubGlobal("fetch", fetchMock);

  render(<ReviewWorkbenchDetailScreen orderId={101} />);

  await screen.findByRole("heading", { level: 1, name: "订单 #101" });

  fireEvent.change(screen.getByLabelText("修订稿 URI"), {
    target: { value: "mock://manual-revision-v1" },
  });
  fireEvent.change(screen.getByLabelText("修订说明"), {
    target: { value: "人工修订第一版" },
  });
  fireEvent.click(screen.getByRole("button", { name: "登记人工修订稿" }));

  await waitFor(() => {
    expect(fetchMock).toHaveBeenCalledWith(
      "/api/orders/101/revisions",
      expect.objectContaining({
        method: "POST",
      }),
    );
  });
});

test("confirms an uploaded manual revision and returns to the workbench list", async () => {
  const fetchMock = createFetchMock({ pendingManualConfirm: true });
  vi.stubGlobal("fetch", fetchMock);

  render(<ReviewWorkbenchDetailScreen orderId={101} />);

  await screen.findByRole("heading", { level: 1, name: "订单 #101" });

  fireEvent.click(screen.getByRole("button", { name: "确认继续流水线" }));

  await waitFor(() => {
    expect(fetchMock).toHaveBeenCalledWith(
      "/api/reviews/101/confirm-revision",
      expect.objectContaining({
        method: "POST",
      }),
    );
  });

  await waitFor(() => {
    expect(pushMock).toHaveBeenCalledWith("/reviews/workbench");
  });
});
