import { fireEvent, render, screen, within } from "@testing-library/react";
import { afterEach, expect, test, vi } from "vitest";
import { VipConfigPage } from "./VipConfigPage.jsx";
import { useVipConfigPage } from "@/features/vip-config/hooks/useVipConfigPage.js";

vi.mock("@/features/vip-config/hooks/useVipConfigPage.js", () => ({
    useVipConfigPage: vi.fn(),
}));

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

test("vip config overview follows the compact five-column design and opens level editing", () => {
    const page = pageFixture();
    vi.mocked(useVipConfigPage).mockReturnValue(page);

    render(<VipConfigPage />);

    expect(screen.getByRole("heading", { name: "VIP配置" })).toBeInTheDocument();
    expect(screen.getByText("fami · Fami P1 VIP")).toBeInTheDocument();
    expect(screen.getByText("高等级从购买时重新计时")).toBeInTheDocument();
    expect(Array.from(document.querySelectorAll("[data-table-header-cell]")).map((cell) => cell.textContent)).toEqual([
        "等级",
        "状态",
        "购买金币",
        "有效期",
        "更新时间",
    ]);
    expect(screen.queryByText("操作", { selector: "[data-table-header-cell] *" })).not.toBeInTheDocument();

    fireEvent.click(screen.getByRole("button", { name: "编辑配置" }));
    expect(page.openLevelsEditor).toHaveBeenCalledTimes(1);
});

test("P1 level editing uses a real dialog and only renders the selected level editor", () => {
    const page = pageFixture({ editorMode: "levels" });
    vi.mocked(useVipConfigPage).mockReturnValue(page);

    render(<VipConfigPage />);

    const dialog = screen.getByRole("dialog", { name: /^VIP等级配置/ });
    const levelNavigation = within(dialog).getByRole("navigation", { name: "VIP等级" });

    expect(screen.getByTestId("vip-level-1")).toBeInTheDocument();
    expect(screen.queryByTestId("vip-level-2")).not.toBeInTheDocument();
    expect(within(screen.getByTestId("vip-level-1")).getByLabelText("奖励资源组（可选）")).toBeInTheDocument();

    fireEvent.click(within(levelNavigation).getByRole("button", { name: /VIP2/ }));

    expect(screen.getByTestId("vip-level-2")).toBeInTheDocument();
    expect(screen.queryByTestId("vip-level-1")).not.toBeInTheDocument();
    fireEvent.change(within(screen.getByTestId("vip-level-2")).getByLabelText("购买金币"), {
        target: { value: "260" },
    });
    expect(page.updateLevel).toHaveBeenCalledWith(2, { priceCoin: "260" });
});

test("benefit search and status filters only change the visible matrix", () => {
    const page = pageFixture({ editorMode: "levels" });
    vi.mocked(useVipConfigPage).mockReturnValue(page);

    render(<VipConfigPage />);

    const benefitPanel = screen.getByRole("region", { name: "VIP1权益配置" });
    fireEvent.change(within(benefitPanel).getByLabelText("搜索权益"), { target: { value: "返现" } });

    expect(within(benefitPanel).getByRole("button", { name: /金币返现/ })).toBeInTheDocument();
    expect(within(benefitPanel).queryByRole("button", { name: /VIP标识/ })).not.toBeInTheDocument();

    fireEvent.change(within(benefitPanel).getByLabelText("搜索权益"), { target: { value: "" } });
    fireEvent.click(within(benefitPanel).getByRole("button", { name: "未启用" }));

    expect(within(benefitPanel).getByRole("button", { name: /金币返现/ })).toBeInTheDocument();
    expect(within(benefitPanel).getByRole("button", { name: /上线全服通知/ })).toBeInTheDocument();
    expect(within(benefitPanel).queryByRole("button", { name: /VIP标识/ })).not.toBeInTheDocument();
    expect(page.updateBenefit).not.toHaveBeenCalled();
    expect(page.updateAllBenefits).not.toHaveBeenCalled();
});

test("benefit inspector writes typed rebate and online notice parameters", () => {
    const page = pageFixture({ editorMode: "levels" });
    vi.mocked(useVipConfigPage).mockReturnValue(page);

    render(<VipConfigPage />);

    const benefitPanel = screen.getByRole("region", { name: "VIP1权益配置" });
    const inspector = screen.getByRole("complementary", { name: "权益详细设置" });

    fireEvent.click(within(benefitPanel).getByRole("button", { name: /金币返现/ }));
    expect(within(inspector).getByLabelText("每日返现金币")).toHaveValue(88);
    fireEvent.change(within(inspector).getByLabelText("每日返现金币"), { target: { value: "99" } });

    fireEvent.click(within(benefitPanel).getByRole("button", { name: /上线全服通知/ }));
    expect(within(inspector).getByLabelText("上线飘屏文案")).toHaveValue("欢迎上线");
    fireEvent.change(within(inspector).getByLabelText("上线飘屏文案"), {
        target: { value: "新的上线文案" },
    });

    const rebatePatch = page.updateBenefit.mock.calls.find((call) => call[1] === "daily_coin_rebate")?.[2];
    const noticePatch = page.updateBenefit.mock.calls.find((call) => call[1] === "online_global_notice")?.[2];
    expect(page.updateBenefit.mock.calls.find((call) => call[1] === "daily_coin_rebate")?.[0]).toBe(1);
    expect(page.updateBenefit.mock.calls.find((call) => call[1] === "online_global_notice")?.[0]).toBe(1);
    expect(JSON.parse(rebatePatch.metadataJson)).toEqual({ channel: "vip", coin_amount: 99 });
    expect(JSON.parse(noticePatch.metadataJson)).toEqual({ message: "新的上线文案", theme: "gold" });
});

