import { QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen } from '@testing-library/react';
import { WeightEntry } from "@/components/Weight/models/WeightEntry";
import { getWeights } from "@/components/Weight/api/weight";
import { testQueryClient } from "@/tests/queryClient";
import { BodyWeight } from "./BodyWeight";
import { FilterType } from "../widgets/FilterButtons";
import type { Mock } from 'vitest';

vi.mock("@/components/Weight/api/weight");
console.log = vi.fn();

describe("Test BodyWeight component", () => {

    // See https://github.com/maslianok/react-resize-detector#testing-with-enzyme-and-jest
    afterEach(() => {
        vi.restoreAllMocks();
    });

    // Arrange
    const weightData = [
        new WeightEntry(new Date('2021-12-10'), 80, 1),
        new WeightEntry(new Date('2021-12-20'), 90, 2),
    ];

    test('renders without crashing', async () => {

        (getWeights as Mock).mockImplementation(() => Promise.resolve(weightData));

        // Act
        render(
            <QueryClientProvider client={testQueryClient}>
                <BodyWeight />
            </QueryClientProvider>
        );

        // Assert
        expect(getWeights).toHaveBeenCalledTimes(1);

        // Both weights are found in the document
        expect(await screen.findByText("80")).toBeInTheDocument();
        expect(await screen.findByText("90")).toBeInTheDocument();
    });

    test('changes filter and updates displayed data', async () => {

        // Mock the getWeights response based on the filter
        (getWeights as Mock).mockImplementation((filter: FilterType) => {
            if (filter === 'lastYear') {
                return Promise.resolve(weightData);
            } else if (filter === 'lastMonth') {
                return Promise.resolve([]);
            }
            return Promise.resolve([]);
        });

        render(
            <QueryClientProvider client={testQueryClient}>
                <BodyWeight />
            </QueryClientProvider>
        );

        // Initially should display data for last year
        expect(await screen.findByText("80")).toBeInTheDocument();
        expect(await screen.findByText("90")).toBeInTheDocument();

        // Change filter to 'lastMonth'
        const filterButton = screen.getByRole('button', { name: /lastMonth/i });
        fireEvent.click(filterButton);

        // Expect getWeights to be called with 'lastMonth'
        expect(getWeights).toHaveBeenCalledWith('lastMonth');

        // Check that entries for last year are no longer in the document
        expect(screen.queryByText("80")).not.toBeInTheDocument();
        expect(screen.queryByText("90")).not.toBeInTheDocument();
    });
});
