/**
 * DateField Tests
 *
 * Tests the date field component with calendar popover and variable support.
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { DateField } from './DateField';
import { ActionField } from '../../types/action';
import { AvailableContext } from '../../hooks/useAvailableContext';

// Mock VariableInput
vi.mock('../VariableInput', () => ({
  VariableInput: ({
    value,
    onChange,
    placeholder,
  }: {
    value: string;
    onChange: (value: string) => void;
    placeholder?: string;
  }) => (
    <input
      data-testid="variable-input"
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
    />
  ),
}));

// Mock Calendar
vi.mock('../ui/calendar', () => ({
  Calendar: ({
    onSelect,
  }: {
    onSelect: (date: Date) => void;
  }) => (
    <div data-testid="calendar">
      <button
        data-testid="calendar-day"
        onClick={() => onSelect(new Date(2025, 0, 15))}
      >
        15
      </button>
    </div>
  ),
}));

// Popover is no longer used — DateField renders the calendar inline

describe('DateField', () => {
  const mockOnChange = vi.fn();

  const mockAvailableContext: AvailableContext = {
    groups: [
      {
        namespace: 'Trigger',
        sourceName: 'Test Trigger',
        sourceType: 'trigger',
        variables: [
          {
            path: 'Trigger.date',
            label: 'Date',
            source: 'Test Trigger',
            namespace: 'Trigger',
            type: 'string',
            description: 'Trigger date',
            example: '2025-01-01',
          },
        ],
      },
    ],
  };

  const defaultField: ActionField = {
    type: 'date',
    label: 'Publish Date',
    description: 'The date to publish',
    required: false,
  };

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

  it('renders label', () => {
    render(
      <DateField
        fieldName="publish_date"
        field={defaultField}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    expect(screen.getByText('Publish Date')).toBeInTheDocument();
  });

  it('renders required asterisk when field is required', () => {
    const requiredField: ActionField = { ...defaultField, required: true };
    render(
      <DateField
        fieldName="publish_date"
        field={requiredField}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    expect(screen.getByText('*')).toBeInTheDocument();
  });

  it('uses YYYY-MM-DD as default placeholder', () => {
    render(
      <DateField
        fieldName="publish_date"
        field={{ ...defaultField, placeholder: undefined }}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    expect(screen.getByTestId('variable-input')).toHaveAttribute('placeholder', 'YYYY-MM-DD');
  });

  it('uses custom placeholder when provided', () => {
    const fieldWithPlaceholder: ActionField = {
      ...defaultField,
      placeholder: 'Select a date',
    };
    render(
      <DateField
        fieldName="publish_date"
        field={fieldWithPlaceholder}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    expect(screen.getByTestId('variable-input')).toHaveAttribute('placeholder', 'Select a date');
  });

  it('disables calendar button when value contains variable syntax', () => {
    render(
      <DateField
        fieldName="publish_date"
        field={defaultField}
        value="{{Trigger.date}}"
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    const calendarButton = screen.getByRole('button', { name: 'Pick date' });
    expect(calendarButton).toBeDisabled();
  });

  it('enables calendar button when value is a plain string', () => {
    render(
      <DateField
        fieldName="publish_date"
        field={defaultField}
        value="2025-01-15"
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    const calendarButton = screen.getByRole('button', { name: 'Pick date' });
    expect(calendarButton).not.toBeDisabled();
  });

  it('displays description', () => {
    render(
      <DateField
        fieldName="publish_date"
        field={defaultField}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    expect(screen.getByText('The date to publish')).toBeInTheDocument();
  });

  it('displays error message', () => {
    render(
      <DateField
        fieldName="publish_date"
        field={defaultField}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
        error="Date is required"
      />,
    );
    expect(screen.getByText('Date is required')).toBeInTheDocument();
  });

  it('calls onChange with formatted date when calendar day is clicked', async () => {
    const user = userEvent.setup();
    render(
      <DateField
        fieldName="publish_date"
        field={defaultField}
        value=""
        onChange={mockOnChange}
        availableContext={mockAvailableContext}
      />,
    );
    // Open the calendar dropdown first
    await user.click(screen.getByRole('button', { name: 'Pick date' }));
    await user.click(screen.getByTestId('calendar-day'));
    expect(mockOnChange).toHaveBeenCalledWith('2025-01-15');
  });
});
