import { describe, it, expect } from 'vitest'
import { render } from '@testing-library/react'
import { CategoryBarStacked } from './category-bar-stacked'

describe('<CategoryBarStacked>', () => {
  function getSegments(container: HTMLElement): HTMLElement[] {
    return Array.from(
      container.querySelectorAll<HTMLElement>('[data-bar-fill="true"]'),
    )
  }

  it('renders one segment per non-zero value with proportional width', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[40, 30]}
        colors={['rgb(0, 200, 0)', 'rgb(0, 100, 0)']}
        maxValue={100}
      />,
    )
    const segs = getSegments(container)
    expect(segs).toHaveLength(2)
    expect(segs[0]!.style.width).toBe('40%')
    expect(segs[1]!.style.width).toBe('30%')
  })

  it('cumulative left offsets — second segment starts at the first segment’s right edge', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[40, 30]}
        colors={['rgb(0, 200, 0)', 'rgb(0, 100, 0)']}
        maxValue={100}
      />,
    )
    const segs = getSegments(container)
    expect(segs[0]!.style.left).toBe('0%')
    expect(segs[1]!.style.left).toBe('40%')
  })

  it('skips zero-value segments entirely (no DOM node, no width:0 placeholder)', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[40, 0, 20]}
        colors={['rgb(0, 200, 0)', 'rgb(0, 100, 0)', 'rgb(0, 50, 0)']}
        maxValue={100}
      />,
    )
    const segs = getSegments(container)
    expect(segs).toHaveLength(2)
    // Cumulative offsets skip the gap from the zero segment — its
    // contribution to the cumulative sum is zero anyway, so the third
    // value's left = 40 + 0 = 40%.
    expect(segs[0]!.style.left).toBe('0%')
    expect(segs[0]!.style.width).toBe('40%')
    expect(segs[1]!.style.left).toBe('40%')
    expect(segs[1]!.style.width).toBe('20%')
  })

  it('renders no segments when maxValue is 0 (and every value is 0 → division-by-zero safety)', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[0, 0]}
        colors={['rgb(0, 0, 0)', 'rgb(0, 0, 0)']}
        maxValue={0}
      />,
    )
    expect(getSegments(container)).toHaveLength(0)
  })

  it('honors colors per segment', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[20, 30]}
        colors={['rgb(255, 0, 0)', 'rgb(0, 0, 255)']}
        maxValue={100}
      />,
    )
    const segs = getSegments(container)
    expect(segs[0]!.style.backgroundColor).toBe('rgb(255, 0, 0)')
    expect(segs[1]!.style.backgroundColor).toBe('rgb(0, 0, 255)')
  })

  it('single value renders a single segment at left:0% (CategoryBar-equivalent)', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[25]}
        colors={['rgb(0, 0, 0)']}
        maxValue={100}
      />,
    )
    const segs = getSegments(container)
    expect(segs).toHaveLength(1)
    expect(segs[0]!.style.left).toBe('0%')
    expect(segs[0]!.style.width).toBe('25%')
  })

  it('defaults to size="small" (data-size on the track)', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[10]}
        colors={['rgb(0, 0, 0)']}
        maxValue={100}
      />,
    )
    const track = container.querySelector('[data-size]')
    expect(track).toBeTruthy()
    expect(track!.getAttribute('data-size')).toBe('small')
  })

  it('propagates size="medium" to the track', () => {
    const { container } = render(
      <CategoryBarStacked
        values={[10]}
        colors={['rgb(0, 0, 0)']}
        maxValue={100}
        size='medium'
      />,
    )
    const track = container.querySelector('[data-size]')
    expect(track!.getAttribute('data-size')).toBe('medium')
  })
})
