import { describe, expect, test } from "vitest";
import {
    appBannerSchema,
    appPopupSchema,
    appSplashScreenSchema,
    exploreTabSchema,
    h5LinkUpdateSchema,
    parseSystemMessagePushUserIds,
    systemMessagePushSchema,
} from "@/features/app-config/schema";
import { FormValidationError, parseForm } from "@/shared/forms/validation";

const validBannerForm = {
    bannerType: "h5",
    countryCode: "",
    coverUrl: "https://media.haiyihy.com/banner/home.png",
    description: "",
    displayScope: "home",
    displayScopes: ["home"],
    endsAtMs: "1800000000000",
    param: "https://h5.example.com/activity",
    platform: "android",
    regionId: "",
    roomSmallImageUrl: "",
    sortOrder: "0",
    startsAtMs: "1700000000000",
    status: "active",
};

const validSplashScreenForm = {
    countryCode: "",
    coverUrl: "https://media.haiyihy.com/splash/launch.png",
    description: "",
    displayDurationMs: "4500",
    endsAtMs: "1800000000000",
    param: "https://h5.example.com/splash",
    platform: "ios",
    regionId: "",
    sortOrder: "0",
    splashType: "h5",
    startsAtMs: "1700000000000",
    status: "active",
};

const validPopupForm = {
    code: "new-user-popup",
    displayPeriodDays: "2",
    endsAtMs: "1800000000000",
    imageUrl: "",
    jumpType: "h5",
    jumpUrl: "https://h5.example.com/popup",
    name: "新人活动",
    sortOrder: "0",
    startsAtMs: "1700000000000",
    status: "active",
};

