import React from "react";
import { render, screen } from "@testing-library/react";
import { jest } from "@jest/globals";

// Mock accounts for different scenarios
let mockAccounts = [];
let mockPermissions = null;
let mockPathname = "/dashboard";

// Mock MSAL
jest.unstable_mockModule("@azure/msal-react", () => ({
  __esModule: true,
  useMsal: () => ({
    accounts: mockAccounts,
  }),
}));

// Mock react-router-dom
jest.unstable_mockModule("react-router-dom", () => ({
  __esModule: true,
  Navigate: ({ to }) => <div data-testid="navigate">{to}</div>,
  Outlet: ({ context }) => <div data-testid="outlet" data-permission-id={context?.permissionId}>Outlet</div>,
  useLocation: () => ({ pathname: mockPathname }),
}));

// Mock UserContext
jest.unstable_mockModule("../context/UserContext.js", () => ({
  __esModule: true,
  useUser: () => ({
    permissions: mockPermissions,
  }),
}));

// Mock userConstants
jest.unstable_mockModule("../constants/userConstants.js", () => ({
  __esModule: true,
  permissionTypes: [
    { key: 1 }, // full access
    { key: 2 }, // read access
    { key: 3 }, // no access
  ],
}));

// Import after mocks
const { default: ProtectedRoute } = await import("../components/ProtectedRoute.js");

describe("ProtectedRoute Component", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockAccounts = [{ username: "test@test.com" }];
    mockPermissions = [
      { Path: "/dashboard", Permission_Id: "1" },
      { Path: "/users", Permission_Id: "2" },
    ];
    mockPathname = "/dashboard";
  });

  it("redirects to signin when no accounts", () => {
    mockAccounts = [];
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("navigate")).toHaveTextContent("/signin");
  });

  it("returns null when permissions is undefined", () => {
    mockPermissions = undefined;
    
    const { container } = render(<ProtectedRoute />);
    
    expect(container.firstChild).toBeNull();
  });

  it("returns null when permissions is null", () => {
    mockPermissions = null;
    
    const { container } = render(<ProtectedRoute />);
    
    expect(container.firstChild).toBeNull();
  });

  it("redirects to unauthorized when path not in permissions", () => {
    mockPathname = "/unknown-path";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("navigate")).toHaveTextContent("/unauthorized");
  });

  it("renders Outlet when user has full access (Permission_Id = 1)", () => {
    mockPermissions = [{ Path: "/dashboard", Permission_Id: "1" }];
    mockPathname = "/dashboard";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("outlet")).toBeInTheDocument();
  });

  it("renders Outlet when user has read access (Permission_Id = 2)", () => {
    mockPermissions = [{ Path: "/users", Permission_Id: "2" }];
    mockPathname = "/users";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("outlet")).toBeInTheDocument();
  });

  it("redirects to unauthorized when user has no access (Permission_Id = 3)", () => {
    mockPermissions = [{ Path: "/admin", Permission_Id: "3" }];
    mockPathname = "/admin";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("navigate")).toHaveTextContent("/unauthorized");
  });

  it("handles permissions with SubMenuItems", () => {
    mockPermissions = [
      {
        IsSubMenu: true,
        SubMenuItems: [
          { Path: "/monitoring/activity", Permission_Id: "1" },
          { Path: "/monitoring/users", Permission_Id: "2" },
        ],
      },
    ];
    mockPathname = "/monitoring/activity";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("outlet")).toBeInTheDocument();
  });

  it("passes permissionId to Outlet context", () => {
    mockPermissions = [{ Path: "/dashboard", Permission_Id: "1" }];
    mockPathname = "/dashboard";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("outlet")).toHaveAttribute("data-permission-id", "1");
  });

  it("handles root path (/) correctly", () => {
    mockPermissions = [{ Path: "/", Permission_Id: "1" }];
    mockPathname = "/";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("outlet")).toBeInTheDocument();
  });

  it("handles partial path matching", () => {
    mockPermissions = [{ Path: "/user-profile", Permission_Id: "1" }];
    mockPathname = "/user-profile/123";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("outlet")).toBeInTheDocument();
  });

  it("handles empty permissions array", () => {
    mockPermissions = [];
    mockPathname = "/dashboard";
    
    render(<ProtectedRoute />);
    
    expect(screen.getByTestId("navigate")).toHaveTextContent("/unauthorized");
  });
});
