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

describe("PopupForm Component", () => {
  const allRoles = [
    { Role_Id: 1, RoleName: "Admin", Status: "Active" },
    { Role_Id: 2, RoleName: "User", Status: "Active" },
    { Role_Id: 3, RoleName: "Inactive Role", Status: "InActive" },
  ];

  const defaultProps = {
    onClose: jest.fn(),
    handleInputChange: jest.fn(),
    setFormData: jest.fn(),
    onSubmit: jest.fn(),
    formData: {
      firstName: "",
      lastName: "",
      email: "",
      role: "",
    },
    errors: {},
    setErrors: jest.fn(),
    allRoles,
    user: { whitelistdomain: "company.com,test.com" },
  };

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

  it("should render form fields", () => {
    render(<PopupForm {...defaultProps} />);

    // Use getAllByText since "Add User" appears multiple times (heading and button)
    expect(screen.getAllByText("Add User").length).toBeGreaterThan(0);
    expect(screen.getByPlaceholderText("First Name")).toBeInTheDocument();
    expect(screen.getByPlaceholderText("Last Name")).toBeInTheDocument();
    expect(screen.getByPlaceholderText("Email")).toBeInTheDocument();
    expect(screen.getByText("Select Role")).toBeInTheDocument();
  });

  it("should call onClose when close button is clicked", () => {
    render(<PopupForm {...defaultProps} />);

    const closeButtons = screen.getAllByRole("button");
    fireEvent.click(closeButtons[0]); // First button is close

    expect(defaultProps.onClose).toHaveBeenCalledTimes(1);
  });

  it("should call handleInputChange when typing in text fields", () => {
    render(<PopupForm {...defaultProps} />);

    const firstNameInput = screen.getByPlaceholderText("First Name");
    fireEvent.change(firstNameInput, { target: { value: "John", name: "firstName" } });

    expect(defaultProps.handleInputChange).toHaveBeenCalled();
  });

  it("should call setFormData when role is selected", () => {
    render(<PopupForm {...defaultProps} />);

    // Open the select dropdown
    const selectElement = screen.getByRole("combobox");
    fireEvent.mouseDown(selectElement);

    // Select a role
    const option = screen.getByText("User");
    fireEvent.click(option);

    expect(defaultProps.setFormData).toHaveBeenCalledWith({
      ...defaultProps.formData,
      role: 2,
    });
  });

  it("should show validation errors", () => {
    const propsWithErrors = {
      ...defaultProps,
      errors: {
        firstName: "First Name is required.",
        lastName: "Last Name is required.",
        email: "Email is required.",
        role: "Role is required.",
      },
    };

    render(<PopupForm {...propsWithErrors} />);

    expect(screen.getByText("First Name is required.")).toBeInTheDocument();
    expect(screen.getByText("Last Name is required.")).toBeInTheDocument();
    expect(screen.getByText("Email is required.")).toBeInTheDocument();
    expect(screen.getByText("Role is required.")).toBeInTheDocument();
  });

  it("should validate form on submit with empty fields", () => {
    render(<PopupForm {...defaultProps} />);

    // Find and click the submit button (Add User)
    const submitButton = screen.getByRole("button", { name: /add user/i });
    fireEvent.click(submitButton);

    // setErrors should be called with validation errors
    expect(defaultProps.setErrors).toHaveBeenCalled();
  });

  it("should call onSubmit when form is valid", () => {
    const validProps = {
      ...defaultProps,
      formData: {
        firstName: "John",
        lastName: "Doe",
        email: "john@company.com",
        role: 1,
      },
    };

    render(<PopupForm {...validProps} />);

    const submitButton = screen.getByRole("button", { name: /add user/i });
    fireEvent.click(submitButton);

    expect(validProps.onSubmit).toHaveBeenCalled();
  });

  it("should validate email domain", () => {
    const invalidEmailProps = {
      ...defaultProps,
      formData: {
        firstName: "John",
        lastName: "Doe",
        email: "john@invalid.com",
        role: 1,
      },
    };

    render(<PopupForm {...invalidEmailProps} />);

    const submitButton = screen.getByRole("button", { name: /add user/i });
    fireEvent.click(submitButton);

    // Should set errors for invalid domain
    expect(defaultProps.setErrors).toHaveBeenCalled();
  });

  it("should filter out inactive roles from dropdown", () => {
    render(<PopupForm {...defaultProps} />);

    const selectElement = screen.getByRole("combobox");
    fireEvent.mouseDown(selectElement);

    // Active roles should be visible
    expect(screen.getByText("Admin")).toBeInTheDocument();
    expect(screen.getByText("User")).toBeInTheDocument();

    // Inactive role should not be rendered as menuitem
    const menuItems = screen.getAllByRole("option");
    const roleNames = menuItems.map((item) => item.textContent);
    expect(roleNames).not.toContain("Inactive Role");
  });

  it("should display form values correctly", () => {
    const propsWithValues = {
      ...defaultProps,
      formData: {
        firstName: "Jane",
        lastName: "Smith",
        email: "jane@company.com",
        role: 2,
      },
    };

    render(<PopupForm {...propsWithValues} />);

    expect(screen.getByDisplayValue("Jane")).toBeInTheDocument();
    expect(screen.getByDisplayValue("Smith")).toBeInTheDocument();
    expect(screen.getByDisplayValue("jane@company.com")).toBeInTheDocument();
  });
});
