import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { beforeEach, expect, test, vi } from "vitest";
import { MemoryRouter } from "react-router-dom";
import { ConfirmProvider } from "@/shared/ui/ConfirmProvider.jsx";
import { ToastProvider } from "@/shared/ui/ToastProvider.jsx";
import { getAppUser, issueAppUserAccessToken, revokeAppUserResource } from "@/features/app-users/api";
import { useAppUserDetail } from "@/features/app-users/components/AppUserDetailContext.jsx";
import { AppUserDetailProvider } from "@/features/app-users/components/AppUserDetailProvider.jsx";

vi.mock("@/features/app-users/api", () => ({
    getAppUser: vi.fn(),
    issueAppUserAccessToken: vi.fn(),
    revokeAppUserResource: vi.fn(),
}));

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

test("detail drawer keeps the identity hero and shows the expanded admin projection", async () => {
    vi.mocked(getAppUser).mockResolvedValue({
        age: 26,
        appVersion: "3.2.1",
        appVersionAtMs: 1780990000000,
        avatar: "",
        ban: { active: true, permanent: true, reason: "risk" },
        birth: "2000-02-29",
        balances: [
            { assetType: "AGENCY_SALARY_USD", availableAmount: 100, frozenAmount: 0 },
            { assetType: "COIN", availableAmount: 15, frozenAmount: 0 },
            { assetType: "HOST_SALARY_USD", availableAmount: 400, frozenAmount: 0 },
        ],
        buildNumber: "345",
        coin: 1200,
        countryDisplayName: "阿联酋",
        createdAtMs: 1780000000000,
        cumulativeRechargeUsdMinor: 12345,
        defaultDisplayUserId: "163337",
        devices: [
            {
                appVersion: "3.2.1",
                buildNumber: "345",
                deviceId: "android_abcdef",
                deviceModel: "Redmi Note 8 Pro",
                firstSeenAtMs: 1770000000000,
                imei: "",
                lastSeenAtMs: 1781500000000,
                manufacturer: "Xiaomi",
                osVersion: "13",
                platform: "android",
            },
        ],
        diamond: 88,
        displayUserId: "163337",
        gender: "female",
        lastLoginAtMs: 1781000000000,
        lastLoginIp: "203.0.113.7",
        lastLoginIpAtMs: 1781600000000,
        lastLoginIpCountryCode: "AE",
        lastOperatedAtMs: 1782000000000,
        lastOperator: { action: "ban", adminId: "7", name: "运营" },
        levels: {
            charm: { displayLevel: 18, realLevel: 7, temporaryTargetLevel: 18, expiresAtMs: 1790000000000 },
            game: { displayLevel: 9, realLevel: 9 },
            wealth: { displayLevel: 20, realLevel: 8, temporaryTargetLevel: 20, expiresAtMs: 1790000000000 },
        },
        prettyDisplayUserId: "VIP888",
        prettyId: "pretty-888",
        regionName: "中东区",
        registerDevice: "iPhone17,2",
        registerDeviceId: "ios_1F2E3D",
        registerOsVersion: "17.5",
        roles: ["主播", "BD"],
        status: "banned",
        thirdPartyIdentities: [
            { createdAtMs: 1760000000000, openid: "g-openid-1", provider: "google", unionId: "g-union-1" },
        ],
        updatedAtMs: 1782000000000,
        userId: "10001",
        username: "tester",
        vip: { active: true, expiresAtMs: 1795000000000, level: 3, name: "黄金会员" },
    });
    vi.mocked(issueAppUserAccessToken).mockResolvedValue({
        accessToken: "eyJhbGciOiJIUzI1NiJ9.this-is-a-long-enough-jwt-payload.signature-tail",
        deviceId: "android_abcdef",
        expiresInSec: 7200,
        sessionId: "session-1",
        sessionLastHeartbeatAtMs: 1781700000000,
        tokenType: "Bearer",
    });

    render(
        <ToastProvider>
            <ConfirmProvider>
                <MemoryRouter initialEntries={["/app/users?status=active"]}>
                    <AppUserDetailProvider>
                        <DetailTrigger />
                    </AppUserDetailProvider>
                </MemoryRouter>
            </ConfirmProvider>
        </ToastProvider>,
    );
    fireEvent.click(screen.getByRole("button", { name: "打开详情" }));

    expect((await screen.findAllByText("VIP888")).length).toBeGreaterThan(0);
    expect(screen.getByText("注册设备")).toBeInTheDocument();
    expect(screen.getByText("iPhone17,2")).toBeInTheDocument();
    expect(screen.getByText("主播、BD")).toBeInTheDocument();
    expect(screen.getByRole("link", { name: /完整详情/ })).toHaveAttribute("href", "/app/users/10001");
    expect(screen.getByRole("tab", { name: "总览" })).toHaveAttribute("aria-selected", "true");
    expect(screen.getAllByText(/真实 Lv8/).length).toBeGreaterThan(0);
    expect(screen.getByText("VIP 3 · 黄金会员")).toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "资产" }));
    expect(screen.getAllByText("累计充值").length).toBeGreaterThan(0);
    expect(screen.getAllByText(/123\.45/).length).toBeGreaterThan(0);
    expect(screen.getByText("$1.00")).toBeInTheDocument();
    expect(screen.getByText("$4.00")).toBeInTheDocument();
    expect(screen.getByText("15", { selector: "div" })).toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "状态记录" }));
    expect(screen.getByText("永久")).toBeInTheDocument();
    expect(screen.getByText("203.0.113.7")).toBeInTheDocument();
    expect(screen.getByText(/AE · 记录于/)).toBeInTheDocument();
    expect(screen.getByText("3.2.1 (build 345)")).toBeInTheDocument();
    expect(screen.getByText("google")).toBeInTheDocument();
    expect(screen.getByText("g-openid-1")).toBeInTheDocument();

    // Token 属于敏感凭证，必须显式点击按钮才发起签发请求，展示为截断形态但复制值仍是完整 Token。
    expect(issueAppUserAccessToken).not.toHaveBeenCalled();
    fireEvent.click(screen.getByRole("button", { name: "获取 Token" }));
    expect(await screen.findByText("eyJhbGciOiJIUz…ature-tail")).toBeInTheDocument();
    expect(issueAppUserAccessToken).toHaveBeenCalledWith("10001");
    expect(screen.getByText("有效期 7200 秒")).toBeInTheDocument();

    fireEvent.click(screen.getByRole("tab", { name: "设备" }));
    expect(screen.getByText("Xiaomi Redmi Note 8 Pro")).toBeInTheDocument();
    expect(screen.getByText("android_abcdef")).toBeInTheDocument();
    expect(screen.getByText("注册系统版本")).toBeInTheDocument();
    expect(screen.getByText("17.5")).toBeInTheDocument();
    expect(screen.getByText("ios_1F2E3D")).toBeInTheDocument();

    fireEvent.click(screen.getByRole("link", { name: /完整详情/ }));
    expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
});

