import { fireEvent, render, screen } from "@testing-library/react";
import { afterEach, expect, test, vi } from "vitest";
import { ResourceGrantListPage } from "./ResourceGrantListPage.jsx";
import { useResourceGrantListPage } from "@/features/resources/hooks/useResourcePages.js";

const mocks = vi.hoisted(() => ({
    revokeGrant: vi.fn(),
}));

vi.mock("@/features/resources/hooks/useResourcePages.js", () => ({
    useResourceGrantListPage: vi.fn(),
}));

afterEach(() => {
    vi.clearAllMocks();
});

test("resource grant list shows revoke only for succeeded resource group grants", () => {
    const eligible = grantFixture({
        grantId: "rgr_group_ok",
        grantSubjectType: "resource_group",
        status: "succeeded",
    });
    vi.mocked(useResourceGrantListPage).mockReturnValue(
        pageFixture({
            data: {
                items: [
                    eligible,
                    grantFixture({ grantId: "rgr_resource_ok", grantSubjectType: "resource", status: "succeeded" }),
                    grantFixture({ grantId: "rgr_group_revoked", grantSubjectType: "resource_group", status: "revoked" }),
                ],
                page: 1,
                pageSize: 50,
                total: 3,
            },
        }),
    );

    render(<ResourceGrantListPage />);

    expect(screen.getByText("已撤销")).toBeInTheDocument();
    const revokeButtons = screen.getAllByLabelText("撤销");
    expect(revokeButtons).toHaveLength(1);

    fireEvent.click(revokeButtons[0]);

    expect(mocks.revokeGrant).toHaveBeenCalledWith(eligible);
});

test("resource grant list hides revoke without permission", () => {
    vi.mocked(useResourceGrantListPage).mockReturnValue(
        pageFixture({
            abilities: { canCreateGrant: false, canRevokeGrant: false },
            data: {
                items: [grantFixture({ grantSubjectType: "resource_group", status: "succeeded" })],
                page: 1,
                pageSize: 50,
                total: 1,
            },
        }),
    );

    render(<ResourceGrantListPage />);

    expect(screen.queryByLabelText("撤销")).not.toBeInTheDocument();
});

test("resource grant list renders readable source, reason, and granted items", () => {
    vi.mocked(useResourceGrantListPage).mockReturnValue(
        pageFixture({
            data: {
                items: [
                    grantFixture({
                        grantId: "rgr_1234567890abcdef",
                        commandId: "seven_day_checkin_1782448934991_9b39c38",
                        grantSource: "seven_day_checkin",
                        grantSubjectId: "18",
                        grantSubjectType: "resource_group",
                        items: [
                            {
                                grantItemId: 1,
                                quantity: 100,
                                resourceId: 0,
                                resourceSnapshotJson: JSON.stringify({
                                    wallet_asset_type: "COIN",
                                    wallet_asset_amount: 100,
                                }),
                            },
                            {
                                durationMs: 7 * 24 * 60 * 60 * 1000,
                                grantItemId: 2,
                                quantity: 1,
                                resourceId: 385,
                                resourceSnapshotJson: JSON.stringify({
                                    Name: "星光头像框",
                                    PreviewURL: "https://media.haiyihy.com/star-frame.png",
                                    ResourceType: "avatar_frame",
                                }),
                            },
                        ],
                        operator: { name: "后台用户", source: "admin", userId: "7" },
                        reason: "seven_day_checkin",
                    }),
                ],
                page: 1,
                pageSize: 50,
                total: 1,
            },
        }),
    );

    render(<ResourceGrantListPage />);

    expect(screen.getAllByText("七日签到")).toHaveLength(2);
    expect(screen.getByText("资源组 · 七日签到")).toBeInTheDocument();
    expect(screen.getByText("资源组 ID 18")).toBeInTheDocument();
    expect(screen.getByText("金币 100")).toBeInTheDocument();
    expect(screen.getByText("星光头像框 x1 · 头像框 · 7天")).toBeInTheDocument();
    expect(screen.queryByText("0 / 100")).not.toBeInTheDocument();
    expect(screen.queryByText("rgr_1234567890abcdef")).not.toBeInTheDocument();
    expect(screen.queryByText("seven_day_checkin_1782448934991_9b39c38")).not.toBeInTheDocument();
    expect(screen.queryByText("后台用户")).not.toBeInTheDocument();
    expect(document.querySelector('img[src="https://media.haiyihy.com/star-frame.png"]')).toBeInTheDocument();
});

test("resource grant list keeps operator only for user initiated manager grants", () => {
    vi.mocked(useResourceGrantListPage).mockReturnValue(
        pageFixture({
            data: {
                items: [
                    grantFixture({
                        grantId: "rgr_manager",
                        grantSource: "manager_center",
                        operator: {
                            source: "manager_center",
                            userId: "328151620022083584",
                            username: "Manager A",
                        },
                    }),
                ],
                page: 1,
                pageSize: 50,
                total: 1,
            },
        }),
    );

    render(<ResourceGrantListPage />);

    expect(screen.getByText("Manager A")).toBeInTheDocument();
});

function pageFixture(patch = {}) {
    return {
        abilities: {
            canCreateGrant: true,
            canRevokeGrant: true,
        },
        activeAction: "",
        changeQuery: vi.fn(),
        changeStatus: vi.fn(),
        closeAction: vi.fn(),
        data: { items: [], page: 1, pageSize: 50, total: 0 },
        error: null,
        form: {
            durationDays: "0",
            giftIds: [],
            groupId: "",
            reason: "",
            resourceIds: [],
            subjectType: "resource",
            targetUserId: "",
        },
        giftOptions: [],
        giftTypeOptions: [],
        groupOptions: [],
        loading: false,
        loadingAction: "",
        openCreateGrant: vi.fn(),
        optionsLoading: false,
        page: 1,
        query: "",
        reload: vi.fn(),
        resetFilters: vi.fn(),
        resourceOptions: [],
        revokeGrant: mocks.revokeGrant,
        setForm: vi.fn(),
        setPage: vi.fn(),
        status: "",
        submitGrant: vi.fn(),
        ...patch,
    };
}

function grantFixture(patch = {}) {
    return {
        commandId: "resource-group-grant-test",
        createdAtMs: 1782287714973,
        grantId: "rgr_test",
        grantSubjectId: "22",
        grantSubjectType: "resource_group",
        items: [{ grantItemId: 1, quantity: 100, resourceId: 0 }],
        operatorUserId: 7,
        reason: "manual",
        status: "succeeded",
        targetUserId: "318705991371722752",
        ...patch,
    };
}
