import type { Payment } from '@core/payments/domain/entities/Payment';
import { PayerType, PaymentStatus, PaymentType } from '@core/payments/domain/entities/Payment';
import type { Logger } from '@core/shared/domain/Logger';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { InMemoryPaymentRepository } from './InMemoryPaymentRepository';

describe('InMemoryPaymentRepository', () => {
  let repository: InMemoryPaymentRepository;
  let logger: Logger;

  beforeEach(() => {
    logger = {
      debug: vi.fn(),
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    } as unknown as Logger;
    repository = new InMemoryPaymentRepository(logger);
  });

  it('creates and finds by filters', async () => {
    const payment: Payment = {
      id: 'pay-1',
      type: PaymentType.SPONSORSHIP,
      amount: 100,
      platformFee: 5,
      netAmount: 95,
      payerId: 'sponsor-1',
      payerType: PayerType.SPONSOR,
      leagueId: 'league-1',
      status: PaymentStatus.PENDING,
      createdAt: new Date('2025-01-01T00:00:00.000Z'),
    };

    await repository.create(payment);

    expect((await repository.findById('pay-1'))?.id).toBe('pay-1');
    expect((await repository.findByLeagueId('league-1')).length).toBeGreaterThanOrEqual(1);
    expect((await repository.findByPayerId('sponsor-1')).length).toBeGreaterThanOrEqual(1);
    expect((await repository.findByType(PaymentType.SPONSORSHIP)).length).toBeGreaterThanOrEqual(1);

    const filtered = await repository.findByFilters({ leagueId: 'league-1', payerId: 'sponsor-1', type: PaymentType.SPONSORSHIP });
    expect(filtered.map(p => p.id)).toContain('pay-1');
  });

  it('updates', async () => {
    const payment: Payment = {
      id: 'pay-2',
      type: PaymentType.MEMBERSHIP_FEE,
      amount: 50,
      platformFee: 2.5,
      netAmount: 47.5,
      payerId: 'driver-1',
      payerType: PayerType.DRIVER,
      leagueId: 'league-2',
      status: PaymentStatus.PENDING,
      createdAt: new Date('2025-01-02T00:00:00.000Z'),
    };

    await repository.create(payment);
    const updated = await repository.update({ ...payment, status: PaymentStatus.COMPLETED, completedAt: new Date('2025-01-03T00:00:00.000Z') });
    expect(updated.status).toBe(PaymentStatus.COMPLETED);
  });
});
