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(),
    openSubSellerList: vi.fn(),
    toggleSubCoinSellerPermission: 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("子币商权限")).toBeInTheDocument();
    expect(screen.getByText("子币商数量")).toBeInTheDocument();
    expect(screen.getByText("12.5")).toBeInTheDocument();
});

test("coin seller sub seller count opens direct child seller drawer", () => {
    const seller = sellerFixture({ subCoinSellerCount: 2 });
    vi.mocked(useHostCoinSellersPage).mockReturnValue(
        pageFixture({
            data: { items: [seller], page: 1, pageSize: 50, total: 1 },
        }),
    );

    render(<HostCoinSellersPage />);

    fireEvent.click(screen.getByRole("button", { name: "2" }));

    expect(mocks.openSubSellerList).toHaveBeenCalledWith(seller);
});

test("coin seller sub permission switch toggles through the page hook", () => {
    const seller = sellerFixture();
    vi.mocked(useHostCoinSellersPage).mockReturnValue(
        pageFixture({
            abilities: { ...pageFixture().abilities, canUpdate: true },
            data: { items: [seller], page: 1, pageSize: 50, total: 1 },
        }),
    );

    render(<HostCoinSellersPage />);

    const switchInput = screen.getByRole("switch", { name: "关闭子币商权限" });
    expect(switchInput).toBeChecked();

    fireEvent.click(switchInput);

    expect(mocks.toggleSubCoinSellerPermission).toHaveBeenCalledWith(seller, false);
});

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" }),
    );
});

test("coin seller sub seller drawer renders approved direct children", () => {
    const seller = sellerFixture({ subCoinSellerCount: 1 });
    const child = sellerFixture({
        displayUserId: "168933",
        merchantBalance: 1200,
        subCoinSellerCount: 0,
        userId: "3002",
        username: "Child seller",
    });
    vi.mocked(useHostCoinSellersPage).mockReturnValue(
        pageFixture({
            activeAction: "sub-sellers",
            data: { items: [seller], page: 1, pageSize: 50, total: 1 },
            selectedSeller: seller,
            subSellerData: { items: [child], page: 1, pageSize: 50, total: 1 },
        }),
    );

    render(<HostCoinSellersPage />);

    expect(screen.getByText("子币商列表 - Flower92 / 164425")).toBeInTheDocument();
    expect(screen.getByText("Child seller")).toBeInTheDocument();
    expect(screen.getByText("168933")).toBeInTheDocument();
});

test("coin seller create form includes sub permission switch", () => {
    const setCreateForm = vi.fn();
    vi.mocked(useHostCoinSellersPage).mockReturnValue(
        pageFixture({
            abilities: { ...pageFixture().abilities, canCreate: true },
            activeAction: "create",
            createForm: { canManageSubCoinSellers: true, contact: "", targetUserId: "" },
            setCreateForm,
        }),
    );

    render(<HostCoinSellersPage />);

    const switchInput = screen.getByRole("switch", { name: "子币商权限" });
    expect(switchInput).toBeChecked();

    fireEvent.click(switchInput);

    expect(setCreateForm).toHaveBeenCalledWith(
        expect.objectContaining({
            canManageSubCoinSellers: false,
        }),
    );
});

test("coin seller edit form preserves sub permission field", () => {
    const setEditForm = vi.fn();
    vi.mocked(useHostCoinSellersPage).mockReturnValue(
        pageFixture({
            abilities: { ...pageFixture().abilities, canUpdate: true },
            activeAction: "edit",
            editForm: { canManageSubCoinSellers: false, contact: "+63", targetUserId: "3001" },
            setEditForm,
        }),
    );

    render(<HostCoinSellersPage />);

    const switchInput = screen.getByRole("switch", { name: "子币商权限" });
    expect(switchInput).not.toBeChecked();

    fireEvent.click(switchInput);

    expect(setEditForm).toHaveBeenCalledWith(
        expect.objectContaining({
            canManageSubCoinSellers: true,
        }),
    );
});

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: { canManageSubCoinSellers: true, contact: "", targetUserId: "" },
        data: { items: [sellerFixture()], page: 1, pageSize: 50, total: 1 },
        editForm: { canManageSubCoinSellers: true, 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(),
        openSubSellerList: mocks.openSubSellerList,
        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(),
        setSubSellerPage: vi.fn(),
        setStockForm: vi.fn(),
        status: "",
        subSellerData: { items: [], page: 1, pageSize: 50, total: 0 },
        subSellerPage: 1,
        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(),
        toggleSubCoinSellerPermission: mocks.toggleSubCoinSellerPermission,
        toggleSeller: vi.fn(),
        updateRateTier: vi.fn(),
        ...patch,
    };
}

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