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

// Mock DateRangePicker component
const MockDateRangePicker = ({ onChange, onApply, onClose }) => {
  return (
    <div data-testid="mock-date-range">
      <button onClick={() => {
        const mockRange = {
          startDate: new Date('2026-03-01'),
          endDate: new Date('2026-03-05')
        };
        onChange(mockRange);
      }}>Mock DateRange</button>
      <div className='action-buttons-date-range-picker'>
        <div>
          <button 
            className='button'
            onClick={() => {
              const mockRange = {
                startDate: new Date('2026-03-01'),
                endDate: new Date('2026-03-05')
              };
              onApply(mockRange);
            }}
          >
            Apply
          </button>
          <button className='btn2' onClick={onClose}>Close</button>
        </div>
      </div>
    </div>
  );
};

// Mock SingleDatePicker component
const MockSingleDatePicker = ({ onChange, onApply, onClose }) => {
  return (
    <div data-testid="mock-single-date">
      <button onClick={() => {
        const mockDate = new Date('2026-03-05');
        onChange(mockDate);
      }}>Mock Calendar</button>
      <div className='action-buttons-date-picker'>
        <div>
          <button 
            className='button'
            onClick={() => {
              const mockDate = new Date('2026-03-05');
              onApply(mockDate);
            }}
          >
            Apply
          </button>
          <button className='btn2' onClick={onClose}>Close</button>
        </div>
      </div>
    </div>
  );
};

// Mock the component modules
jest.unstable_mockModule('./DateRangePicker.js', () => ({
  __esModule: true,
  default: MockDateRangePicker
}));

jest.unstable_mockModule('./SingleDatePicker.js', () => ({
  __esModule: true,
  default: MockSingleDatePicker 
}));

import SmartDateSelector from './SmartDateSelector';

