import { cleanup, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it } from 'vitest';
import { BugPreview, bugPreviewStyle, type BugPreviewGeometry } from './bugPreview';

const base: BugPreviewGeometry = {
  horizontalMargin: 1,
  location: 'TopLeft',
  opacity: 80,
  size: 'Scaled',
  verticalMargin: 1,
  width: 5
};

describe('bugPreviewStyle', () => {
  it('anchors TopLeft using the margins', () => {
    const style = bugPreviewStyle(base);
    expect(style.top).toBe('1%');
    expect(style.left).toBe('1%');
    expect(style.bottom).toBeUndefined();
    expect(style.right).toBeUndefined();
  });

  it('anchors BottomRight using the margins', () => {
    const style = bugPreviewStyle({ ...base, location: 'BottomRight' });
    expect(style.bottom).toBe('1%');
    expect(style.right).toBe('1%');
    expect(style.top).toBeUndefined();
    expect(style.left).toBeUndefined();
  });

  it('centers horizontally for TopMiddle', () => {
    const style = bugPreviewStyle({ ...base, location: 'TopMiddle' });
    expect(style.top).toBe('1%');
    expect(style.left).toBe('50%');
    expect(style.transform).toBe('translateX(-50%)');
  });

  it('centers vertically for LeftMiddle', () => {
    const style = bugPreviewStyle({ ...base, location: 'LeftMiddle' });
    expect(style.left).toBe('1%');
    expect(style.top).toBe('50%');
    expect(style.transform).toBe('translateY(-50%)');
  });

  it('centers both axes for MiddleCenter', () => {
    const style = bugPreviewStyle({ ...base, location: 'MiddleCenter' });
    expect(style.transform).toBe('translate(-50%, -50%)');
  });

  it('anchors BottomLeft using the margins', () => {
    const style = bugPreviewStyle({ ...base, location: 'BottomLeft' });
    expect(style.bottom).toBe('1%');
    expect(style.left).toBe('1%');
    expect(style.top).toBeUndefined();
    expect(style.right).toBeUndefined();
    expect(style.transform).toBeUndefined();
  });

  it('anchors TopRight using the margins', () => {
    const style = bugPreviewStyle({ ...base, location: 'TopRight' });
    expect(style.top).toBe('1%');
    expect(style.right).toBe('1%');
    expect(style.bottom).toBeUndefined();
    expect(style.left).toBeUndefined();
    expect(style.transform).toBeUndefined();
  });

  it('centers vertically for RightMiddle', () => {
    const style = bugPreviewStyle({ ...base, location: 'RightMiddle' });
    expect(style.right).toBe('1%');
    expect(style.top).toBe('50%');
    expect(style.transform).toBe('translateY(-50%)');
  });

  it('centers horizontally for BottomMiddle', () => {
    const style = bugPreviewStyle({ ...base, location: 'BottomMiddle' });
    expect(style.bottom).toBe('1%');
    expect(style.left).toBe('50%');
    expect(style.transform).toBe('translateX(-50%)');
  });

  it('scales width by percent when size is Scaled', () => {
    expect(bugPreviewStyle({ ...base, width: 12 }).width).toBe('12%');
  });

  it('leaves width unset at ActualSize', () => {
    expect(bugPreviewStyle({ ...base, size: 'ActualSize' }).width).toBeUndefined();
  });

  it('maps opacity percent to a 0-1 fraction', () => {
    expect(bugPreviewStyle({ ...base, opacity: 80 }).opacity).toBeCloseTo(0.8);
  });
});

describe('BugPreview', () => {
  afterEach(cleanup);

  it('renders the image when a src is supplied', () => {
    render(<BugPreview {...base} alt="Bug preview" src="/iptv/logos/abc" />);
    expect(screen.getByAltText('Bug preview')).toHaveAttribute('src', '/iptv/logos/abc');
  });

  it('renders an empty frame without a src', () => {
    render(<BugPreview {...base} src={null} />);
    expect(screen.queryByRole('img')).toBeNull();
  });
});
