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

// The react-date-range Calendar is mocked in __mocks__/react-date-range.js

describe("SingleDatePicker Component", () => {
  const defaultProps = {
    onChange: jest.fn(),
    onApply: jest.fn(),
    onClose: jest.fn(),
    value: "2023-06-15",
  };

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

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

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

    // Should have Apply and Close buttons
    expect(screen.getByText("Apply")).toBeInTheDocument();
    expect(screen.getByText("Close")).toBeInTheDocument();
  });

  it("should call onApply when Apply button is clicked", () => {
    render(<SingleDatePicker {...defaultProps} />);

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

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

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

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

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

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

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

  it("should call onChange when date is selected from calendar", () => {
    render(<SingleDatePicker {...defaultProps} />);

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

    // The mock Calendar has a button that triggers onChange when clicked
    const calendarButton = screen.getByText("Mock Calendar");
    fireEvent.click(calendarButton);

    // onChange should be called (the mock's onChange calls props.onChange)
    expect(defaultProps.onChange).toHaveBeenCalled();
  });

  it("should render with default date when value is not provided", () => {
    const propsWithoutDate = {
      onChange: jest.fn(),
      onApply: jest.fn(),
      onClose: jest.fn(),
    };

    render(<SingleDatePicker {...propsWithoutDate} />);

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

    expect(screen.getByText("Apply")).toBeInTheDocument();
  });

  it("should handle date selection correctly", () => {
    render(<SingleDatePicker {...defaultProps} />);

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

    // Calendar should be rendered
    expect(screen.getByTestId("mock-calendar")).toBeInTheDocument();
  });

  it("should pass selected date to onApply", () => {
    render(<SingleDatePicker {...defaultProps} />);

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

    // First select a date from calendar using the mock button
    const calendarButton = screen.getByText("Mock Calendar");
    fireEvent.click(calendarButton);

    // Then apply
    fireEvent.click(screen.getByText("Apply"));

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

  it("should render with null value", () => {
    const propsWithNullDate = {
      onChange: jest.fn(),
      onApply: jest.fn(),
      onClose: jest.fn(),
      value: null,
    };

    render(<SingleDatePicker {...propsWithNullDate} />);

    // Click the input to open the calendar
    const input = screen.getByPlaceholderText("Select date");
    fireEvent.click(input);

    expect(screen.getByText("Apply")).toBeInTheDocument();
  });
});
