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

// Mock the apiService hook
const mockPostApi = jest.fn();
jest.unstable_mockModule("../services/apiService.js", () => ({
  default: () => ({
    postApi: mockPostApi,
  }),
}));

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

const renderComponent = (props = {}) => {
  const defaultProps = {
    employeeId: null,
    summaryFilter: null,
    ...props,
  };

  return render(
    <BrowserRouter>
      <UserProvider value={mockUserContext}>
        <CallDetails {...defaultProps} />
      </UserProvider>
    </BrowserRouter>
  );
};

describe("CallDetails Component", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockPostApi.mockResolvedValue([
      { EmpCode: "EMP001", EmployeeName: "John Doe", Total_Call_Duration: "00:30:00", CallWith: "+1234567890" }
    ]);
  });

  test("renders component with loader initially", () => {
    renderComponent();
    expect(screen.getByTestId("loader")).toBeInTheDocument();
  });

  test("renders common table", () => {
    renderComponent();
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  test("renders date filter dropdown", () => {
    renderComponent();
    expect(screen.getByRole("combobox")).toBeInTheDocument();
  });

  test("renders with employeeId prop", () => {
    renderComponent({ employeeId: "EMP001" });
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  test("renders with summaryFilter prop", () => {
    const summaryFilter = {
      CallDate: { startDate: new Date(), endDate: new Date() },
      ResultsFor: "test",
    };
    renderComponent({ summaryFilter });
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  test("renders with title userProfile", () => {
    renderComponent({ title: "userProfile" });
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  test("renders without employeeId", () => {
    renderComponent();
    const searchInput = screen.getByRole("textbox");
    expect(searchInput).toBeInTheDocument();
  });

  test("does not render search input when employeeId provided", () => {
    const { container } = renderComponent({ employeeId: "EMP001" });
    const searchInputs = container.querySelectorAll('input[placeholder*="Search"]');
    expect(searchInputs.length).toBe(0);
  });

  test("renders inner-container", () => {
    const { container } = renderComponent();
    expect(container.querySelector(".inner-container")).toBeInTheDocument();
  });

  test("renders filters-wrapper", () => {
    const { container } = renderComponent();
    expect(container.querySelector(".filters-wrapper")).toBeInTheDocument();
  });

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

  test("handles date filter change", async () => {
    renderComponent();
    const dateFilter = screen.getByRole("combobox");
    fireEvent.mouseDown(dateFilter);
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  test("renders with numeric employeeId", () => {
    renderComponent({ employeeId: 12345 });
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  test("renders other-filters section", () => {
    const { container } = renderComponent();
    expect(container.querySelector(".other-filters")).toBeInTheDocument();
  });

  test("renders with summaryFilter containing EmpCode", () => {
    const summaryFilter = {
      EmpCode: "EMP001",
      CallDate: { startDate: "2024-01-01", endDate: "2024-01-31" },
      ResultsFor: "day",
    };
    renderComponent({ summaryFilter });
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  // Additional tests to cover more lines

  // Test handleDateFilterChange (lines 66-86)
  test("handleDateFilterChange with date range selection", async () => {
    renderComponent();
    
    const dateFilter = screen.getByRole("combobox");
    fireEvent.mouseDown(dateFilter);
    
    await waitFor(() => {
      const options = screen.getAllByRole("option");
      if (options.length > 0) {
        fireEvent.click(options[0]);
      }
    });
    
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  // Test handleDateFilterChange with EmployeeName prop
  test("handleDateFilterChange uses EmployeeName when available", async () => {
    renderComponent({ EmployeeName: "John Doe" });
    
    const dateFilter = screen.getByRole("combobox");
    fireEvent.mouseDown(dateFilter);
    
    await waitFor(() => {
      const options = screen.getAllByRole("option");
      if (options.length > 0) {
        fireEvent.click(options[0]);
      }
    });
    
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  // Test handleSearch (lines 90-97)
  test("handleSearch triggers API call with search text", async () => {
    renderComponent();
    
    const searchInput = screen.getByRole("textbox");
    fireEvent.change(searchInput, { target: { value: "john" } });
    
    const searchButton = screen.getByTestId("search-button");
    fireEvent.click(searchButton);
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  // Test API error handling (line 51)
  test("handles API error gracefully", async () => {
    mockPostApi.mockRejectedValueOnce(new Error("API Error"));
    const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
    
    await act(async () => {
      renderComponent();
    });
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
    
    consoleSpy.mockRestore();
  });

  // Test with null result from API
  test("handles null result from API", async () => {
    mockPostApi.mockResolvedValueOnce(null);
    
    await act(async () => {
      renderComponent();
    });
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  // Test with non-array result from API
  test("handles non-array result from API", async () => {
    mockPostApi.mockResolvedValueOnce({ data: "not an array" });
    
    await act(async () => {
      renderComponent();
    });
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  // Test with external filter prop
  test("renders with external filter prop", async () => {
    const externalFilter = {
      PageNumber: 2,
      PageSize: 25,
    };
    
    await act(async () => {
      renderComponent({ filter: externalFilter });
    });
    
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  // Test with summaryFilter EmpCode
  test("handleDateFilterChange uses summaryFilter EmpCode", async () => {
    const summaryFilter = {
      EmpCode: "EMP123",
      CallDate: { startDate: new Date(), endDate: new Date() },
    };
    
    renderComponent({ summaryFilter });
    
    const dateFilter = screen.getByRole("combobox");
    fireEvent.mouseDown(dateFilter);
    
    await waitFor(() => {
      const options = screen.getAllByRole("option");
      if (options.length > 0) {
        fireEvent.click(options[0]);
      }
    });
    
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });

  // Test handleSearch with lowercase conversion
  test("handleSearch converts search text to lowercase", async () => {
    renderComponent();
    
    const searchInput = screen.getByRole("textbox");
    fireEvent.change(searchInput, { target: { value: "JOHN DOE" } });
    
    const searchButton = screen.getByTestId("search-button");
    fireEvent.click(searchButton);
    
    await waitFor(() => {
      expect(screen.getByTestId("common-table")).toBeInTheDocument();
    });
  });

  // Test with title other than userProfile
  test("renders with default title", async () => {
    await act(async () => {
      renderComponent({ title: "dashboard" });
    });
    
    expect(screen.getByTestId("common-table")).toBeInTheDocument();
  });
});