// src/components/PasswordInput.test.tsx
import React from 'react';
import { screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { PasswordInput } from './PasswordInput';
import { renderWithProviders } from '../tests/utils/renderWithProviders';
// Mock the child PasswordStrengthIndicator component to isolate the test (relative to new location)
vi.mock('./PasswordStrengthIndicator', () => ({
  PasswordStrengthIndicator: ({ password }: { password?: string }) => (
    <div data-testid="strength-indicator">{`Strength for: ${password}`}</div>
  ),
}));

describe('PasswordInput (in auth feature)', () => {
  it('should render as a password input by default', () => {
    renderWithProviders(<PasswordInput placeholder="Enter password" />);
    const input = screen.getByPlaceholderText('Enter password');
    expect(input).toHaveAttribute('type', 'password');
  });

  it('should toggle input type between password and text when the eye icon is clicked', () => {
    renderWithProviders(<PasswordInput placeholder="Enter password" />);
    const input = screen.getByPlaceholderText('Enter password');
    const toggleButton = screen.getByRole('button', { name: /show password/i });

    // Initial state
    expect(input).toHaveAttribute('type', 'password');

    // Click to show
    fireEvent.click(toggleButton);
    expect(input).toHaveAttribute('type', 'text');
    expect(toggleButton).toHaveAttribute('aria-label', 'Hide password');

    // Click to hide again
    fireEvent.click(toggleButton);
    expect(input).toHaveAttribute('type', 'password');
    expect(toggleButton).toHaveAttribute('aria-label', 'Show password');
  });

  it('should pass through standard input attributes', () => {
    const handleChange = vi.fn();
    renderWithProviders(
      <PasswordInput
        value="test"
        onChange={handleChange}
        placeholder="Enter password"
        className="extra-class"
      />,
    );

    const input = screen.getByPlaceholderText('Enter password');
    expect(input).toHaveValue('test');
    expect(input).toHaveClass('extra-class');

    fireEvent.change(input, { target: { value: 'new value' } });
    expect(handleChange).toHaveBeenCalledTimes(1);
  });

  it('should not show strength indicator by default', () => {
    renderWithProviders(<PasswordInput value="some-password" onChange={() => {}} />);
    expect(screen.queryByTestId('strength-indicator')).not.toBeInTheDocument();
  });

  it('should show strength indicator when showStrength is true and there is a value', () => {
    renderWithProviders(<PasswordInput value="some-password" showStrength onChange={() => {}} />);
    const indicator = screen.getByTestId('strength-indicator');
    expect(indicator).toBeInTheDocument();
    expect(indicator).toHaveTextContent('Strength for: some-password');
  });

  it('should not show strength indicator when showStrength is true but value is empty', () => {
    renderWithProviders(<PasswordInput value="" showStrength onChange={() => {}} />);
    expect(screen.queryByTestId('strength-indicator')).not.toBeInTheDocument();
  });

  it('should handle undefined className gracefully', () => {
    renderWithProviders(<PasswordInput placeholder="No class" />);
    const input = screen.getByPlaceholderText('No class');
    expect(input.className).not.toContain('undefined');
    expect(input.className).toContain('block w-full');
  });

  it('should not show strength indicator if value is undefined', () => {
    renderWithProviders(<PasswordInput showStrength onChange={() => {}} />);
    expect(screen.queryByTestId('strength-indicator')).not.toBeInTheDocument();
  });

  it('should not show strength indicator if value is not a string', () => {
    // Force a non-string value to test the typeof check
    const props = { value: 12345, showStrength: true, onChange: () => {} } as any;
    renderWithProviders(<PasswordInput {...props} />);
    expect(screen.queryByTestId('strength-indicator')).not.toBeInTheDocument();
  });
});
