import { describe, it, expect, beforeEach } from 'vitest';
import { GetSponsorsPresenter } from './GetSponsorsPresenter';
import { Sponsor } from '@core/racing/domain/entities/sponsor/Sponsor';

describe('GetSponsorsPresenter', () => {
  let presenter: GetSponsorsPresenter;

  beforeEach(() => {
    presenter = new GetSponsorsPresenter();
  });

  describe('reset', () => {
    it('should reset the model to null and cause responseModel to throw', () => {
      const sponsors: Sponsor[] = [];
      presenter.present(sponsors);
      expect(presenter.responseModel).toEqual({ sponsors: [] });

      presenter.reset();
      expect(() => presenter.responseModel).toThrow('Presenter not presented');
    });
  });

  describe('present', () => {
    it('should map sponsors to DTO responseModel', () => {
      const sponsors: Sponsor[] = [
        Sponsor.create({
          id: 'sponsor-1',
          name: 'Sponsor One',
          contactEmail: 's1@example.com',
          logoUrl: 'https://one.example.com/logo1.png',
          websiteUrl: 'https://one.example.com',
          createdAt: new Date('2024-01-01T00:00:00Z'),
        }),
        Sponsor.create({
          id: 'sponsor-2',
          name: 'Sponsor Two',
          contactEmail: 's2@example.com',
        }),
      ];

      presenter.present(sponsors);

      expect(presenter.responseModel).toEqual({
        sponsors: [
          {
            id: 'sponsor-1',
            name: 'Sponsor One',
            contactEmail: 's1@example.com',
            logoUrl: 'https://one.example.com/logo1.png',
            websiteUrl: 'https://one.example.com',
            createdAt: new Date('2024-01-01T00:00:00Z'),
          },
          {
            id: 'sponsor-2',
            name: 'Sponsor Two',
            contactEmail: 's2@example.com',
            createdAt: expect.any(Date),
          },
        ],
      });
    });
  });

  describe('getResponseModel', () => {
    it('should return null when not presented', () => {
      expect(presenter.getResponseModel()).toBeNull();
    });

    it('should return the model when presented', () => {
      const sponsors: Sponsor[] = [];
      presenter.present(sponsors);

      expect(presenter.getResponseModel()).toEqual({ sponsors: [] });
    });
  });

  describe('responseModel', () => {
    it('should throw error when not presented', () => {
      expect(() => presenter.responseModel).toThrow('Presenter not presented');
    });

    it('should return the model when presented', () => {
      const sponsors: Sponsor[] = [
        Sponsor.create({
          id: 'sponsor-1',
          name: 'Sponsor One',
          contactEmail: 's1@example.com',
        }),
      ];
      presenter.present(sponsors);

      expect(presenter.responseModel).toEqual({
        sponsors: [
          {
            id: 'sponsor-1',
            name: 'Sponsor One',
            contactEmail: 's1@example.com',
            createdAt: expect.any(Date),
          },
        ],
      });
    });
  });
});