import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DateFieldComponent } from './date-field';

describe('DateFieldComponent', () => {
  let component: DateFieldComponent;
  let fixture: ComponentFixture<DateFieldComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [DateFieldComponent]
    }).compileComponents();

    fixture = TestBed.createComponent(DateFieldComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should render date input', () => {
    const compiled = fixture.nativeElement as HTMLElement;
    const input = compiled.querySelector('input[type="date"]');
    expect(input).toBeTruthy();
  });

  it('should display clear button when value is set', () => {
    component.value = new Date('2023-01-01');
    fixture.detectChanges();
    
    const compiled = fixture.nativeElement as HTMLElement;
    const clearButton = compiled.querySelector('.ccl-datefield__clear');
    expect(clearButton).toBeTruthy();
  });

  it('should not display clear button when value is null', () => {
    component.value = null;
    fixture.detectChanges();
    
    const compiled = fixture.nativeElement as HTMLElement;
    const clearButton = compiled.querySelector('.ccl-datefield__clear');
    expect(clearButton).toBeFalsy();
  });

  it('should handle date input correctly', () => {
    spyOn(component, 'onDateInput');
    
    const compiled = fixture.nativeElement as HTMLElement;
    const input = compiled.querySelector('input[type="date"]') as HTMLInputElement;
    
    input.value = '2023-01-01';
    input.dispatchEvent(new Event('input'));
    
    expect(component.onDateInput).toHaveBeenCalled();
  });

  it('should clear value when clear button is clicked', () => {
    component.value = new Date('2023-01-01');
    spyOn(component, 'clear');
    
    fixture.detectChanges();
    
    const compiled = fixture.nativeElement as HTMLElement;
    const clearButton = compiled.querySelector('.ccl-datefield__clear') as HTMLButtonElement;
    clearButton.click();
    
    expect(component.clear).toHaveBeenCalled();
  });

  it('should emit onChange when value changes', () => {
    spyOn(component.onChange, 'emit');
    
    const testDate = new Date('2023-01-01');
    component.value = testDate;
    component.onDateInput({ target: { value: '2023-01-01' } } as any);
    
    expect(component.onChange.emit).toHaveBeenCalledWith(testDate);
  });

  it('should handle empty input', () => {
    spyOn(component.onChange, 'emit');
    
    component.onDateInput({ target: { value: '' } } as any);
    
    expect(component.value).toBeNull();
    expect(component.onChange.emit).toHaveBeenCalledWith(null);
  });

  it('should set error message for invalid date', () => {
    component.onDateInput({ target: { value: 'invalid-date' } } as any);
    
    expect(component.errorMessage).toBe('Invalid date format');
  });

  it('should clear error message for valid date', () => {
    component.errorMessage = 'Invalid date format';
    component.onDateInput({ target: { value: '2023-01-01' } } as any);
    
    expect(component.errorMessage).toBe('');
  });

  it('should return correct input value', () => {
    const testDate = new Date('2023-01-01');
    component.value = testDate;
    
    expect(component.getInputValue()).toBe('2023-01-01');
  });

  it('should return empty string for null value', () => {
    component.value = null;
    
    expect(component.getInputValue()).toBe('');
  });

  it('should return min date string', () => {
    const minDate = new Date('2023-01-01');
    component.minDate = minDate;
    
    expect(component.getMinDateString()).toBe('2023-01-01');
  });

  it('should return empty string when no min date', () => {
    component.minDate = undefined;
    
    expect(component.getMinDateString()).toBe('');
  });

  it('should return max date string', () => {
    const maxDate = new Date('2023-12-31');
    component.maxDate = maxDate;
    
    expect(component.getMaxDateString()).toBe('2023-12-31');
  });

  it('should return empty string when no max date', () => {
    component.maxDate = undefined;
    
    expect(component.getMaxDateString()).toBe('');
  });

  it('should handle blur event', () => {
    spyOn(component, 'onTouched');
    
    component.onBlur();
    
    expect(component.onTouched).toHaveBeenCalled();
  });

  it('should implement ControlValueAccessor', () => {
    const testDate = new Date('2023-01-01');
    
    component.writeValue(testDate);
    expect(component.value).toBe(testDate);
    
    let onChangeValue: Date | null = null;
    component.registerOnChange((value: Date | null) => {
      onChangeValue = value;
    });
    
    component.onDateInput({ target: { value: '2023-01-01' } } as any);
    expect(onChangeValue).toEqual(jasmine.any(Date));
  });

  it('should handle input click', () => {
    spyOn(component.inputEl.nativeElement, 'focus');
    spyOn(component.inputEl.nativeElement, 'showPicker');
    
    component.onInputClick();
    
    expect(component.inputEl.nativeElement.focus).toHaveBeenCalled();
    expect(component.inputEl.nativeElement.showPicker).toHaveBeenCalled();
  });

  it('should not open picker when disabled', () => {
    component.disabled = true;
    spyOn(component.inputEl.nativeElement, 'focus');
    spyOn(component.inputEl.nativeElement, 'showPicker');
    
    component.onInputClick();
    
    expect(component.inputEl.nativeElement.focus).not.toHaveBeenCalled();
    expect(component.inputEl.nativeElement.showPicker).not.toHaveBeenCalled();
  });
});