import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule, FormBuilder } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

import { HarmonizedCreateViewComponent, FormSection, EntityBadge } from './harmonized-create-view.component';

describe('HarmonizedCreateViewComponent', () => {
  let component: HarmonizedCreateViewComponent;
  let fixture: ComponentFixture<HarmonizedCreateViewComponent>;
  let fb: FormBuilder;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ HarmonizedCreateViewComponent ],
      imports: [
        ReactiveFormsModule,
        MatFormFieldModule,
        MatInputModule,
        MatSelectModule,
        MatButtonModule,
        MatIconModule,
        NoopAnimationsModule
      ]
    })
    .compileComponents();

    fixture = TestBed.createComponent(HarmonizedCreateViewComponent);
    component = fixture.componentInstance;
    fb = TestBed.inject(FormBuilder);
  });

  beforeEach(() => {
    // Setup minimal required inputs
    component.form = fb.group({
      testField: ['']
    });
    component.formData = [
      {
        controlName: 'testField',
        controlType: 'text',
        placeholder: 'Test Field',
        validators: { required: false }
      }
    ];
    fixture.detectChanges();
  });

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

  it('should initialize with default entity badges when none provided', () => {
    component.ngOnInit();
    expect(component.entityBadges).toBeDefined();
    expect(component.entityBadges!.length).toBeGreaterThan(0);
  });

  it('should show entity header by default', () => {
    expect(component.showEntityHeader).toBe(true);
  });

  it('should emit save event when form is valid', () => {
    spyOn(component.save, 'emit');
    component.form.patchValue({ testField: 'test value' });

    component.onSave();

    expect(component.save.emit).toHaveBeenCalledWith({ testField: 'test value' });
  });

  it('should not emit save event when form is invalid', () => {
    spyOn(component.save, 'emit');
    component.form = fb.group({
      requiredField: ['', { validators: [] }]
    });
    component.form.get('requiredField')?.setErrors({ required: true });

    component.onSave();

    expect(component.save.emit).not.toHaveBeenCalled();
  });

  it('should emit cancel event', () => {
    spyOn(component.cancel, 'emit');

    component.onCancel();

    expect(component.cancel.emit).toHaveBeenCalled();
  });

  it('should emit saveAndContinue event when form is valid', () => {
    spyOn(component.saveAndContinue, 'emit');
    component.form.patchValue({ testField: 'test value' });

    component.onSaveAndContinue();

    expect(component.saveAndContinue.emit).toHaveBeenCalledWith({ testField: 'test value' });
  });

  it('should get section fields correctly', () => {
    const section: FormSection = {
      title: 'Test Section',
      fields: ['testField']
    };

    const result = component.getSectionFields(section);

    expect(result.length).toBe(1);
    expect(result[0].controlName).toBe('testField');
  });

  it('should return all formData when section has no fields specified', () => {
    const section: FormSection = {
      title: 'Test Section'
    };

    const result = component.getSectionFields(section);

    expect(result).toBe(component.formData);
  });

  it('should mark form as touched when validation fails', () => {
    component.form = fb.group({
      requiredField: ['', { validators: [] }]
    });
    component.form.get('requiredField')?.setErrors({ required: true });

    component.onSave();

    expect(component.form.get('requiredField')?.touched).toBe(true);
  });

  it('should emit section action correctly', () => {
    spyOn(component.sectionAction, 'emit');
    const action = { label: 'Test Action', action: 'test' };
    const section: FormSection = { title: 'Test Section' };

    component.onSectionAction(action, section);

    expect(component.sectionAction.emit).toHaveBeenCalledWith({ action: 'test', section });
  });

  it('should determine canSaveForm correctly', () => {
    // Valid form
    component.canSave = true;
    component.form.patchValue({ testField: 'valid value' });
    expect(component.canSaveForm).toBe(true);

    // Invalid form
    component.form.get('testField')?.setErrors({ required: true });
    expect(component.canSaveForm).toBe(false);

    // CanSave disabled
    component.canSave = false;
    component.form.get('testField')?.setErrors(null);
    expect(component.canSaveForm).toBe(false);
  });

  it('should get badge class correctly', () => {
    const defaultBadge: EntityBadge = { label: 'Test' };
    const successBadge: EntityBadge = { label: 'Test', type: 'success' };

    expect(component.getBadgeClass(defaultBadge)).toBe('entity-badge');
    expect(component.getBadgeClass(successBadge)).toBe('entity-badge entity-badge--success');
  });
});