test("benefit select-all targets only the current level", () => {
    const page = pageFixture({ editorMode: "levels" });
    vi.mocked(useVipConfigPage).mockReturnValue(page);

    render(<VipConfigPage />);

    const selectAll = screen.getByRole("checkbox", { name: "VIP1权益全选" });
    expect(selectAll).toHaveAttribute("data-indeterminate", "true");
    expect(screen.getByRole("checkbox", { name: "VIP标识权益" })).toBeChecked();

    fireEvent.click(selectAll);

    expect(page.updateAllBenefits).toHaveBeenCalledTimes(1);
    expect(page.updateAllBenefits).toHaveBeenCalledWith(1, "active");
});

test("level dialog exposes one footer cancel and one whole-package save action", () => {
    const page = pageFixture({ editorMode: "levels" });
    vi.mocked(useVipConfigPage).mockReturnValue(page);

    render(<VipConfigPage />);

    const dialog = screen.getByRole("dialog", { name: /^VIP等级配置/ });
    const cancelButtons = within(dialog).getAllByRole("button", { name: "取消" });
    const saveButtons = within(dialog).getAllByRole("button", { name: "保存全部配置" });
    expect(cancelButtons).toHaveLength(1);
    expect(saveButtons).toHaveLength(1);

    fireEvent.click(cancelButtons[0]);
    fireEvent.click(saveButtons[0]);

    expect(page.closeEditor).toHaveBeenCalledTimes(1);
    expect(page.submitLevels).toHaveBeenCalledTimes(1);
});

function pageFixture(patch = {}) {
    const benefits = [
        benefitFixture({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active" }),
        benefitFixture({
            benefitCode: "daily_coin_rebate",
            metadataJson: '{"channel":"vip","coin_amount":88}',
            name: "金币返现",
            trialEnabled: false,
            unlockLevel: 6,
        }),
        benefitFixture({
            benefitCode: "online_global_notice",
            executionScope: "notice",
            metadataJson: '{"message":"欢迎上线","theme":"gold"}',
            name: "上线全服通知",
            unlockLevel: 9,
        }),
    ];
    const firstLevel = levelFixture({ benefits, level: 1, name: "VIP1", status: "active" });
    const secondLevel = levelFixture({
        benefits: benefits.map((benefit) => ({ ...benefit })),
        level: 2,
        name: "VIP2",
        priceCoin: "200",
        sortOrder: "20",
    });
    return {
        abilities: { canUpdate: true, canView: true },
        activeCount: 1,
        appCode: "fami",
        closeEditor: vi.fn(),
        config: {
            levels: [
                { ...firstLevel, durationMs: 30 * 24 * 60 * 60 * 1000, priceCoin: 100 },
                { ...secondLevel, durationMs: 30 * 24 * 60 * 60 * 1000, priceCoin: 200 },
            ],
        },
        editorMode: "",
        error: null,
        form: { levels: [firstLevel, secondLevel] },
        loading: false,
        openLevelsEditor: vi.fn(),
        openProgramEditor: vi.fn(),
        program: {
            grantMode: "trial_card",
            levelCount: 2,
            programType: "tiered_privilege_v1",
            status: "active",
            trialCardEnabled: true,
            upgradeExpiryPolicy: "replace_from_now",
        },
        programForm: { enabled: true, levelCount: "2", programType: "tiered_privilege_v1" },
        reload: vi.fn(),
        resourceGroups: [{ groupId: 11, name: "VIP1资源组" }],
        resources: [],
        resourcesLoading: false,
        saving: false,
        submitLevels: vi.fn((event) => event.preventDefault()),
        submitProgram: vi.fn((event) => event.preventDefault()),
        updateAllBenefits: vi.fn(),
        updateBenefit: vi.fn(),
        updateLevel: vi.fn(),
        updateProgramField: vi.fn(),
        ...patch,
    };
}

function levelFixture(patch = {}) {
    return {
        benefits: [],
        durationDays: "30",
        level: 1,
        name: "VIP1",
        priceCoin: "100",
        rewardResourceGroupId: "11",
        sortOrder: "10",
        status: "disabled",
        updatedAtMs: 1780000000000,
        ...patch,
    };
}

function benefitFixture(patch = {}) {
    return {
        autoEquip: false,
        benefitCode: "room_entry_notice",
        benefitType: "function",
        executionScope: "room",
        metadataJson: "{}",
        name: "VIP进房通知",
        resourceId: "",
        resourceType: "",
        sortOrder: "10",
        status: "disabled",
        trialEnabled: true,
        unlockLevel: 2,
        ...patch,
    };
}
