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

describe('PasswordStrengthIndicator', () => {
  it('should not render when password is empty', () => {
    const { container } = render(<PasswordStrengthIndicator password="" />);
    expect(container.firstChild).toBeNull();
  });

  it('should show "Very Weak" for very weak password', () => {
    render(<PasswordStrengthIndicator password="a" />);
    expect(screen.getByText('Very Weak')).toBeInTheDocument();
  });

  it('should show "Weak" for weak password with only length', () => {
    render(<PasswordStrengthIndicator password="abcdefghijkl" />);
    expect(screen.getByText('Weak')).toBeInTheDocument();
  });

  it('should show "Fair" for password with length, uppercase, and lowercase', () => {
    render(<PasswordStrengthIndicator password="PasswordTest" />);
    expect(screen.getByText('Fair')).toBeInTheDocument();
  });

  it('should show "Good" for password with length, uppercase, lowercase, and number', () => {
    render(<PasswordStrengthIndicator password="Password1234" />);
    expect(screen.getByText('Good')).toBeInTheDocument();
  });

  it('should show "Strong" for password with all requirements', () => {
    render(<PasswordStrengthIndicator password="SecurePass123!" />);
    expect(screen.getByText('Strong')).toBeInTheDocument();
  });

  it('should display all validation rules', () => {
    render(<PasswordStrengthIndicator password="test" />);
    expect(screen.getByText(/at least 12 characters/i)).toBeInTheDocument();
    expect(screen.getByText(/one uppercase letter/i)).toBeInTheDocument();
    expect(screen.getByText(/one lowercase letter/i)).toBeInTheDocument();
    expect(screen.getByText(/one number/i)).toBeInTheDocument();
    expect(screen.getByText(/one special character/i)).toBeInTheDocument();
  });

  it('should show checkmarks for fulfilled requirements', () => {
    render(<PasswordStrengthIndicator password="SecurePass123!" />);
    const checks = screen.getAllByText('✓');
    expect(checks.length).toBe(5); // All 5 requirements met
  });

  it('should show circles for unfulfilled requirements', () => {
    render(<PasswordStrengthIndicator password="a" />);
    const circles = screen.getAllByText('○');
    expect(circles.length).toBeGreaterThan(0);
  });

  it('should have correct progress bar width for score', () => {
    const { container } = render(
      <PasswordStrengthIndicator password="SecurePass123!" />,
    );
    const progressBar = container.querySelector(
      '[role="progressbar"]',
    ) as HTMLElement;
    expect(progressBar).toBeInTheDocument();
    expect(progressBar.style.width).toBe('100%'); // 5/5 = 100%
    expect(progressBar.getAttribute('aria-valuenow')).toBe('5');
  });

  it('should have correct progress bar width for partial score', () => {
    // Password1234 has 12 characters, upper, lower, number = 4 points = 80%
    const { container } = render(
      <PasswordStrengthIndicator password="Password1234" />,
    );
    const progressBar = container.querySelector(
      '[role="progressbar"]',
    ) as HTMLElement;
    expect(progressBar).toBeInTheDocument();
    expect(progressBar.getAttribute('aria-valuenow')).toBe('4');
    expect(progressBar.style.width).toContain('%'); // Should have percentage width
  });

  it('should correctly identify special characters', () => {
    // Test with a single special character
    const { container } = render(
      <PasswordStrengthIndicator password="Password1234!" />,
    );
    expect(container.firstChild).not.toBeNull();
    // Should show "Strong" for password with all requirements including special char
    expect(screen.getByText('Strong')).toBeInTheDocument();
  });

  it('should have accessible progress bar attributes', () => {
    const { container } = render(
      <PasswordStrengthIndicator password="SecurePass123!" />,
    );
    const progressBar = container.querySelector(
      '[role="progressbar"]',
    ) as HTMLElement;

    expect(progressBar.getAttribute('role')).toBe('progressbar');
    expect(progressBar.getAttribute('aria-valuenow')).toBe('5');
    expect(progressBar.getAttribute('aria-valuemin')).toBe('0');
    expect(progressBar.getAttribute('aria-valuemax')).toBe('5');
    expect(progressBar.getAttribute('aria-label')).toContain(
      'Password strength',
    );
  });

  it('should update score when password changes', () => {
    const { rerender } = render(<PasswordStrengthIndicator password="a" />);
    expect(screen.getByText('Very Weak')).toBeInTheDocument();

    rerender(<PasswordStrengthIndicator password="SecurePass123!" />);
    expect(screen.getByText('Strong')).toBeInTheDocument();
  });
});
