import { jest } from "@jest/globals";
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import ConsentPopup from "../common/ConsentPopup.js";
import { consentType } from "../constants/userConstants.js";

describe("ConsentPopup Component", () => {
  const defaultProps = {
    consentTypeAction: "default",
    title: "Confirm Action",
    message: "Are you sure you want to proceed?",
    onClose: jest.fn(),
    onAccept: jest.fn(),
  };

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

  it("should render title and message", () => {
    render(<ConsentPopup {...defaultProps} />);

    expect(screen.getByText("Confirm Action")).toBeInTheDocument();
    expect(screen.getByText("Are you sure you want to proceed?")).toBeInTheDocument();
  });

  it("should render default button labels", () => {
    render(<ConsentPopup {...defaultProps} />);

    expect(screen.getByText("Yes")).toBeInTheDocument();
    expect(screen.getByText("No")).toBeInTheDocument();
  });

  it("should render custom button labels", () => {
    render(
      <ConsentPopup
        {...defaultProps}
        actionMessagePositive="Confirm"
        actionMessageNegative="Cancel"
      />
    );

    expect(screen.getByText("Confirm")).toBeInTheDocument();
    expect(screen.getByText("Cancel")).toBeInTheDocument();
  });

  it("should call onAccept and onClose when accepting", () => {
    render(<ConsentPopup {...defaultProps} />);

    fireEvent.click(screen.getByText("Yes"));

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

  it("should call onClose when declining", () => {
    render(<ConsentPopup {...defaultProps} />);

    fireEvent.click(screen.getByText("No"));

    expect(defaultProps.onClose).toHaveBeenCalledTimes(1);
    expect(defaultProps.onAccept).not.toHaveBeenCalled();
  });

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

    // Click the close icon button (first button in the header)
    const closeButtons = screen.getAllByRole("button");
    fireEvent.click(closeButtons[0]); // Close icon is first button

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

  it("should render role selection for DeleteRole with totalAccessUsers", () => {
    const allRoles = [
      { Role_Id: 1, RoleName: "Admin", Status: "Active" },
      { Role_Id: 2, RoleName: "User", Status: "Active" },
      { Role_Id: 3, RoleName: "Manager", Status: "InActive" },
    ];

    render(
      <ConsentPopup
        {...defaultProps}
        consentTypeAction={consentType.DeleteRole}
        editRoleData={{ Role_Id: 1 }}
        totalAccessUsers={5}
        allRoles={allRoles}
        setChangedRoleId={jest.fn()}
      />
    );

    expect(screen.getByText("Select New Role")).toBeInTheDocument();
  });

  it("should disable accept button when role not selected with totalAccessUsers", () => {
    const allRoles = [
      { Role_Id: 1, RoleName: "Admin", Status: "Active" },
      { Role_Id: 2, RoleName: "User", Status: "Active" },
    ];

    render(
      <ConsentPopup
        {...defaultProps}
        consentTypeAction={consentType.DeleteRole}
        editRoleData={{ Role_Id: 1 }}
        totalAccessUsers={5}
        allRoles={allRoles}
        setChangedRoleId={jest.fn()}
      />
    );

    expect(screen.getByText("Yes")).toBeDisabled();
  });

  it("should handle role selection change", () => {
    const setChangedRoleId = jest.fn();
    const allRoles = [
      { Role_Id: 1, RoleName: "Admin", Status: "Active" },
      { Role_Id: 2, RoleName: "User", Status: "Active" },
    ];

    render(
      <ConsentPopup
        {...defaultProps}
        consentTypeAction={consentType.DeleteRole}
        editRoleData={{ Role_Id: 1 }}
        totalAccessUsers={5}
        allRoles={allRoles}
        setChangedRoleId={setChangedRoleId}
      />
    );

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

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

    expect(setChangedRoleId).toHaveBeenCalledWith(2);
  });

  it("should filter out inactive roles from dropdown", () => {
    const allRoles = [
      { Role_Id: 1, RoleName: "Admin", Status: "Active" },
      { Role_Id: 2, RoleName: "InactiveRole", Status: "InActive" },
    ];

    render(
      <ConsentPopup
        {...defaultProps}
        consentTypeAction={consentType.DeleteRole}
        editRoleData={{ Role_Id: 1 }}
        totalAccessUsers={5}
        allRoles={allRoles}
        setChangedRoleId={jest.fn()}
      />
    );

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

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

  it("should not show role selector without totalAccessUsers", () => {
    render(
      <ConsentPopup
        {...defaultProps}
        consentTypeAction={consentType.DeleteRole}
        editRoleData={{ Role_Id: 1 }}
        totalAccessUsers={0}
        allRoles={[]}
        setChangedRoleId={jest.fn()}
      />
    );

    expect(screen.queryByText("Select New Role")).not.toBeInTheDocument();
  });
});
