import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { act, render, screen, waitFor } from "@testing-library/react";
import { SessionTestProvider } from "@xtablo/shared/contexts/SessionContext";
import { ThemeProvider } from "@xtablo/shared/contexts/ThemeContext";
import { I18nextProvider } from "react-i18next";
import { createMemoryRouter, RouterProvider } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import testI18n from "../i18n.test";
import { TestUserStoreProvider, type User } from "../providers/UserStoreProvider";
import { PlanningPage } from "./planning";

vi.mock("../hooks/events", () => ({
  useDeleteEvent: () => ({ mutate: vi.fn(), isPending: false }),
  useEventsByTablo: () => ({
    data: [
      {
        event_id: "event-1",
        tablo_id: "tablo-1",
        tablo_name: "Tablo Alpha",
        tablo_color: "bg-blue-500",
        start_date: "2026-04-22",
        start_time: "09:00:00",
        end_time: "10:00:00",
        title: "Kickoff",
        description: "Planning event",
      },
    ],
    isLoading: false,
  }),
}));

vi.mock("../hooks/tablos", () => ({
  useGetAllTabloAccess: () => ({
    data: [{ tablo_id: "tablo-1", is_admin: true }],
  }),
  useTablosList: () => ({
    data: [{ id: "tablo-1", name: "Tablo Alpha" }],
    isLoading: false,
  }),
}));

vi.mock("../providers/UserStoreProvider", async (importOriginal) => {
  const actual = await importOriginal<typeof import("../providers/UserStoreProvider")>();
  return {
    ...actual,
    useIsReadOnlyUser: () => false,
  };
});

vi.mock("../components/EventModal", () => ({
  EventModal: () => <div data-testid="event-modal" />,
}));

const testUser: User = {
  id: "user-1",
  short_user_id: "u1",
  name: "John Doe",
  first_name: "John",
  last_name: "Doe",
  email: "john@example.com",
  avatar_url: null,
  is_client: false,
  client_onboarded_at: null,
  last_signed_in: null,
  plan: "none",
  created_at: new Date("2026-01-01").toISOString(),
};

const createTestRouter = (initialEntry: string) =>
  createMemoryRouter(
    [
      {
        path: "/planning",
        element: <PlanningPage />,
      },
      {
        path: "/tasks",
        element: <div>Tasks page</div>,
      },
    ],
    { initialEntries: [initialEntry] }
  );

const renderPlanningRouter = (initialEntry: string) => {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        staleTime: Infinity,
      },
    },
  });
  const router = createTestRouter(initialEntry);

  return {
    router,
    ...render(
      <I18nextProvider i18n={testI18n}>
        <ThemeProvider>
          <QueryClientProvider client={queryClient}>
            <SessionTestProvider
              testUser={{
                id: testUser.id,
                app_metadata: {},
                aud: "test",
                created_at: "2021-01-01",
                user_metadata: {
                  first_name: testUser.first_name,
                  last_name: testUser.last_name,
                  avatar_url: testUser.avatar_url,
                  full_name: testUser.name,
                },
              }}
            >
              <TestUserStoreProvider user={testUser}>
                <RouterProvider router={router} />
              </TestUserStoreProvider>
            </SessionTestProvider>
          </QueryClientProvider>
        </ThemeProvider>
      </I18nextProvider>
    ),
  };
};

describe("PlanningPage", () => {
  beforeEach(() => {
    testI18n.changeLanguage("fr");
  });

  it("does not throw when leaving the planning page from the events tab", async () => {
    const { router } = renderPlanningRouter("/planning?tab=events");

    expect(screen.getByText("Événements")).toBeInTheDocument();

    await act(async () => {
      await expect(router.navigate("/tasks")).resolves.toBeUndefined();
    });

    await waitFor(() => {
      expect(screen.getByText("Tasks page")).toBeInTheDocument();
    });
  });
});
