import { fireEvent, render, screen } from "@testing-library/react";
import { useState } from "react";
import { expect, test, vi } from "vitest";
import { GiftResourceSelectField } from "./GiftResourceSelectDrawer.jsx";

vi.mock("@/shared/ui/SideDrawer.jsx", () => ({
    SideDrawer({ actions, children, drawerProps, onClose, open, title }) {
        if (!open) {
            return null;
        }
        return (
            <aside aria-label={title} data-z-index={drawerProps?.sx?.zIndex} role="dialog">
                <button type="button" onClick={onClose}>
                    关闭
                </button>
                {children}
                {actions}
            </aside>
        );
    },
}));

const giftTypes = [
    { displayName: "普通礼物", sortOrder: 10, status: "active", tabKey: "normal" },
    { displayName: "CP礼物", sortOrder: 20, status: "active", tabKey: "cp" },
];

const resources = [
    {
        coinPrice: 10,
        name: "Rose Resource",
        priceType: "coin",
        resourceCode: "rose_resource",
        resourceId: 11,
        resourceType: "gift",
    },
    {
        coinPrice: 20,
        name: "CP Ring Resource",
        priceType: "coin",
        resourceCode: "cp_ring_resource",
        resourceId: 12,
        resourceType: "gift",
    },
    {
        coinPrice: 100,
        name: "VIP Vehicle",
        priceType: "coin",
        resourceCode: "vip_vehicle",
        resourceId: 21,
        resourceType: "vehicle",
    },
];

const gifts = [
    {
        chargeAssetType: "COIN",
        coinPrice: 10,
        giftId: "rose",
        giftTypeCode: "normal",
        name: "Rose Gift",
        resource: { previewUrl: "https://media.haiyihy.com/rose.png", resourceCode: "rose_resource" },
        resourceId: 11,
    },
    {
        chargeAssetType: "COIN",
        coinPrice: 20,
        giftId: "cp_ring",
        giftTypeCode: "cp",
        name: "CP Ring",
        resourceId: 12,
    },
];

test("gift resource select drawer filters by gift type and supports multiple selection", () => {
    const changes = [];

    function Harness() {
        const [value, setValue] = useState([]);
        return (
            <GiftResourceSelectField
                giftTypes={giftTypes}
                gifts={gifts}
                resources={resources}
                selectedResourceIds={value}
                onChange={(nextValue) => {
                    changes.push(nextValue);
                    setValue(nextValue);
                }}
            />
        );
    }

    render(<Harness />);

    fireEvent.click(screen.getByPlaceholderText("请选择资源"));

    expect(screen.getByRole("dialog", { name: "选择资源" })).toHaveAttribute("data-z-index", "1600");
    expect(screen.getByText("VIP Vehicle")).toBeInTheDocument();
    expect(screen.queryByText("Rose Gift")).not.toBeInTheDocument();
    expect(screen.queryByText("CP Ring")).not.toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "普通礼物" }));

    expect(screen.getByText("Rose Gift")).toBeInTheDocument();
    expect(screen.queryByText("VIP Vehicle")).not.toBeInTheDocument();

    fireEvent.click(screen.getByText("Rose Gift"));

    fireEvent.click(screen.getByRole("tab", { name: "CP礼物" }));

    expect(screen.queryByText("Rose Gift")).not.toBeInTheDocument();
    expect(screen.getByText("CP Ring")).toBeInTheDocument();

    fireEvent.click(screen.getByText("CP Ring"));

    expect(changes.at(-1)).toEqual(["11", "12"]);
    expect(screen.getByDisplayValue("Rose Gift，CP Ring")).toBeInTheDocument();
});

test("gift resource select drawer hides excluded gift resources from candidates", () => {
    function Harness() {
        const [value, setValue] = useState([]);
        return (
            <GiftResourceSelectField
                excludedResourceIds={[11]}
                giftTypes={giftTypes}
                gifts={gifts}
                resources={resources}
                selectedResourceIds={value}
                onChange={setValue}
            />
        );
    }

    render(<Harness />);

    fireEvent.click(screen.getByPlaceholderText("请选择资源"));
    fireEvent.click(screen.getByRole("tab", { name: "普通礼物" }));

    expect(screen.queryByText("Rose Gift")).not.toBeInTheDocument();
    expect(screen.getByText("当前无可选资源")).toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "CP礼物" }));
    expect(screen.getByText("CP Ring")).toBeInTheDocument();
});

test("gift resource select drawer hides excluded resources but keeps selected resources removable", () => {
    const changes = [];

    function Harness() {
        const [value, setValue] = useState(["11"]);
        return (
            <GiftResourceSelectField
                excludedResourceIds={[11, 21]}
                giftTypes={giftTypes}
                gifts={gifts}
                resources={resources}
                selectedResourceIds={value}
                onChange={(nextValue) => {
                    changes.push(nextValue);
                    setValue(nextValue);
                }}
            />
        );
    }

    render(<Harness />);

    fireEvent.click(screen.getByPlaceholderText("请选择资源"));

    expect(screen.getByText("Rose Gift")).toBeInTheDocument();
    expect(screen.queryByText("VIP Vehicle")).not.toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "CP礼物" }));
    fireEvent.click(screen.getByText("CP Ring"));

    expect(changes.at(-1)).toEqual(["11", "12"]);
    expect(screen.getByDisplayValue("Rose Gift，CP Ring")).toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "普通礼物" }));
    fireEvent.click(screen.getByText("Rose Gift"));

    expect(changes.at(-1)).toEqual(["12"]);
    expect(screen.queryByText("Rose Gift")).not.toBeInTheDocument();
    expect(screen.getByDisplayValue("CP Ring")).toBeInTheDocument();
});
