import { describe, it, expect } from 'vitest';
import { LiveryDecal } from './LiveryDecal';

describe('LiveryDecal', () => {
  it('should create valid decal', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    expect(decal.id).toBe('test-id');
    expect(decal.imageUrl).toBe('http://example.com/image.png');
    expect(decal.x).toBe(0.5);
    expect(decal.y).toBe(0.5);
    expect(decal.width).toBe(0.2);
    expect(decal.height).toBe(0.1);
    expect(decal.rotation).toBe(0);
    expect(decal.zIndex).toBe(1);
    expect(decal.type).toBe('sponsor');
  });

  it('should create with custom rotation', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      rotation: 45,
      zIndex: 1,
      type: 'user',
    });
    expect(decal.rotation).toBe(45);
  });

  it('should validate id required', () => {
    expect(() => LiveryDecal.create({
      id: '',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal ID is required');
  });

  it('should validate imageUrl required', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: '',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal imageUrl is required');
  });

  it('should validate x coordinate range', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: -0.1,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal x coordinate must be between 0 and 1');
  });

  it('should validate y coordinate range', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 1.1,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal y coordinate must be between 0 and 1');
  });

  it('should validate width range', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal width must be between 0 and 1');
  });

  it('should validate height range', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 1.1,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal height must be between 0 and 1');
  });

  it('should validate zIndex non-negative integer', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: -1,
      type: 'sponsor',
    })).toThrow('LiveryDecal zIndex must be a non-negative integer');
  });

  it('should validate rotation range', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      rotation: 361,
      zIndex: 1,
      type: 'sponsor',
    })).toThrow('LiveryDecal rotation must be between 0 and 360 degrees');
  });

  it('should validate type required', () => {
    expect(() => LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: '' as 'sponsor',
    })).toThrow('LiveryDecal type is required');
  });

  it('should move to new position', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const moved = decal.moveTo(0.3, 0.7);
    expect(moved.x).toBe(0.3);
    expect(moved.y).toBe(0.7);
    expect(moved.id).toBe(decal.id);
  });

  it('should resize', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const resized = decal.resize(0.4, 0.2);
    expect(resized.width).toBe(0.4);
    expect(resized.height).toBe(0.2);
  });

  it('should set zIndex', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const updated = decal.setZIndex(5);
    expect(updated.zIndex).toBe(5);
  });

  it('should rotate', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const rotated = decal.rotate(90);
    expect(rotated.rotation).toBe(90);
  });

  it('should normalize rotation', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const rotated = decal.rotate(450);
    expect(rotated.rotation).toBe(90);
  });

  it('should check overlaps', () => {
    const decal1 = LiveryDecal.create({
      id: '1',
      imageUrl: 'http://example.com/image.png',
      x: 0.1,
      y: 0.1,
      width: 0.3,
      height: 0.3,
      zIndex: 1,
      type: 'sponsor',
    });
    const decal2 = LiveryDecal.create({
      id: '2',
      imageUrl: 'http://example.com/image.png',
      x: 0.2,
      y: 0.2,
      width: 0.3,
      height: 0.3,
      zIndex: 1,
      type: 'sponsor',
    });
    expect(decal1.overlapsWith(decal2)).toBe(true);
  });

  it('should not overlap when separate', () => {
    const decal1 = LiveryDecal.create({
      id: '1',
      imageUrl: 'http://example.com/image.png',
      x: 0.1,
      y: 0.1,
      width: 0.2,
      height: 0.2,
      zIndex: 1,
      type: 'sponsor',
    });
    const decal2 = LiveryDecal.create({
      id: '2',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.2,
      zIndex: 1,
      type: 'sponsor',
    });
    expect(decal1.overlapsWith(decal2)).toBe(false);
  });

  it('should have props', () => {
    const decal = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    expect(decal.props).toEqual({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      rotation: 0,
      zIndex: 1,
      type: 'sponsor',
    });
  });

  it('equals', () => {
    const decal1 = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const decal2 = LiveryDecal.create({
      id: 'test-id',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    const decal3 = LiveryDecal.create({
      id: 'different',
      imageUrl: 'http://example.com/image.png',
      x: 0.5,
      y: 0.5,
      width: 0.2,
      height: 0.1,
      zIndex: 1,
      type: 'sponsor',
    });
    expect(decal1.equals(decal2)).toBe(true);
    expect(decal1.equals(decal3)).toBe(false);
  });
});