import { describe, expect, it } from "vitest";
import {
  buildFlockBatchCases,
  classifyFlockFailure,
  randomCargo,
} from "@/scripts/batch-flock-stress";
import {
  FLOCK_LIMITS,
  fitsFlockTrailerCargo,
} from "@/lib/constants/flock-limits";

function mulberry32(seed: number): () => number {
  return () => {
    let t = (seed += 0x6d2b79f5);
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

describe("buildFlockBatchCases", () => {
  it("生成样例且 ZIP/货物均在 Flock 合法范围（含线性英尺）", () => {
    const cases = buildFlockBatchCases(20, 42);
    expect(cases).toHaveLength(20);
    const zips = new Set([
      "02109",
      "94102",
      "60611",
      "78701",
      "21230",
      "19106",
      "15222",
      "30326",
      "90212",
      "90248",
    ]);
    for (const c of cases) {
      expect(zips.has(c.pickupZip)).toBe(true);
      expect(zips.has(c.deliveryZip)).toBe(true);
      expect(c.pickupZip).not.toBe(c.deliveryZip);
      expect(c.palletCount).toBeGreaterThanOrEqual(FLOCK_LIMITS.palletCount.min);
      expect(c.palletCount).toBeLessThanOrEqual(FLOCK_LIMITS.palletCount.max);
      expect(c.totalWeightLb).toBeLessThanOrEqual(FLOCK_LIMITS.totalWeightLbMax);
      expect(c.lengthIn).toBeLessThanOrEqual(FLOCK_LIMITS.dimIn.lengthMax);
      expect(c.widthIn).toBeLessThanOrEqual(FLOCK_LIMITS.dimIn.widthMax);
      expect(c.heightIn).toBeLessThanOrEqual(FLOCK_LIMITS.dimIn.heightMax);
      expect(
        fitsFlockTrailerCargo({
          palletCount: c.palletCount,
          lengthIn: c.lengthIn,
          widthIn: c.widthIn,
        }),
      ).toBe(true);
    }
  });
});

describe("randomCargo", () => {
  it("不生成触发 Linear feet 超限的组合", () => {
    const rng = mulberry32(99);
    for (let i = 0; i < 50; i += 1) {
      const c = randomCargo(rng);
      expect(fitsFlockTrailerCargo(c)).toBe(true);
    }
  });
});

describe("classifyFlockFailure", () => {
  it("识别限流", () => {
    expect(classifyFlockFailure("Too many quote requests, try again later")).toBe(
      "rate_limit",
    );
  });
});
