import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import ProgressBar from './progress-bar';

const getWrap = () => document.querySelector('.acms-admin-progress') as HTMLElement;
const getBar = () => document.querySelector('.acms-admin-progress-bar') as HTMLElement;

describe('ProgressBar', () => {
  it('value / max から割合を width に反映する', () => {
    render(<ProgressBar value={30} max={60} />);
    expect(getBar().style.width).toBe('50%');
  });

  it('value が max を超えても 100% に丸める', () => {
    render(<ProgressBar value={150} max={100} />);
    expect(getBar().style.width).toBe('100%');
  });

  it('負の value は 0% に丸める', () => {
    render(<ProgressBar value={-10} max={100} />);
    expect(getBar().style.width).toBe('0%');
  });

  it('variant に応じた色クラスを付与する', () => {
    render(<ProgressBar value={50} variant="danger" />);
    expect(document.querySelector('.acms-admin-progress-bar-danger')).toBeInTheDocument();
  });

  it('default variant では色クラスを付与しない', () => {
    render(<ProgressBar value={50} variant="default" />);
    expect(document.querySelector('.acms-admin-progress-bar-info')).not.toBeInTheDocument();
    expect(document.querySelector('.acms-admin-progress-bar-danger')).not.toBeInTheDocument();
  });

  it('striped / animated でクラスを付与する', () => {
    render(<ProgressBar value={50} striped animated />);
    expect(getWrap().classList.contains('acms-admin-progress-striped')).toBe(true);
    expect(getWrap().classList.contains('acms-admin-active')).toBe(true);
  });

  it('label を bar 内の span として表示する', () => {
    render(<ProgressBar value={50} label="読み込み中" />);
    expect(getBar().querySelector('span')?.textContent).toBe('読み込み中');
  });

  it('labelPosition=overlay はラベルをバー外（中央）に置く', () => {
    render(<ProgressBar value={0} label="処理中" labelPosition="overlay" />);
    expect(screen.getByText('処理中')).toBeInTheDocument();
    expect(getBar().style.width).toBe('0%');
    // overlay は width 0% のバー内ではなく progress 直下に置かれる
    expect(getBar().querySelector('span')).toBeNull();
  });

  it('100% に達すると animated 指定でもアニメーション(active)を止める（ストライプは残す）', () => {
    render(<ProgressBar value={100} max={100} striped animated />);
    expect(getWrap().classList.contains('acms-admin-active')).toBe(false);
    expect(getWrap().classList.contains('acms-admin-progress-striped')).toBe(true);
  });

  it('100% 未満なら animated 指定でアニメーション(active)する', () => {
    render(<ProgressBar value={50} animated />);
    expect(getWrap().classList.contains('acms-admin-active')).toBe(true);
  });

  it('indeterminate（value=null）はストライプアニメーションのフル幅になる', () => {
    render(<ProgressBar value={null} />);
    expect(getWrap().classList.contains('acms-admin-progress-striped')).toBe(true);
    expect(getWrap().classList.contains('acms-admin-active')).toBe(true);
    expect(getBar().style.width).toBe('100%');
    expect(getWrap().getAttribute('aria-valuenow')).toBeNull();
  });

  it('ARIA 属性（valuenow/valuemax/valuetext）を設定する', () => {
    render(<ProgressBar value={40} max={80} getValueLabel={(v, m) => `${v}/${m}`} />);
    const wrap = screen.getByRole('progressbar');
    expect(wrap).toHaveAttribute('aria-valuenow', '40');
    expect(wrap).toHaveAttribute('aria-valuemax', '80');
    expect(wrap).toHaveAttribute('aria-valuetext', '40/80');
  });
});
