import { describe, it, expect } from 'vitest';
import { LiveryTemplate } from './LiveryTemplate';
import { LiveryDecal } from '../value-objects/LiveryDecal';

describe('LiveryTemplate', () => {
  const validProps = {
    id: 'template1',
    leagueId: 'league1',
    seasonId: 'season1',
    carId: 'car1',
    baseImageUrl: 'https://example.com/image.png',
  };

  it('should create a livery template', () => {
    const template = LiveryTemplate.create(validProps);
    expect(template.id.toString()).toBe('template1');
    expect(template.leagueId.toString()).toBe('league1');
    expect(template.seasonId.toString()).toBe('season1');
    expect(template.carId.toString()).toBe('car1');
    expect(template.baseImageUrl.toString()).toBe('https://example.com/image.png');
    expect(template.adminDecals).toEqual([]);
  });

  it('should throw on empty id', () => {
    expect(() => LiveryTemplate.create({ ...validProps, id: '' })).toThrow('LiveryTemplate ID is required');
  });

  it('should throw on empty leagueId', () => {
    expect(() => LiveryTemplate.create({ ...validProps, leagueId: '' })).toThrow('LiveryTemplate leagueId is required');
  });

  it('should throw on empty seasonId', () => {
    expect(() => LiveryTemplate.create({ ...validProps, seasonId: '' })).toThrow('LiveryTemplate seasonId is required');
  });

  it('should throw on empty carId', () => {
    expect(() => LiveryTemplate.create({ ...validProps, carId: '' })).toThrow('LiveryTemplate carId is required');
  });

  it('should throw on empty baseImageUrl', () => {
    expect(() => LiveryTemplate.create({ ...validProps, baseImageUrl: '' })).toThrow('LiveryTemplate baseImageUrl is required');
  });

  it('should add a sponsor decal', () => {
    const template = LiveryTemplate.create(validProps);
    const decal = LiveryDecal.create({
      id: 'decal1',
      imageUrl: 'https://example.com/decal.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const updated = template.addDecal(decal);
    expect(updated.adminDecals).toHaveLength(1);
    expect(updated.adminDecals[0]).toBe(decal);
    expect(updated.updatedAt).toBeDefined();
  });

  it('should throw when adding non-sponsor decal', () => {
    const template = LiveryTemplate.create(validProps);
    const decal = LiveryDecal.create({
      id: 'decal1',
      imageUrl: 'https://example.com/decal.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'user',
    });
    expect(() => template.addDecal(decal)).toThrow('Only sponsor decals can be added to admin template');
  });

  it('should remove a decal', () => {
    const decal = LiveryDecal.create({
      id: 'decal1',
      imageUrl: 'https://example.com/decal.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const template = LiveryTemplate.create({ ...validProps, adminDecals: [decal] });
    const updated = template.removeDecal('decal1');
    expect(updated.adminDecals).toHaveLength(0);
    expect(updated.updatedAt).toBeDefined();
  });

  it('should throw when removing non-existent decal', () => {
    const template = LiveryTemplate.create(validProps);
    expect(() => template.removeDecal('nonexistent')).toThrow('Decal not found in template');
  });

  it('should update a decal', () => {
    const decal = LiveryDecal.create({
      id: 'decal1',
      imageUrl: 'https://example.com/decal.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const template = LiveryTemplate.create({ ...validProps, adminDecals: [decal] });
    const updatedDecal = LiveryDecal.create({
      id: 'decal1',
      imageUrl: 'https://example.com/decal.png',
      x: 0.6,
      y: 0.6,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const updated = template.updateDecal('decal1', updatedDecal);
    expect(updated.adminDecals[0]).toBe(updatedDecal);
    expect(updated.updatedAt).toBeDefined();
  });

  it('should throw when updating non-existent decal', () => {
    const template = LiveryTemplate.create(validProps);
    const decal = LiveryDecal.create({
      id: 'decal1',
      imageUrl: 'https://example.com/decal.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    expect(() => template.updateDecal('nonexistent', decal)).toThrow('Decal not found in template');
  });

  it('should get sponsor decals', () => {
    const sponsorDecal = LiveryDecal.create({
      id: 'sponsor1',
      imageUrl: 'https://example.com/sponsor.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const userDecal = LiveryDecal.create({
      id: 'user1',
      imageUrl: 'https://example.com/user.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'user',
    });
    const template = LiveryTemplate.create({ ...validProps, adminDecals: [sponsorDecal, userDecal] });
    const sponsors = template.getSponsorDecals();
    expect(sponsors).toHaveLength(1);
    expect(sponsors[0]).toBe(sponsorDecal);
  });

  it('should check if has sponsor decals', () => {
    const sponsorDecal = LiveryDecal.create({
      id: 'sponsor1',
      imageUrl: 'https://example.com/sponsor.png',
      x: 0.5,
      y: 0.5,
      width: 0.1,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const templateWithSponsor = LiveryTemplate.create({ ...validProps, adminDecals: [sponsorDecal] });
    const templateWithout = LiveryTemplate.create(validProps);
    expect(templateWithSponsor.hasSponsorDecals()).toBe(true);
    expect(templateWithout.hasSponsorDecals()).toBe(false);
  });
});