import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DatePipe, CurrencyPipe } from '@angular/common';
import { of } from 'rxjs';

import { FinesListComponent } from './fines-list.component';
import { FinesService } from '../../fines.service';
import { Fines } from '../../fines.interface';

describe('FinesListComponent', () => {
  let component: FinesListComponent;
  let fixture: ComponentFixture<FinesListComponent>;
  let mockFinesService: jasmine.SpyObj<FinesService>;

  const mockFines: Fines[] = [
    {
      id: 1,
      name: 'Multa Teste 1',
      fine_number: 'M001',
      fine_value: 195.23,
      fine_date: '2024-01-15',
      driverId: 1,
      organization: 'municipality',
      status: 'pending',
      notes: 'Estacionamento proibido'
    },
    {
      id: 2,
      name: 'Multa Teste 2', 
      fine_number: 'M002',
      fine_value: 88.38,
      fine_date: '2024-01-10',
      driverId: 2,
      organization: 'state',
      status: 'paid',
      notes: 'Rodízio veicular'
    }
  ];

  beforeEach(async () => {
    const finesServiceSpy = jasmine.createSpyObj('FinesService', ['getFines']);

    await TestBed.configureTestingModule({
      imports: [FinesListComponent],
      providers: [
        DatePipe,
        CurrencyPipe,
        { provide: FinesService, useValue: finesServiceSpy }
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(FinesListComponent);
    component = fixture.componentInstance;
    mockFinesService = TestBed.inject(FinesService) as jasmine.SpyObj<FinesService>;
  });

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

  it('should initialize with default config', () => {
    expect(component.config.showNewButton).toBe(true);
    expect(component.config.showFilters).toBe(true);
    expect(component.config.readonly).toBe(false);
    expect(component.config.pageSize).toBe(10);
  });

  it('should load fines on init', () => {
    mockFinesService.getFines.and.returnValue(of({
      data: mockFines,
      totalCount: 2,
      pageCount: 1,
      currentPage: 1
    }));

    component.ngOnInit();

    expect(mockFinesService.getFines).toHaveBeenCalled();
    expect(component.state.fines).toEqual(mockFines);
    expect(component.state.totalCount).toBe(2);
  });

  it('should filter fines by organization type', () => {
    component.state.fines = mockFines;
    component.setActiveFilter('municipal');

    expect(component.state.filteredFines.length).toBe(1);
    expect(component.state.filteredFines[0].organization).toBe('municipality');
  });

  it('should emit events correctly', () => {
    spyOn(component.fineSelected, 'emit');
    spyOn(component.newFineRequested, 'emit');

    const testFine = mockFines[0];
    component.onFineSelected(testFine);
    expect(component.fineSelected.emit).toHaveBeenCalledWith(testFine);

    component.onNewFineClick();
    expect(component.newFineRequested.emit).toHaveBeenCalled();
  });

  it('should format currency correctly', () => {
    const formatted = component.formatCurrency(195.23);
    expect(formatted).toContain('195,23');
  });

  it('should format date correctly', () => {
    const formatted = component.formatDate('2024-01-15');
    expect(formatted).toBe('15/01/2024');
  });

  it('should handle pagination correctly', () => {
    component.state.filteredFines = mockFines;
    component.config.pageSize = 1;
    component.goToPage(1);

    expect(component.paginatedFines.length).toBe(1);
    expect(component.totalPages).toBe(2);
  });

  it('should handle empty state', () => {
    component.state.fines = [];
    component.state.filteredFines = [];
    component.state.loading = false;
    component.state.error = null;

    fixture.detectChanges();

    const emptyState = fixture.nativeElement.querySelector('.empty-state');
    expect(emptyState).toBeTruthy();
  });

  it('should handle error state', () => {
    component.state.error = 'Erro de teste';
    component.state.loading = false;

    fixture.detectChanges();

    const errorState = fixture.nativeElement.querySelector('.error-state');
    expect(errorState).toBeTruthy();
  });

  it('should handle loading state', () => {
    component.state.loading = true;

    fixture.detectChanges();

    const loadingState = fixture.nativeElement.querySelector('.loading-state');
    expect(loadingState).toBeTruthy();
  });
});
