import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { adminApi } from "../lib/api";
import { DataExplorerPage } from "./DataExplorerPage";

vi.mock("../lib/api", () => ({
  adminApi: {
    get: vi.fn(),
    patch: vi.fn(),
  },
}));

describe("DataExplorerPage", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("loads rows for the selected table and saves approved edits", async () => {
    vi.mocked(adminApi.get).mockImplementation(async (path: string) => {
      if (path === "/admin/tables") {
        return {
          data: {
            tables: [
              { id: "profiles", label: "Users" },
              { id: "tablo_access", label: "Tablo Access" },
            ],
          },
        };
      }

      if (path === "/admin/tables/profiles/meta") {
        return {
          data: {
            columns: [
              { id: "id", label: "ID" },
              { id: "email", label: "Email" },
              { id: "first_name", label: "First name" },
            ],
            editableFields: ["first_name"],
            id: "profiles",
            label: "Users",
            primaryKey: "id",
          },
        };
      }

      if (path === "/admin/tables/profiles/rows") {
        return {
          data: {
            rows: [
              {
                email: "test_owner@example.com",
                first_name: "Test",
                id: "user-1",
              },
            ],
          },
        };
      }

      throw new Error(`Unexpected path: ${path}`);
    });
    vi.mocked(adminApi.patch).mockResolvedValue({
      data: {
        row: {
          email: "test_owner@example.com",
          first_name: "Ada",
          id: "user-1",
        },
      },
    });

    render(
      <MemoryRouter>
        <DataExplorerPage />
      </MemoryRouter>
    );

    expect(await screen.findByRole("button", { name: /users/i })).toBeInTheDocument();
    expect(await screen.findByText(/email/i)).toBeInTheDocument();
    expect(await screen.findByText(/test_owner@example.com/i)).toBeInTheDocument();

    fireEvent.click(screen.getByText(/test_owner@example.com/i));
    fireEvent.change(screen.getByLabelText(/first name/i), {
      target: { value: "Ada" },
    });
    fireEvent.click(screen.getByRole("button", { name: /review changes/i }));
    fireEvent.click(screen.getByRole("button", { name: /confirm update/i }));

    await waitFor(() =>
      expect(adminApi.patch).toHaveBeenCalledWith("/admin/tables/profiles/rows/user-1", {
        first_name: "Ada",
      })
    );
    expect(await screen.findByText(/row updated and logged/i)).toBeInTheDocument();
  });
});
