import { describe, it, expect, beforeEach, vi } from 'vitest';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CustomerCardPointsSummaryComponent } from './customer-card-points-summary.component';
import { BonusCardInfo } from '@isa/crm/data-access';

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

  const mockCards: BonusCardInfo[] = [
    {
      code: 'CARD-1',
      firstName: 'John',
      lastName: 'Doe',
      isActive: true,
      isPrimary: true,
      totalPoints: 1500,
      cardNumber: '1234-5678-9012-3456',
    } as BonusCardInfo,
    {
      code: 'CARD-2',
      firstName: 'John',
      lastName: 'Doe',
      isActive: true,
      isPrimary: false,
      totalPoints: 500,
      cardNumber: '9876-5432-1098-7654',
    } as BonusCardInfo,
  ];

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [CustomerCardPointsSummaryComponent],
    });

    fixture = TestBed.createComponent(CustomerCardPointsSummaryComponent);
    component = fixture.componentInstance;
  });

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

  describe('Inputs', () => {
    it('should accept cards input', () => {
      fixture.componentRef.setInput('cards', mockCards);
      fixture.detectChanges();

      expect(component.cards()).toEqual(mockCards);
    });
  });

  describe('formattedPoints computed signal', () => {
    it('should display points from first card', () => {
      fixture.componentRef.setInput('cards', mockCards);
      fixture.detectChanges();

      expect(component.formattedPoints()).toBe('1.500');
    });

    it('should format points with German thousands separator', () => {
      const cardsWithHighPoints: BonusCardInfo[] = [
        {
          code: 'CARD-1',
          firstName: 'John',
          lastName: 'Doe',
          isActive: true,
          isPrimary: true,
          totalPoints: 123456,
          cardNumber: '1234-5678-9012-3456',
        } as BonusCardInfo,
      ];

      fixture.componentRef.setInput('cards', cardsWithHighPoints);
      fixture.detectChanges();

      expect(component.formattedPoints()).toBe('123.456');
    });

    it('should display points from first card regardless of isPrimary flag', () => {
      const cardsWithoutPrimary: BonusCardInfo[] = [
        {
          code: 'CARD-1',
          firstName: 'John',
          lastName: 'Doe',
          isActive: true,
          isPrimary: false,
          totalPoints: 1500,
          cardNumber: '1234-5678-9012-3456',
        } as BonusCardInfo,
      ];

      fixture.componentRef.setInput('cards', cardsWithoutPrimary);
      fixture.detectChanges();

      expect(component.formattedPoints()).toBe('1.500');
    });

    it('should display 0 when cards array is empty', () => {
      fixture.componentRef.setInput('cards', []);
      fixture.detectChanges();

      expect(component.formattedPoints()).toBe('0');
    });

    it('should handle points value of 0', () => {
      const cardsWithZeroPoints: BonusCardInfo[] = [
        {
          code: 'CARD-1',
          firstName: 'John',
          lastName: 'Doe',
          isActive: true,
          isPrimary: true,
          totalPoints: 0,
          cardNumber: '1234-5678-9012-3456',
        } as BonusCardInfo,
      ];

      fixture.componentRef.setInput('cards', cardsWithZeroPoints);
      fixture.detectChanges();

      expect(component.formattedPoints()).toBe('0');
    });

    it('should only use first card points, not sum of all cards', () => {
      const multipleCards: BonusCardInfo[] = [
        {
          code: 'CARD-1',
          firstName: 'John',
          lastName: 'Doe',
          isActive: true,
          isPrimary: false,
          totalPoints: 1000,
          cardNumber: '1234-5678-9012-3456',
        } as BonusCardInfo,
        {
          code: 'CARD-2',
          firstName: 'John',
          lastName: 'Doe',
          isActive: true,
          isPrimary: true,
          totalPoints: 500,
          cardNumber: '9876-5432-1098-7654',
        } as BonusCardInfo,
      ];

      fixture.componentRef.setInput('cards', multipleCards);
      fixture.detectChanges();

      // Should be 1000 (first card), not 500 (primary) or 1500 (sum)
      expect(component.formattedPoints()).toBe('1.000');
    });
  });

  describe('Output: navigateToPraemienshop', () => {
    it('should emit navigateToPraemienshop event when onNavigateToPraemienshop is called', () => {
      const emitSpy = vi.fn();
      component.navigateToPraemienshop.subscribe(emitSpy);

      fixture.componentRef.setInput('cards', mockCards);
      fixture.detectChanges();

      component.onNavigateToPraemienshop();

      expect(emitSpy).toHaveBeenCalledTimes(1);
    });
  });
});
