import React from "react";
import { render, screen, waitFor, fireEvent } from "@testing-library/react";
import { jest } from "@jest/globals";
import Users from "../pages/Users.js";
import { UserProvider } from "../context/UserContext.js";
import { MemoryRouter } from "react-router-dom";

const mockUserContext = {
  permissions: [{ Path: "/users", Permission_Id: "1" }],
};

const renderComponent = (initialRoute = "/users", state = {}) => {
  return render(
    <MemoryRouter initialEntries={[{ pathname: initialRoute, state }]}>
      <UserProvider value={mockUserContext}>
        <Users />
      </UserProvider>
    </MemoryRouter>
  );
};

describe("Users Component", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    localStorage.setItem("user", JSON.stringify({ user_email: "test@test.com" }));
    localStorage.setItem("permissions", JSON.stringify([]));
  });

  afterEach(() => {
    localStorage.clear();
  });

  it("should render the component", () => {
    renderComponent();
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  it("should render loader initially", () => {
    renderComponent();
    expect(screen.getByTestId("loader")).toBeInTheDocument();
  });

  it("should render date filter dropdown", () => {
    renderComponent();
    const comboboxes = screen.getAllByRole("combobox");
    expect(comboboxes.length).toBeGreaterThan(0);
  });

  it("should render search input", () => {
    renderComponent();
    expect(screen.getByRole("textbox")).toBeInTheDocument();
  });

  it("should handle search with text", async () => {
    renderComponent();
    
    const searchInput = screen.getByRole("textbox");
    fireEvent.change(searchInput, { target: { value: "test" } });
    
    await waitFor(() => {
      expect(searchInput.value).toBe("test");
    });
  });

  it("should render with from button state", () => {
    renderComponent("/users", { from: "button" });
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  it("should handle date filter change", async () => {
    renderComponent();
    
    const dateFilter = screen.getAllByRole("combobox")[0];
    fireEvent.mouseDown(dateFilter);
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  it("should render status dropdown filter", () => {
    renderComponent();
    const comboboxes = screen.getAllByRole("combobox");
    // At least 2 dropdowns: date filter and status filter
    expect(comboboxes.length).toBeGreaterThanOrEqual(2);
  });

  it("should handle list filter change to Active Users", async () => {
    renderComponent();
    
    // Find the status dropdown and interact with it
    const comboboxes = screen.getAllByRole("combobox");
    if (comboboxes.length >= 2) {
      const statusDropdown = comboboxes[comboboxes.length - 1];
      fireEvent.mouseDown(statusDropdown);
      
      // Wait for options to appear and click Active Users
      await waitFor(() => {
        const option = screen.getByText("Active Users");
        if (option) {
          fireEvent.click(option);
        }
      });
    }
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  it("should handle list filter change to All Users", async () => {
    renderComponent("/users", { from: "button" }); // Start with active users filter
    
    // Find the status dropdown and interact with it
    const comboboxes = screen.getAllByRole("combobox");
    if (comboboxes.length >= 2) {
      const statusDropdown = comboboxes[comboboxes.length - 1];
      fireEvent.mouseDown(statusDropdown);
      
      // Wait for options to appear and click All Users
      await waitFor(() => {
        const option = screen.getByText("All Users");
        if (option) {
          fireEvent.click(option);
        }
      });
    }
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  it("should render columns correctly", () => {
    renderComponent();
    // Common table should be rendered with columns
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  it("should handle clear search", async () => {
    renderComponent();
    
    const searchInput = screen.getByRole("textbox");
    fireEvent.change(searchInput, { target: { value: "test" } });
    
    await waitFor(() => {
      expect(searchInput.value).toBe("test");
    });

    // Find and click clear button
    const clearButton = screen.queryByRole("button", { name: /clear/i });
    if (clearButton) {
      fireEvent.click(clearButton);
    }
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  it("should set initial filter based on location state", () => {
    renderComponent("/users", { from: "button" });
    
    // When from is "button", it should show Active Users
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  it("should render with outer-body class", () => {
    const { container } = renderComponent();
    expect(container.querySelector(".outer-body")).toBeInTheDocument();
  });

  it("should render filters wrapper", () => {
    const { container } = renderComponent();
    expect(container.querySelector(".filters-wrapper")).toBeInTheDocument();
  });
});