describe("app config form schema", () => {
    test("validates dynamic h5 config item", () => {
        const payload = parseForm(h5LinkUpdateSchema, {
            key: "host-center.v2",
            label: "Host Center",
            url: "https://h5.example.com/host",
        });

        expect(payload.key).toBe("host-center.v2");
        expect(payload.label).toBe("Host Center");
    });

    test("rejects dynamic h5 config key with spaces", () => {
        expect(() =>
            parseForm(h5LinkUpdateSchema, {
                key: "host center",
                label: "Host Center",
                url: "https://h5.example.com/host",
            }),
        ).toThrow(FormValidationError);
    });

    test("parses and dedupes system message push user IDs as strings", () => {
        expect(parseSystemMessagePushUserIds("325379237278126080, 42，42  1001")).toEqual([
            "325379237278126080",
            "42",
            "1001",
        ]);
    });

    test("keeps system message push payload constrained to supported scopes", () => {
        const payload = parseForm(systemMessagePushSchema, {
            actionParam: "",
            actionType: "",
            body: "正文",
            summary: "摘要",
            targetScope: "all_registered_users",
            title: "标题",
            userIdsText: "",
        });

        expect(payload.targetScope).toBe("all_registered_users");
    });

    test("requires system message push user IDs for specified users", () => {
        expect(() =>
            parseForm(systemMessagePushSchema, {
                actionParam: "",
                actionType: "",
                body: "",
                summary: "摘要",
                targetScope: "user_ids",
                title: "标题",
                userIdsText: "",
            }),
        ).toThrow(FormValidationError);
    });

    test("keeps banner display scope and delivery time fields", () => {
        const payload = parseForm(appBannerSchema, validBannerForm);

        expect(payload.displayScopes).toEqual(["home"]);
        expect(payload.startsAtMs).toBe(1700000000000);
        expect(payload.endsAtMs).toBe(1800000000000);
    });

    test("accepts public app jump json for banner", () => {
        const payload = parseForm(appBannerSchema, {
            ...validBannerForm,
            bannerType: "app",
            param: '{"type":"room_random_game","game_id":"dice"}',
        });

        expect(payload.bannerType).toBe("app");
        expect(payload.param).toBe('{"type":"room_random_game","game_id":"dice"}');
    });

    test("rejects incomplete public app jump json for banner", () => {
        expect(() =>
            parseForm(appBannerSchema, {
                ...validBannerForm,
                bannerType: "app",
                param: '{"type":"room_game","room_id":"room_1"}',
            }),
        ).toThrow(FormValidationError);
    });

    test("accepts multiple banner display scopes", () => {
        const payload = parseForm(appBannerSchema, {
            ...validBannerForm,
            displayScopes: ["home", "room", "recharge", "me"],
            roomSmallImageUrl: "https://media.haiyihy.com/banner/room-small.png",
        });

        expect(payload.displayScopes).toEqual(["home", "room", "recharge", "me"]);
    });

    test("requires room small image for room banner", () => {
        expect(() =>
            parseForm(appBannerSchema, {
                ...validBannerForm,
                displayScopes: ["home", "room"],
                roomSmallImageUrl: "",
            }),
        ).toThrow(FormValidationError);
    });

    test("rejects inverted banner delivery time range", () => {
        expect(() =>
            parseForm(appBannerSchema, {
                ...validBannerForm,
                endsAtMs: "1700000000000",
                startsAtMs: "1800000000000",
            }),
        ).toThrow(FormValidationError);
    });

    test("keeps splash screen delivery and placement fields without display scope", () => {
        const payload = parseForm(appSplashScreenSchema, validSplashScreenForm);

        expect(payload.splashType).toBe("h5");
        expect(payload.displayDurationMs).toBe(4500);
        expect(payload.startsAtMs).toBe(1700000000000);
        expect(payload.endsAtMs).toBe(1800000000000);
        expect("displayScopes" in payload).toBe(false);
    });

    test("accepts public app jump json for splash screen", () => {
        const payload = parseForm(appSplashScreenSchema, {
            ...validSplashScreenForm,
            param: '{"type":"wallet"}',
            splashType: "app",
        });

        expect(payload.splashType).toBe("app");
        expect(payload.param).toBe('{"type":"wallet"}');
    });

    test("requires h5 link for splash screen h5 type", () => {
        expect(() =>
            parseForm(appSplashScreenSchema, {
                ...validSplashScreenForm,
                param: "",
            }),
        ).toThrow(FormValidationError);
    });

    test("rejects negative splash screen display duration", () => {
        expect(() =>
            parseForm(appSplashScreenSchema, {
                ...validSplashScreenForm,
                displayDurationMs: "-1",
            }),
        ).toThrow(FormValidationError);
    });

    test("rejects inverted splash screen delivery time range", () => {
        expect(() =>
            parseForm(appSplashScreenSchema, {
                ...validSplashScreenForm,
                endsAtMs: "1700000000000",
                startsAtMs: "1800000000000",
            }),
        ).toThrow(FormValidationError);
    });

    test("keeps popup optional image and display period", () => {
        const payload = parseForm(appPopupSchema, validPopupForm);

        expect(payload.code).toBe("new-user-popup");
        expect(payload.imageUrl).toBe("");
        expect(payload.displayPeriodDays).toBe(2);
        expect(payload.startsAtMs).toBe(1700000000000);
        expect(payload.endsAtMs).toBe(1800000000000);
    });

    test("accepts public app jump json for popup", () => {
        const payload = parseForm(appPopupSchema, {
            ...validPopupForm,
            jumpType: "app",
            jumpUrl: '{"type":"room_window","room_id":"room_1","window":"gift_panel","gift_id":"gift_1"}',
        });

        expect(payload.jumpType).toBe("app");
        expect(payload.jumpUrl).toBe(
            '{"type":"room_window","room_id":"room_1","window":"gift_panel","gift_id":"gift_1"}',
        );
    });

    test("rejects popup code with spaces", () => {
        expect(() =>
            parseForm(appPopupSchema, {
                ...validPopupForm,
                code: "new user popup",
            }),
        ).toThrow(FormValidationError);
    });

    test("requires popup jump address", () => {
        expect(() =>
            parseForm(appPopupSchema, {
                ...validPopupForm,
                jumpUrl: "",
            }),
        ).toThrow(FormValidationError);
    });

    test("rejects inverted popup effective time range", () => {
        expect(() =>
            parseForm(appPopupSchema, {
                ...validPopupForm,
                endsAtMs: "1700000000000",
                startsAtMs: "1800000000000",
            }),
        ).toThrow(FormValidationError);
    });

    test("validates explore tab h5 url and sort order", () => {
        const payload = parseForm(exploreTabSchema, {
            enabled: true,
            h5Url: "https://h5.example.com/explore/live",
            sortOrder: "3",
            tab: "Live",
        });

        expect(payload.sortOrder).toBe(3);
        expect(payload.h5Url).toBe("https://h5.example.com/explore/live");
    });

    test("rejects explore tab url with whitespace", () => {
        expect(() =>
            parseForm(exploreTabSchema, {
                enabled: true,
                h5Url: "https://h5.example.com/explore live",
                sortOrder: "0",
                tab: "Live",
            }),
        ).toThrow(FormValidationError);
    });
});