test("detail drawer revokes one material by entitlement and reloads owner state", async () => {
    const userWithHostBadge = {
        defaultDisplayUserId: "163337",
        equippedResources: [
            {
                entitlementId: "ent-host-badge",
                equipped: true,
                name: "host",
                quantity: 1,
                remainingQuantity: 1,
                resourceId: 91,
                resourceType: "badge",
                status: "active",
            },
        ],
        resources: [
            {
                entitlementId: "ent-host-badge",
                equipped: true,
                name: "host",
                quantity: 1,
                remainingQuantity: 1,
                resourceId: 91,
                resourceType: "badge",
                status: "active",
            },
        ],
        status: "active",
        userId: "10001",
        username: "tester",
    };
    vi.mocked(getAppUser)
        .mockResolvedValueOnce(userWithHostBadge)
        .mockResolvedValueOnce({ ...userWithHostBadge, equippedResources: [], resources: [] });
    vi.mocked(revokeAppUserResource).mockResolvedValue({});

    render(
        <ToastProvider>
            <ConfirmProvider>
                <MemoryRouter initialEntries={["/app/users"]}>
                    <AppUserDetailProvider>
                        <DetailTrigger />
                    </AppUserDetailProvider>
                </MemoryRouter>
            </ConfirmProvider>
        </ToastProvider>,
    );
    fireEvent.click(screen.getByRole("button", { name: "打开详情" }));
    fireEvent.click(await screen.findByRole("tab", { name: "资源 (2)" }));

    const revokeButtons = screen.getAllByRole("button", { name: "撤回素材 host" });
    expect(revokeButtons).toHaveLength(2);
    fireEvent.click(revokeButtons[0]);
    expect(screen.getByText(/同一资源组的其他素材不受影响/)).toBeInTheDocument();
    fireEvent.click(screen.getByRole("button", { name: "确认撤回" }));

    await waitFor(() =>
        expect(revokeAppUserResource).toHaveBeenCalledWith("10001", "ent-host-badge", {
            reason: "后台用户详情撤回素材：host",
        }),
    );
    await waitFor(() => expect(getAppUser).toHaveBeenCalledTimes(2));
    await waitFor(() => expect(screen.queryByRole("button", { name: "撤回素材 host" })).not.toBeInTheDocument());
    expect(screen.getAllByText("当前无数据")).toHaveLength(2);
});

function DetailTrigger() {
    const { openAppUserDetail } = useAppUserDetail();
    return (
        <button type="button" onClick={() => openAppUserDetail({ userId: "10001", username: "tester" })}>
            打开详情
        </button>
    );
}
