/**
 * Flow 层级与任务兼容性测试
 *
 * **Validates: Requirements 2.2**
 *
 * Property 21: 对任意 Flow 类型和任务定义，当 Flow 包含的层不包含该任务所属层时，
 * 该任务不应出现在可选列表中；当 Flow 包含该任务所属层时，该任务应出现在可选列表中。
 */

import { describe, it, expect } from "vitest";
import { getFlowLayers } from "../pages/TaskConfig";

/* ------------------------------------------------------------------ */
/*  预期的 Flow 定义（来自设计文档）                                     */
/* ------------------------------------------------------------------ */

const EXPECTED_FLOWS: Record<string, string[]> = {
  api_ods: ["ODS"],
  api_ods_dwd: ["ODS", "DWD"],
  api_full: ["ODS", "DWD", "DWS", "INDEX"],
  ods_dwd: ["DWD"],
  dwd_dws: ["DWS"],
  dwd_dws_index: ["DWS", "INDEX"],
  dwd_index: ["INDEX"],
};

describe("getFlowLayers — Flow 层级与任务兼容性", () => {
  /* ---- 1. 每个已知 Flow 返回正确的层列表 ---- */
  it.each(Object.entries(EXPECTED_FLOWS))(
    "Flow '%s' 应返回 %j",
    (flowId, expectedLayers) => {
      expect(getFlowLayers(flowId)).toEqual(expectedLayers);
    },
  );

  /* ---- 2. 未知 Flow ID 返回空数组 ---- */
  it("未知 Flow ID 应返回空数组", () => {
    expect(getFlowLayers("unknown_flow")).toEqual([]);
    expect(getFlowLayers("")).toEqual([]);
    expect(getFlowLayers("API_FULL")).toEqual([]); // 大小写敏感
  });

  /* ---- 3. 所有 7 种 Flow 都有定义 ---- */
  it("应定义全部 7 种 Flow", () => {
    const allFlowIds = Object.keys(EXPECTED_FLOWS);
    expect(allFlowIds).toHaveLength(7);
    for (const flowId of allFlowIds) {
      expect(getFlowLayers(flowId).length).toBeGreaterThan(0);
    }
  });

  /* ---- 4. 层级互斥性验证 ---- */
  describe("层级互斥性", () => {
    it("api_ods 不包含 DWD / DWS / INDEX", () => {
      const layers = getFlowLayers("api_ods");
      expect(layers).not.toContain("DWD");
      expect(layers).not.toContain("DWS");
      expect(layers).not.toContain("INDEX");
    });

    it("ods_dwd 只包含 DWD，不包含 ODS / DWS / INDEX", () => {
      const layers = getFlowLayers("ods_dwd");
      expect(layers).not.toContain("ODS");
      expect(layers).not.toContain("DWS");
      expect(layers).not.toContain("INDEX");
    });

    it("dwd_dws 只包含 DWS，不包含 ODS / DWD / INDEX", () => {
      const layers = getFlowLayers("dwd_dws");
      expect(layers).not.toContain("ODS");
      expect(layers).not.toContain("DWD");
      expect(layers).not.toContain("INDEX");
    });

    it("dwd_index 只包含 INDEX，不包含 ODS / DWD / DWS", () => {
      const layers = getFlowLayers("dwd_index");
      expect(layers).not.toContain("ODS");
      expect(layers).not.toContain("DWD");
      expect(layers).not.toContain("DWS");
    });
  });

  /* ---- 5. 任务兼容性：模拟任务按层过滤 ---- */
  describe("任务兼容性过滤", () => {
    // 模拟任务定义
    const mockTasks = [
      { code: "FETCH_ORDERS", layer: "ODS" },
      { code: "LOAD_DWD_ORDERS", layer: "DWD" },
      { code: "AGG_DAILY_REVENUE", layer: "DWS" },
      { code: "CALC_WBI_INDEX", layer: "INDEX" },
    ];

    /**
     * 根据 Flow 包含的层过滤任务（与 TaskSelector 组件逻辑一致）
     */
    function filterTasksByFlow(flowId: string) {
      const layers = getFlowLayers(flowId);
      return mockTasks.filter((t) => layers.includes(t.layer));
    }

    it("api_ods 只显示 ODS 任务", () => {
      const visible = filterTasksByFlow("api_ods");
      expect(visible.map((t) => t.code)).toEqual(["FETCH_ORDERS"]);
    });

    it("api_full 显示所有层的任务", () => {
      const visible = filterTasksByFlow("api_full");
      expect(visible).toHaveLength(4);
    });

    it("dwd_dws_index 显示 DWS 和 INDEX 任务", () => {
      const visible = filterTasksByFlow("dwd_dws_index");
      const codes = visible.map((t) => t.code);
      expect(codes).toContain("AGG_DAILY_REVENUE");
      expect(codes).toContain("CALC_WBI_INDEX");
      expect(codes).not.toContain("FETCH_ORDERS");
      expect(codes).not.toContain("LOAD_DWD_ORDERS");
    });

    it("未知 Flow 不显示任何任务", () => {
      const visible = filterTasksByFlow("nonexistent");
      expect(visible).toHaveLength(0);
    });
  });
});
