import { beforeEach, describe, expect, it, vi } from "vitest";
import { submitQuote } from "@/modules/quote/orchestrator";

vi.mock("@/modules/cache/redis-cache", () => ({
  getL2: vi.fn(),
}));

vi.mock("@/modules/quote/idempotency", () => ({
  checkIdempotency: vi.fn(),
  saveIdempotency: vi.fn(),
}));

vi.mock("@/modules/quote/quote-id", () => ({
  generateQuoteId: vi.fn(),
  handleQuoteIdConflict: vi.fn(),
  isQuoteIdUniqueConflict: vi.fn(),
}));

vi.mock("@/modules/quote/rpa-queue", () => ({
  enqueueQuoteJob: vi.fn(),
}));

vi.mock("@/modules/pricing/engine", () => ({
  getMarkupPercent: vi.fn().mockResolvedValue(0),
  applyMarkupToQuotes: vi.fn((quotes: unknown[]) => quotes),
}));

vi.mock("@/modules/metrics/collector", () => ({
  safeRecord: vi.fn(),
  recordPostTotal: vi.fn().mockResolvedValue(undefined),
  recordCacheHit: vi.fn().mockResolvedValue(undefined),
  recordPostDone: vi.fn().mockResolvedValue(undefined),
  recordRpaTriggered: vi.fn().mockResolvedValue(undefined),
  markQuoteStarted: vi.fn().mockResolvedValue(undefined),
}));

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

import { getL2 } from "@/modules/cache/redis-cache";
import { checkIdempotency } from "@/modules/quote/idempotency";
import { enqueueQuoteJob } from "@/modules/quote/rpa-queue";
import {
  MOTHERSHIP_DELIVERY_CONFIRMED,
  MOTHERSHIP_PICKUP_CONFIRMED,
} from "@/__tests__/fixtures/mothership-address";

const VALID_BODY = {
  request_id: "550e8400-e29b-41d4-a716-446655440000",
  customer_id: "CUST_001",
  pickup_address: {
    street: "1234 Warehouse Blvd",
    city: "Los Angeles",
    state: "CA",
    zip: "90001",
    place_id: "ChIJ_pickup",
    formatted_address: "1234 Warehouse Blvd, Los Angeles, CA 90001, USA",
    selected_from_suggestions: true,
    ...MOTHERSHIP_PICKUP_CONFIRMED,
  },
  delivery_address: {
    street: "5678 Distribution Dr",
    city: "Dallas",
    state: "TX",
    zip: "75201",
    place_id: "ChIJ_delivery",
    formatted_address: "5678 Distribution Dr, Dallas, TX 75201, USA",
    selected_from_suggestions: true,
    ...MOTHERSHIP_DELIVERY_CONFIRMED,
  },
  weight: { value: 500, unit: "lb" },
  dimensions: { length: 48, width: 40, height: 48, unit: "in" },
  pallet_count: 2,
  cargo_type: "general_freight",
};

describe("TC-108 L2 过期触发 RPA（task-112）", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.mocked(checkIdempotency).mockResolvedValue({ hit: false });
    vi.mocked(getL2).mockResolvedValue(null);
    vi.mocked(enqueueQuoteJob).mockResolvedValue(undefined);
  });

  it("L2 不存在（已过期/DEL）→ 触发 RPA 入队", async () => {
    const result = await submitQuote(VALID_BODY);

    expect(result.status).toBe("processing");
    expect(enqueueQuoteJob).toHaveBeenCalledTimes(1);
    expect(result.source_type).toBeUndefined();
  });

  it("L2 存在 → 不走 RPA", async () => {
    vi.mocked(getL2).mockResolvedValue({
      quotes: [
        {
          service_level: "standard",
          rate_option: "lowest",
          raw_freight: 320,
          surcharges: 0,
          raw_total: 320,
          carrier: "M",
          transit_days: "5",
          transit_description: "x",
        },
        {
          service_level: "standard",
          rate_option: "fastest",
          raw_freight: 365,
          surcharges: 0,
          raw_total: 365,
          carrier: "M",
          transit_days: "3",
          transit_description: "x",
        },
        {
          service_level: "guaranteed",
          rate_option: "lowest",
          raw_freight: 380,
          surcharges: 0,
          raw_total: 380,
          carrier: "M",
          transit_days: "4",
          transit_description: "x",
        },
        {
          service_level: "guaranteed",
          rate_option: "fastest",
          raw_freight: 410,
          surcharges: 0,
          raw_total: 410,
          carrier: "M",
          transit_days: "3",
          transit_description: "x",
        },
      ],
    });

    const result = await submitQuote(VALID_BODY);

    expect(result.status).toBe("done");
    expect(result.source_type).toBe("cache");
    expect(enqueueQuoteJob).not.toHaveBeenCalled();
  });
});
