import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, test, vi } from "vitest";
import {
    ExternalAdminPermissionSelector,
    updatePermissionSelection,
} from "./ExternalAdminPermissionSelector.jsx";
import { defaultPermissionSelection } from "@/features/external-admin-users/permissionSelection.js";

const catalog = [
    { code: "user:list", dependencies: [], group: "用户管理", label: "用户列表" },
    { code: "user:update", dependencies: ["user:list"], group: "用户管理", label: "编辑用户" },
    { code: "room:list", dependencies: [], group: "房间管理", label: "房间列表" },
];

describe("ExternalAdminPermissionSelector", () => {
    test("adds required permissions and removes actions whose dependency is cleared", () => {
        expect(updatePermissionSelection(catalog, [], "user:update", true)).toEqual(["user:list", "user:update"]);
        expect(
            updatePermissionSelection(catalog, ["user:list", "user:update", "room:list"], "user:list", false),
        ).toEqual(["room:list"]);
    });

    test("expands dependencies declared by default-granted catalog entries", () => {
        expect(
            defaultPermissionSelection([
                { code: "user:list", defaultGranted: false, dependencies: [] },
                { code: "user:update", defaultGranted: true, dependencies: ["user:list"] },
            ]),
        ).toEqual(["user:list", "user:update"]);
    });

    test("resolves cyclic dependencies without recursion or removal loops", () => {
        const cyclicCatalog = [
            { code: "level:view", dependencies: ["vip:view"], group: "等级", label: "等级" },
            { code: "vip:view", dependencies: ["level:view"], group: "等级", label: "VIP" },
        ];

        expect(updatePermissionSelection(cyclicCatalog, [], "level:view", true)).toEqual([
            "level:view",
            "vip:view",
        ]);
        expect(updatePermissionSelection(cyclicCatalog, ["level:view", "vip:view"], "level:view", false)).toEqual([]);
    });

    test("renders backend groups and supports explicit select all and clear", () => {
        const onChange = vi.fn();
        const { rerender } = render(
            <ExternalAdminPermissionSelector catalog={catalog} onChange={onChange} value={["user:list"]} />,
        );

        expect(screen.getByText("已选 1 / 3 项")).toBeInTheDocument();
        expect(screen.getByText("用户管理")).toBeInTheDocument();
        fireEvent.click(screen.getByRole("button", { name: "全选" }));
        expect(onChange).toHaveBeenLastCalledWith(["user:list", "user:update", "room:list"]);

        rerender(<ExternalAdminPermissionSelector catalog={catalog} onChange={onChange} value={catalog.map((item) => item.code)} />);
        fireEvent.click(screen.getByRole("button", { name: "清空" }));
        expect(onChange).toHaveBeenLastCalledWith([]);
    });
});
