import { describe, expect, test } from "vitest";
import { fallbackNavigation, filterNavigationByPermission, mapBackendMenus, mergeNavigationItems } from "./menu.js";

describe("navigation menu helpers", () => {
    test("keeps only fallback menu items allowed by permissions", () => {
        const items = filterNavigationByPermission(
            fallbackNavigation,
            (code) => code === "agency:view" || code === "host:view",
        );

        expect(flattenCodes(items)).not.toContain("geo");
        expect(flattenCodes(items)).toContain("host-org");
        expect(flattenCodes(items)).toContain("host-org-managers");
        expect(flattenCodes(items)).toContain("host-org-agencies");
        expect(flattenCodes(items)).toContain("host-org-hosts");
        expect(flattenCodes(items)).not.toContain("host-org-bds");
    });

    test("places country and region pages under geo menu", () => {
        const items = filterNavigationByPermission(
            fallbackNavigation,
            (code) => code === "country:view" || code === "region:view",
        );
        const geo = items.find((item) => item.code === "geo");

        expect(geo).toBeTruthy();
        expect(geo.children.map((item) => item.code)).toEqual(["host-org-countries", "host-org-regions"]);
        expect(flattenCodes(items)).not.toContain("host-org");
    });

    test("keeps the app user login log entry routable", () => {
        const items = filterNavigationByPermission(fallbackNavigation, (code) => code === "app-user:view");
        const appUsers = items.find((item) => item.code === "app-users");

        expect(appUsers.children.map((item) => item.code)).toContain("app-user-login-logs");
        expect(appUsers.children.find((item) => item.code === "app-user-login-logs").path).toBe(
            "/app/users/login-logs",
        );
    });

    test("adds missing permitted fallback children to backend menu groups", () => {
        const backendMenus = [
            {
                children: [],
                code: "host-org",
                icon: fallbackNavigation.find((item) => item.code === "host-org").icon,
                id: "host-org",
                label: "团队管理",
            },
        ];
        const fallbackMenus = filterNavigationByPermission(fallbackNavigation, (code) => code === "agency:view");
        const merged = mergeNavigationItems(backendMenus, fallbackMenus);

        expect(flattenCodes(merged)).toContain("host-org-agencies");
        expect(flattenCodes(merged)).toContain("host-org-managers");
    });

    test("places recharge products under app config even when backend menu is stale", () => {
        const mapped = mapBackendMenus([
            { children: [], code: "app-config", icon: "settings", id: "app-config", label: "APP配置" },
            {
                children: [
                    {
                        code: "payment-recharge-products",
                        icon: "wallet",
                        id: "payment-recharge-products",
                        label: "内购配置",
                        path: "/payment/recharge-products",
                        permissionCode: "payment-product:view",
                    },
                ],
                code: "payment",
                icon: "wallet",
                id: "payment",
                label: "支付管理",
            },
        ]);
        const appConfig = mapped.find((item) => item.code === "app-config");
        const payment = mapped.find((item) => item.code === "payment");

        expect(appConfig.children.map((item) => item.code)).toContain("payment-recharge-products");
        expect(appConfig.children.find((item) => item.code === "payment-recharge-products").path).toBe(
            "/app-config/recharge-products",
        );
        expect(payment).toBeUndefined();
    });
});

function flattenCodes(items) {
    return items.flatMap((item) => [item.code, ...flattenCodes(item.children || [])]);
}
