import { fireEvent, render, screen } from "@testing-library/react";
import { afterEach, expect, test, vi } from "vitest";
import { MemoryRouter, useLocation } from "react-router-dom";
import { HostAgenciesPage } from "./HostAgenciesPage.jsx";
import { HostBdLeadersPage } from "./HostBdLeadersPage.jsx";
import { HostBdsPage } from "./HostBdsPage.jsx";
import { HostHostsPage } from "./HostHostsPage.jsx";
import { useHostAgenciesPage } from "@/features/host-org/hooks/useHostAgenciesPage.js";
import { useHostBdsPage } from "@/features/host-org/hooks/useHostBdsPage.js";
import { useHostHostsPage } from "@/features/host-org/hooks/useHostHostsPage.js";

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

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

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

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

test("agency list salary wallet header requests salary wallet sorting", () => {
    const changeSort = vi.fn();
    vi.mocked(useHostAgenciesPage).mockReturnValue(agencyPageFixture({ changeSort }));

    renderWithRouter(<HostAgenciesPage />);
    fireEvent.click(screen.getByLabelText("按工资钱包降序排序"));

    expect(changeSort).toHaveBeenCalledWith("salary_wallet");
});

test("agency host count opens filtered host list", () => {
    vi.mocked(useHostAgenciesPage).mockReturnValue(agencyPageFixture());

    const location = renderWithRouter(<HostAgenciesPage />);
    fireEvent.click(screen.getByRole("button", { name: "查看 Agency 9001 的 Host 列表" }));

    expect(location.current()).toBe("/host/hosts?agency_id=9001");
});

test("closed agency status switch can reopen agency", () => {
    const toggleAgencyStatusFromList = vi.fn();
    vi.mocked(useHostAgenciesPage).mockReturnValue(
        agencyPageFixture({
            abilities: { canCreate: false, canDelete: false, canSalaryAdjust: false, canStatus: true },
            data: { items: [{ ...agencyFixture(), joinEnabled: false, status: "closed" }], page: 1, pageSize: 50, total: 1 },
            toggleAgencyStatusFromList,
        }),
    );

    renderWithRouter(<HostAgenciesPage />);
    fireEvent.click(screen.getByRole("switch", { name: "启用 Agency" }));

    expect(toggleAgencyStatusFromList).toHaveBeenCalledWith(expect.objectContaining({ agencyId: "9001" }), true);
});

test("bd leader list salary wallet header requests salary wallet sorting", () => {
    const changeSort = vi.fn();
    vi.mocked(useHostBdsPage).mockReturnValue(bdPageFixture({ changeSort, profileType: "leader" }));

    render(<HostBdLeadersPage />);
    fireEvent.click(screen.getByLabelText("按工资钱包降序排序"));

    expect(changeSort).toHaveBeenCalledWith("salary_wallet");
});

test("bd list salary wallet header requests salary wallet sorting", () => {
    const changeSort = vi.fn();
    vi.mocked(useHostBdsPage).mockReturnValue(bdPageFixture({ changeSort, profileType: "bd" }));

    render(<HostBdsPage />);
    fireEvent.click(screen.getByLabelText("按工资钱包降序排序"));

    expect(changeSort).toHaveBeenCalledWith("salary_wallet");
});

test("bd list renders child agency count", () => {
    vi.mocked(useHostBdsPage).mockReturnValue(
        bdPageFixture({
            data: { items: [{ ...bdFixture(), agencyCount: 7 }], page: 1, pageSize: 50, total: 1 },
            profileType: "bd",
        }),
    );

    render(<HostBdsPage />);

    expect(screen.getByText("子 Agency")).toBeInTheDocument();
    expect(screen.getByText("7")).toBeInTheDocument();
});

test("host list salary wallet header requests salary wallet sorting", () => {
    const changeSort = vi.fn();
    vi.mocked(useHostHostsPage).mockReturnValue(hostPageFixture({ changeSort }));

    render(<HostHostsPage />);
    fireEvent.click(screen.getByLabelText("按工资钱包降序排序"));

    expect(changeSort).toHaveBeenCalledWith("salary_wallet");
});

function agencyPageFixture(patch = {}) {
    return {
        abilities: { canCreate: false, canDelete: false, canSalaryAdjust: false, canStatus: false },
        activeAction: "",
        agencyForm: { joinEnabled: true, name: "", ownerUserId: "", parentBdUserId: "", reason: "" },
        changeParentBdUserId: vi.fn(),
        changeQuery: vi.fn(),
        changeRegionId: vi.fn(),
        changeSort: vi.fn(),
        changeStatus: vi.fn(),
        closeAction: vi.fn(),
        closeAgencyFromList: vi.fn(),
        data: { items: [agencyFixture()], page: 1, pageSize: 50, total: 1 },
        error: null,
        loading: false,
        loadingAction: "",
        loadingRegions: false,
        openAgencyForm: vi.fn(),
        page: 1,
        parentBdUserId: "",
        query: "",
        regionId: "",
        regionOptions: [],
        reload: vi.fn(),
        removeAgencyFromList: vi.fn(),
        resetFilters: vi.fn(),
        setAgencyForm: vi.fn(),
        setPage: vi.fn(),
        sortBy: "",
        sortDirection: "",
        status: "",
        submitAgency: vi.fn(),
        toggleAgencyStatusFromList: vi.fn(),
        toggleAgencyJoinEnabledFromList: vi.fn(),
        ...patch,
    };
}

