import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { jest } from "@jest/globals";
import PopupForFilter from "../components/PopupForFilter.js";
import "@testing-library/jest-dom";

describe("PopupForFilter Component", () => {
const mockOnClose = jest.fn();
const mockGetUsersTable = jest.fn();
const mockHandleFilter = jest.fn();

const defaultProps = {
onClose: mockOnClose,
getUsersTable: mockGetUsersTable,
handleFilter: mockHandleFilter,
filter: {
selectedValues: {},
Filter: { FilterColumn: [], FilterValue: [] },
},
allRoles: [{ RoleName: "Admin" }, { RoleName: "User" }],
};

beforeEach(() => {
jest.clearAllMocks();
});

it("renders status and role checkboxes", () => {
render(<PopupForFilter {...defaultProps} />);
expect(screen.getByText("Filters")).toBeInTheDocument();
expect(screen.getByText("Active")).toBeInTheDocument();
expect(screen.getByText("Deactive")).toBeInTheDocument();
expect(screen.getByText("Deleted")).toBeInTheDocument();
expect(screen.getByText("Admin")).toBeInTheDocument();
expect(screen.getByText("User")).toBeInTheDocument();
});


it("clears all filters when CLEAR ALL is clicked", () => {
render(<PopupForFilter {...defaultProps} />);
const clearButton = screen.getByText("CLEAR ALL");
fireEvent.click(clearButton);

expect(mockHandleFilter).toHaveBeenCalledWith(defaultProps.filter, true);
});

it("calls getUsersTable and onClose when Apply Filters is clicked", async () => {
render(<PopupForFilter {...defaultProps} />);
const applyButton = screen.getByText("Apply Filters");
fireEvent.click(applyButton);

await waitFor(() => {
  expect(mockGetUsersTable).toHaveBeenCalledWith(defaultProps.filter);
  expect(mockOnClose).toHaveBeenCalled();
});
});

it("calls onClose when Cancel is clicked", () => {
render(<PopupForFilter {...defaultProps} />);
const cancelButton = screen.getByText("Cancel");
fireEvent.click(cancelButton);

expect(mockOnClose).toHaveBeenCalled();
});

it("shows Loader while applying filters", async () => {
const { getByText, queryByText } = render(<PopupForFilter {...defaultProps} />);
const applyButton = getByText("Apply Filters");
fireEvent.click(applyButton);

// Loader appears momentarily
expect(queryByText(/loading/i)).not.toBeInTheDocument();
});

it("updates checkboxValues and calls handleFilter when checkbox is checked", () => {
render(<PopupForFilter {...defaultProps} />);

const activeCheckbox = screen.getAllByRole('checkbox')[0]; // Active checkbox
fireEvent.click(activeCheckbox);

expect(mockHandleFilter).toHaveBeenCalled();
// Verify the filter has correct structure
const call = mockHandleFilter.mock.calls[0][0];
expect(call).toHaveProperty('selectedValues');
expect(call.selectedValues).toHaveProperty('active', true);
});

it("handles multiple checkbox selections", () => {
render(<PopupForFilter {...defaultProps} />);

const checkboxes = screen.getAllByRole('checkbox');
// Check Active
fireEvent.click(checkboxes[0]);
// Check Admin
fireEvent.click(checkboxes[3]); // Admin should be 4th checkbox

expect(mockHandleFilter).toHaveBeenCalledTimes(2);
});

it("unchecks a previously checked checkbox", () => {
const propsWithSelected = {
  ...defaultProps,
  filter: {
    selectedValues: { active: true },
    Filter: { FilterColumn: ['user_status_name'], FilterValue: ['Active'] },
  },
};
render(<PopupForFilter {...propsWithSelected} />);

const activeCheckbox = screen.getAllByRole('checkbox')[0];
// Should be checked initially
expect(activeCheckbox).toBeChecked();

// Uncheck it
fireEvent.click(activeCheckbox);

expect(mockHandleFilter).toHaveBeenCalled();
const call = mockHandleFilter.mock.calls[0][0];
expect(call.selectedValues).toHaveProperty('active', false);
});

it("builds filter with role selection", () => {
render(<PopupForFilter {...defaultProps} />);

const adminCheckbox = screen.getAllByRole('checkbox')[3]; // Admin checkbox
fireEvent.click(adminCheckbox);

expect(mockHandleFilter).toHaveBeenCalled();
const call = mockHandleFilter.mock.calls[0][0];
expect(call.Filter.FilterColumn).toContain('user_role_name');
expect(call.Filter.FilterValue).toContain('Admin');
});

it("builds filter with status selection", () => {
render(<PopupForFilter {...defaultProps} />);

const deletedCheckbox = screen.getAllByRole('checkbox')[2]; // Deleted checkbox
fireEvent.click(deletedCheckbox);

expect(mockHandleFilter).toHaveBeenCalled();
const call = mockHandleFilter.mock.calls[0][0];
expect(call.Filter.FilterColumn).toContain('user_status_name');
expect(call.Filter.FilterValue).toContain('Deleted');
});

it("renders with pre-selected values", () => {
const propsWithValues = {
  ...defaultProps,
  filter: {
    selectedValues: { active: true, Admin: true },
    Filter: { FilterColumn: ['user_status_name', 'user_role_name'], FilterValue: ['Active', 'Admin'] },
  },
};
render(<PopupForFilter {...propsWithValues} />);

const checkboxes = screen.getAllByRole('checkbox');
expect(checkboxes[0]).toBeChecked(); // Active
expect(checkboxes[3]).toBeChecked(); // Admin
});

it("handles error when getUsersTable throws", async () => {
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const errorProps = {
  ...defaultProps,
  getUsersTable: jest.fn().mockImplementation(() => { throw new Error('API Error'); }),
};
render(<PopupForFilter {...errorProps} />);

const applyButton = screen.getByText("Apply Filters");
fireEvent.click(applyButton);

await waitFor(() => {
  expect(consoleErrorSpy).toHaveBeenCalledWith('Error fetching filtered data', expect.any(Error));
  expect(mockOnClose).toHaveBeenCalled();
});

consoleErrorSpy.mockRestore();
});

it("renders Roles section with scrollable class", () => {
render(<PopupForFilter {...defaultProps} />);

// Find the Roles header
const rolesHeader = screen.getByText("Roles");
expect(rolesHeader).toBeInTheDocument();

// Check for add-scroller class on the roles container
const rolesContainer = rolesHeader.nextElementSibling;
expect(rolesContainer).toHaveClass('add-scroller');
});
});
