import { fireEvent, render, screen } from '@testing-library/react';
import { createRef } from 'react';
import { describe, expect, it, vi } from 'vitest';
import { InputField } from '../../src/components/InputField';

describe('InputField', () => {
    it('supports email type and emits change/blur callbacks', () => {
        const onChange = vi.fn();
        const onBlur = vi.fn();
        render(
            <InputField
                label="Email"
                type="email"
                value=""
                onChange={onChange}
                onBlur={onBlur}
                required
            />,
        );

        const input = screen.getByLabelText('Email') as HTMLInputElement;
        expect(input.type).toBe('email');
        expect(input).toBeRequired();

        fireEvent.change(input, { target: { value: 'new@example.com' } });
        fireEvent.blur(input);
        expect(onChange).toHaveBeenCalledTimes(1);
        expect(onBlur).toHaveBeenCalledTimes(1);
    });

    it('passes refs to input element', () => {
        const inputRef = createRef<HTMLInputElement>();
        render(<InputField label="Username" type="text" value="john" onChange={() => {}} inputRef={inputRef} />);

        expect(inputRef.current).toBeInstanceOf(HTMLInputElement);
        expect(inputRef.current?.value).toBe('john');
    });

    it('toggles password visibility', () => {
        render(<InputField label="Password" type="password" value="abc" onChange={() => {}} />);

        expect((screen.getByLabelText('Password') as HTMLInputElement).type).toBe('password');
        fireEvent.click(screen.getByRole('button', { name: 'Show password' }));
        expect((screen.getByLabelText('Password') as HTMLInputElement).type).toBe('text');
        fireEvent.click(screen.getByRole('button', { name: 'Hide password' }));
        expect((screen.getByLabelText('Password') as HTMLInputElement).type).toBe('password');
    });

    it('renders rightIcon for non-password input and displays errors', () => {
        const { container } = render(
            <InputField
                label="Username"
                type="text"
                value="john"
                onChange={() => {}}
                rightIcon={<span data-testid="right-icon">R</span>}
                error="Invalid username"
                inputClassName="custom-input"
            />,
        );

        const input = container.querySelector('input');
        expect(input).toBeInstanceOf(HTMLInputElement);
        expect(input).toHaveClass('pr-10');
        expect(input).toHaveClass('custom-input');
        expect(screen.getByTestId('right-icon')).toBeInTheDocument();
        expect(screen.getByText('Invalid username')).toBeInTheDocument();
    });

    it('disables password toggle when input is disabled', () => {
        render(
            <InputField
                label="Password"
                type="password"
                value="secret"
                onChange={() => {}}
                disabled
            />,
        );

        expect(screen.getByRole('button', { name: 'Show password' })).toBeDisabled();
    });

    it('supports inline layout classes', () => {
        const { container } = render(
            <InputField label="Username" type="text" value="" onChange={() => {}} layout="inline" />,
        );

        expect(container.querySelector('label')).toHaveClass('inline-flex');
        expect(container.querySelector('label > div')).not.toHaveClass('mt-1');
    });
});
