import { describe, expect, test } from "vitest";
import { completeVipLevels, levelToForm, vipConfigPayloadFromForm } from "./useVipConfigPage.js";

describe("VIP config form semantics", () => {
    test("keeps only explicit target-level benefits and never restores catalog omissions", () => {
        const program = tieredProgram({
            benefits: [
                benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active", unlockLevel: 1 }),
                benefit({ benefitCode: "daily_coin_rebate", name: "金币返现", status: "active", unlockLevel: 6 }),
            ],
        });
        const levels = completeVipLevels(
            [
                {
                    ...level(),
                    benefits: [benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "disabled" })],
                },
            ],
            program,
        );

        expect(levels[0].benefits).toHaveLength(1);
        expect(levels[0].benefits[0]).toMatchObject({ benefitCode: "vip_badge_identity", status: "disabled" });
        expect(levels[0].benefits.some((item) => item.benefitCode === "daily_coin_rebate")).toBe(false);
    });

    test("allows an active Fami level without a reward group and saves typed benefit metadata", () => {
        const payload = vipConfigPayloadFromForm(
            {
                levels: [
                    level({
                        benefits: [
                            benefit({
                                benefitCode: "daily_coin_rebate",
                                metadataJson: '{"source":"daily","coin_amount":"88"}',
                                name: "金币返现",
                                status: "active",
                                trialEnabled: true,
                                unlockLevel: 6,
                            }),
                            benefit({
                                benefitCode: "online_global_notice",
                                executionScope: "notice",
                                metadataJson: '{"message":"  欢迎上线  ","theme":"gold"}',
                                name: "上线全服通知",
                                status: "active",
                                unlockLevel: 9,
                            }),
                        ],
                        rewardResourceGroupId: "",
                    }),
                ],
            },
            tieredProgram(),
        );

        expect(payload.levels[0].rewardResourceGroupId).toBe(0);
        expect(JSON.parse(payload.levels[0].benefits[0].metadataJson)).toEqual({
            source: "daily",
            coin_amount: 88,
        });
        expect(payload.levels[0].benefits[0].trialEnabled).toBe(false);
        expect(JSON.parse(payload.levels[0].benefits[1].metadataJson)).toEqual({
            message: "欢迎上线",
            theme: "gold",
        });
    });

    test("shows missing catalog benefits as disabled placeholders without persisting untouched rows", () => {
        const program = tieredProgram({
            benefits: [
                benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active" }),
                benefit({ benefitCode: "visitor_history", name: "查看访客", status: "active" }),
            ],
        });
        const formLevel = levelToForm(
            level({
                benefits: [benefit({ benefitCode: "vip_badge_identity", name: "VIP标识", status: "active" })],
            }),
            program,
        );

        expect(formLevel.benefits).toHaveLength(34);
        const visitorIndex = formLevel.benefits.findIndex((item) => item.benefitCode === "visitor_history");
        expect(formLevel.benefits[visitorIndex]).toMatchObject({
            benefitCode: "visitor_history",
            catalogPlaceholder: true,
            status: "disabled",
        });
        expect(vipConfigPayloadFromForm({ levels: [formLevel] }, program).levels[0].benefits).toHaveLength(1);

        formLevel.benefits[visitorIndex] = { ...formLevel.benefits[visitorIndex], status: "active" };
        expect(vipConfigPayloadFromForm({ levels: [formLevel] }, program).levels[0].benefits).toHaveLength(2);
    });

    test("keeps the reward group requirement for an active classic VIP level", () => {
        expect(() =>
            vipConfigPayloadFromForm(
                { levels: [level({ benefits: [], rewardResourceGroupId: "" })] },
                { ...tieredProgram(), programType: "legacy_timed" },
            ),
        ).toThrow("启用时必须选择奖励资源组");
    });
});

function tieredProgram(patch = {}) {
    return {
        levelCount: 1,
        programType: "tiered_privilege_v1",
        ...patch,
    };
}

function level(patch = {}) {
    return {
        benefits: [],
        durationDays: "30",
        durationMs: 30 * 24 * 60 * 60 * 1000,
        level: 1,
        name: "VIP1",
        priceCoin: "100",
        rewardResourceGroupId: "",
        sortOrder: "10",
        status: "active",
        ...patch,
    };
}

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