function bdPageFixture(patch = {}) {
    return {
        abilities: { canCreate: false, canSalaryAdjust: false, canUpdate: false, canView: true },
        activeAction: "",
        bdForm: { parentLeaderUserId: "", reason: "", targetUserId: "" },
        bdLeaderForm: { positionAlias: "", reason: "", targetUserId: "" },
        bdUserLookup: { error: "", loading: false, user: null },
        changeParentLeaderUserId: vi.fn(),
        changeQuery: vi.fn(),
        changeRegionId: vi.fn(),
        changeSort: vi.fn(),
        changeStatus: vi.fn(),
        closeAction: vi.fn(),
        data: { items: [bdFixture()], page: 1, pageSize: 50, total: 1 },
        error: null,
        leaderBDs: { items: [], page: 1, pageSize: 50, total: 0 },
        leaderBDsError: "",
        leaderBDsLoading: false,
        loadLeaderBDs: vi.fn(),
        loading: false,
        loadingAction: "",
        loadingRegions: false,
        openAddLeaderBD: vi.fn(),
        openBDForm: vi.fn(),
        openBDLeaderForm: vi.fn(),
        openLeaderBDs: vi.fn(),
        page: 1,
        parentLeaderUserId: "",
        profileType: "bd",
        query: "",
        regionId: "",
        regionOptions: [],
        reload: vi.fn(),
        removeBDLeader: vi.fn(),
        resetFilters: vi.fn(),
        saveBDLeaderPositionAlias: vi.fn(),
        selectedLeader: null,
        setBDForm: vi.fn(),
        setBDLeaderForm: vi.fn(),
        setPage: vi.fn(),
        sortBy: "",
        sortDirection: "",
        status: "",
        submitBD: vi.fn(),
        submitBDLeader: vi.fn(),
        submitLeaderBD: vi.fn(),
        toggleBD: vi.fn(),
        toggleBDLeader: vi.fn(),
        ...patch,
    };
}

function hostPageFixture(patch = {}) {
    return {
        abilities: { canSalaryAdjust: false, canView: true },
        agencyId: "",
        changeAgencyId: vi.fn(),
        changeQuery: vi.fn(),
        changeRegionId: vi.fn(),
        changeSort: vi.fn(),
        changeStatus: vi.fn(),
        data: { items: [hostFixture()], page: 1, pageSize: 50, total: 1 },
        diamondSortDirection: "",
        error: null,
        loading: false,
        loadingRegions: false,
        page: 1,
        query: "",
        regionId: "",
        regionOptions: [],
        reload: vi.fn(),
        resetFilters: vi.fn(),
        setPage: vi.fn(),
        sortBy: "",
        sortDirection: "",
        status: "",
        toggleDiamondSort: vi.fn(),
        ...patch,
    };
}

function agencyFixture() {
    return {
        activeHostCount: 12,
        agencyId: "9001",
        joinEnabled: true,
        name: "Agency One",
        ownerDisplayUserId: "160001",
        ownerUserId: "1001",
        ownerUsername: "agency_owner",
        parentBdUserId: "2001",
        regionName: "中东区",
        salaryWallet: { availableAmount: 1200 },
        status: "active",
        updatedAtMs: 1760000000000,
    };
}

function bdFixture() {
    return {
        agencyCount: 3,
        createdAtMs: 1760000000000,
        displayUserId: "160002",
        parentLeaderUserId: "3001",
        regionName: "中东区",
        role: "bd",
        salaryWallet: { availableAmount: 1200 },
        status: "active",
        subBdCount: 0,
        updatedAtMs: 1760000000000,
        userId: "2001",
        username: "bd_user",
    };
}

function hostFixture() {
    return {
        currentAgencyId: "9001",
        diamond: 100,
        displayUserId: "160003",
        firstBecameHostAtMs: 1760000000000,
        regionName: "中东区",
        salaryWallet: { availableAmount: 1200 },
        source: "agency_invite",
        status: "active",
        updatedAtMs: 1760000000000,
        userId: "3001",
        username: "host_user",
    };
}

function renderWithRouter(ui) {
    const location = { value: "" };
    function LocationProbe() {
        const currentLocation = useLocation();
        location.value = `${currentLocation.pathname}${currentLocation.search}`;
        return null;
    }
    render(
        <MemoryRouter initialEntries={["/host/agencies"]}>
            {ui}
            <LocationProbe />
        </MemoryRouter>,
    );
    return { current: () => location.value };
}
