import { fireEvent, render, screen } from "@testing-library/react";
import { afterEach, expect, test, vi } from "vitest";
import { HostCoinSellersPage } from "./HostCoinSellersPage.jsx";
import { useHostCoinSellersPage } from "@/features/host-org/hooks/useHostCoinSellersPage.js";

const mocks = vi.hoisted(() => ({
    ledgerTable: vi.fn(),
    openSellerLedger: vi.fn(),
}));

vi.mock("@/features/host-org/hooks/useHostCoinSellersPage.js", () => ({
    useHostCoinSellersPage: vi.fn(),
}));

vi.mock("@/features/operations/components/CoinSellerLedgerTable.jsx", () => ({
    CoinSellerLedgerTable: (props) => {
        mocks.ledgerTable(props);
        return <div data-testid="coin-seller-ledger-table">{props.sellerUserId}</div>;
    },
}));

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

test("coin seller row action opens seller ledger with current seller", () => {
    vi.mocked(useHostCoinSellersPage).mockReturnValue(pageFixture());

    render(<HostCoinSellersPage />);

    const ledgerButton = screen.getAllByLabelText("币商流水").find((node) => node.tagName.toLowerCase() === "button");
    fireEvent.click(ledgerButton);

    expect(mocks.openSellerLedger).toHaveBeenCalledWith(expect.objectContaining({ userId: "3001" }));
});

test("coin seller table shows cumulative USDT and hides creator id column", () => {
    vi.mocked(useHostCoinSellersPage).mockReturnValue(pageFixture());

    render(<HostCoinSellersPage />);

    expect(screen.queryByText("创建人 ID")).not.toBeInTheDocument();
    expect(screen.getByText("累充USDT")).toBeInTheDocument();
    expect(screen.getByText("12.5")).toBeInTheDocument();
});

test("coin seller balance and cumulative USDT headers request sorting", () => {
    const changeSort = vi.fn();
    vi.mocked(useHostCoinSellersPage).mockReturnValue(pageFixture({ changeSort }));

    render(<HostCoinSellersPage />);

    fireEvent.click(screen.getByLabelText("按币商余额降序排序"));
    fireEvent.click(screen.getByLabelText("按累充USDT降序排序"));

    expect(changeSort).toHaveBeenCalledWith("merchant_balance");
    expect(changeSort).toHaveBeenCalledWith("total_recharge_usdt");
});

test("coin seller contact edits inline and saves on blur", () => {
    const saveSellerContact = vi.fn();
    vi.mocked(useHostCoinSellersPage).mockReturnValue(
        pageFixture({
            abilities: { ...pageFixture().abilities, canUpdate: true },
            saveSellerContact,
        }),
    );

    render(<HostCoinSellersPage />);

    fireEvent.click(screen.getByRole("button", { name: "菲律賓 +63" }));
    const input = screen.getByDisplayValue("菲律賓 +63");
    fireEvent.change(input, { target: { value: "+63" } });
    fireEvent.blur(input);

    expect(saveSellerContact).toHaveBeenCalledWith(expect.objectContaining({ userId: "3001" }), "+63");
});

test("coin seller ledger drawer passes locked seller id to shared table", () => {
    const seller = sellerFixture();
    vi.mocked(useHostCoinSellersPage).mockReturnValue(pageFixture({ activeAction: "ledger", selectedSeller: seller }));

    render(<HostCoinSellersPage />);

    expect(screen.getByTestId("coin-seller-ledger-table")).toHaveTextContent("3001");
    expect(mocks.ledgerTable).toHaveBeenCalledWith(expect.objectContaining({ lockedSeller: seller, sellerUserId: "3001" }));
});

function pageFixture(patch = {}) {
    return {
        abilities: {
            canCreate: false,
            canExchangeRate: false,
            canLedger: true,
            canStockCredit: false,
            canUpdate: false,
            canView: true,
        },
        activeAction: "",
        addRateTier: vi.fn(),
        changeQuery: vi.fn(),
        changeRateRegionId: vi.fn(),
        changeRegionId: vi.fn(),
        changeSort: vi.fn(),
        changeStatus: vi.fn(),
        closeAction: vi.fn(),
        contactSavingIds: {},
        createForm: { contact: "", targetUserId: "" },
        data: { items: [sellerFixture()], page: 1, pageSize: 50, total: 1 },
        editForm: { contact: "", targetUserId: "" },
        error: null,
        loading: false,
        loadingAction: "",
        loadingRates: false,
        loadingRegions: false,
        openCreateSeller: vi.fn(),
        openEditSeller: vi.fn(),
        openRateSettings: vi.fn(),
        openSellerLedger: mocks.openSellerLedger,
        openStockCredit: vi.fn(),
        page: 1,
        query: "",
        rateRegionId: "",
        rateTiers: [],
        regionId: "",
        regionOptions: [],
        reload: vi.fn(),
        removeRateTier: vi.fn(),
        resetFilters: vi.fn(),
        saveSellerContact: vi.fn(),
        selectedSeller: null,
        setCreateForm: vi.fn(),
        setEditForm: vi.fn(),
        setPage: vi.fn(),
        setStockForm: vi.fn(),
        status: "",
        stockDebitForm: { coinAmount: "", reason: "", rechargeAmount: "" },
        stockForm: { coinAmount: "", reason: "", rechargeAmount: "", type: "usdt_purchase" },
        sortBy: "",
        sortDirection: "",
        submitCreateSeller: vi.fn(),
        submitEditSeller: vi.fn(),
        submitRateSettings: vi.fn(),
        submitStockCredit: vi.fn(),
        toggleSeller: vi.fn(),
        updateRateTier: vi.fn(),
        ...patch,
    };
}

function sellerFixture() {
    return {
        avatar: "",
        contact: "菲律賓 +63",
        displayUserId: "164425",
        merchantAssetType: "COIN_SELLER_COIN",
        merchantBalance: 9400000,
        regionId: 1,
        status: "active",
        totalRechargeUsdtMicro: 12500000,
        updatedAtMs: 1760000000000,
        userId: "3001",
        username: "Flower92",
    };
}