describe('SmartDateSelector Component', () => {
  const mockOnApply = jest.fn();

  beforeEach(() => {
    mockOnApply.mockClear();
  });

  test('should render select dropdown', () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    expect(select).toBeInTheDocument();
  });

  test('should have preset options', () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    fireEvent.mouseDown(select);

    const options = screen.getAllByRole('option');
    expect(options).toHaveLength(4);
    expect(options[0]).toHaveTextContent('Today');
    expect(options[1]).toHaveTextContent('Current Week');
    expect(options[2]).toHaveTextContent('Current Month');
    expect(options[3]).toHaveTextContent('Custom');
  });

  test('should call onApply when Today is selected', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');

    fireEvent.mouseDown(select);
    const weekOption = screen.getByRole('option', { name: 'Current Week' });
    fireEvent.click(weekOption);

    fireEvent.mouseDown(select);
    const todayOption = screen.getByRole('option', { name: 'Today' });
    fireEvent.click(todayOption);

    await waitFor(() => expect(mockOnApply).toHaveBeenCalledTimes(2));
    expect(mockOnApply.mock.calls.at(-1)[0].displayLabel).toBe('Today');
  });

  test('should call onApply when Current Week is selected', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const weekOption = screen.getByRole('option', { name: 'Current Week' });
    fireEvent.click(weekOption);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
  });

  test('should call onApply when Current Month is selected', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const monthOption = screen.getByRole('option', { name: 'Current Month' });
    fireEvent.click(monthOption);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
  });

  test('should pass date range object to onApply', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const monthOption = screen.getByRole('option', { name: 'Current Month' });
    fireEvent.click(monthOption);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalledWith(
        expect.objectContaining({
          startDate: expect.any(Date),
          endDate: expect.any(Date),
          displayLabel: expect.any(String)
        })
      );
    });
  });

  test('should set displayLabel to Today', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const weekOption = screen.getByRole('option', { name: 'Current Week' });
    fireEvent.click(weekOption);

    fireEvent.mouseDown(select);
    const todayOption = screen.getByRole('option', { name: 'Today' });
    fireEvent.click(todayOption);
    
    await waitFor(() => {
      const callArgs = mockOnApply.mock.calls.at(-1)[0];
      expect(callArgs.displayLabel).toBe('Today');
    });
  });

  test('should accept initialValue prop', () => {
    const initialValue = {
      startDate: new Date(),
      endDate: new Date(),
      displayLabel: 'Today'
    };
    render(
      <SmartDateSelector 
        onApply={mockOnApply} 
        useSingleDate={false}
        initialValue={initialValue}
      />
    );
    expect(screen.getByRole('combobox')).toBeInTheDocument();
  });

  test('should show custom picker when Custom is selected', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    // The backdrop should be visible when custom picker is open
    await waitFor(() => {
      expect(document.querySelector('.MuiBackdrop-root')).toBeInTheDocument();
    });
  });

  test('should close custom picker when backdrop is clicked', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.MuiBackdrop-root')).toBeInTheDocument();
    });

    // Click backdrop to close
    const backdrop = document.querySelector('.MuiBackdrop-root');
    fireEvent.click(backdrop);
    
    await waitFor(() => {
      // Backdrop should not be visible anymore (or Paper should not be visible)
      expect(document.querySelector('.custom-date-picker-modal')).not.toBeInTheDocument();
    });
  });

  test('should render with useSingleDate=true', () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={true} />);
    expect(screen.getByRole('combobox')).toBeInTheDocument();
  });

  test('should show SingleDatePicker when Custom selected with useSingleDate=true', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={true} />);
    const select = screen.getByRole('combobox');
    
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).toBeInTheDocument();
    });
  });

  test('should use default dateType when not provided', () => {
    render(<SmartDateSelector onApply={mockOnApply} />);
    expect(screen.getByRole('combobox')).toBeInTheDocument();
  });

  test('should return null for unknown option in getDateRange', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    // First select a valid option (Current Month)
    fireEvent.mouseDown(select);
    const monthOption = screen.getByRole('option', { name: 'Current Month' });
    fireEvent.click(monthOption);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
    
    // Verify the call had valid date range structure
    const lastCall = mockOnApply.mock.calls.at(-1)[0];
    expect(lastCall).toHaveProperty('startDate');
    expect(lastCall).toHaveProperty('endDate');
    expect(lastCall).toHaveProperty('displayLabel');
  });

  test('should handle apply button click in DateRangePicker', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    // Open custom picker
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).toBeInTheDocument();
    });
    
    // First, click the mock DateRange button to set up the range
    const mockRangeButton = screen.getByText('Mock DateRange');
    fireEvent.click(mockRangeButton);
    
    // Then click the Apply button in the date range picker
    const applyButton = screen.getByText('Apply');
    fireEvent.click(applyButton);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
  });

  test('should handle apply button click in SingleDatePicker', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={true} />);
    const select = screen.getByRole('combobox');
    
    // Open custom picker
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).toBeInTheDocument();
    });
    
    // Click the date input to open the SingleDatePicker calendar
    const dateInput = document.querySelector('.custom-date-picker-modal input[type="text"]');
    fireEvent.click(dateInput);
    
    // Wait for calendar to appear and click the Apply button
    await waitFor(() => {
      const applyButton = screen.getByText('Apply');
      expect(applyButton).toBeInTheDocument();
    });
    
    const applyButton = screen.getByText('Apply');
    fireEvent.click(applyButton);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
  });

  test('should close picker when Close button is clicked', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    // Open custom picker
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).toBeInTheDocument();
    });
    
    // Click the Close button
    const closeButton = screen.getByText('Close');
    fireEvent.click(closeButton);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).not.toBeInTheDocument();
    });
  });

  test('should handle date selection from calendar in useSingleDate mode', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={true} />);
    const select = screen.getByRole('combobox');
    
    // Open custom picker
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).toBeInTheDocument();
    });
    
    // Click the date input to open the SingleDatePicker calendar
    const dateInput = document.querySelector('.custom-date-picker-modal input[type="text"]');
    fireEvent.click(dateInput);
    
    // Wait for calendar and apply button to be available
    await waitFor(() => {
      const applyButton = screen.getByText('Apply');
      expect(applyButton).toBeInTheDocument();
    });
    
    // Click apply button
    const applyButton = screen.getByText('Apply');
    fireEvent.click(applyButton);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
  });

  test('should handle date range selection from picker', async () => {
    render(<SmartDateSelector onApply={mockOnApply} useSingleDate={false} />);
    const select = screen.getByRole('combobox');
    
    // Open custom picker
    fireEvent.mouseDown(select);
    const customOption = screen.getByRole('option', { name: 'Custom' });
    fireEvent.click(customOption);
    
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).toBeInTheDocument();
    });
    
    // First, click the mock DateRange button to set up the range
    const mockRangeButton = screen.getByText('Mock DateRange');
    fireEvent.click(mockRangeButton);
    
    // Apply the date range
    const applyButton = screen.getByText('Apply');
    fireEvent.click(applyButton);
    
    await waitFor(() => {
      expect(mockOnApply).toHaveBeenCalled();
    });
    
    // Verify the picker closes after apply
    await waitFor(() => {
      expect(document.querySelector('.custom-date-picker-modal')).not.toBeInTheDocument();
    });
  });
});
