// #region InputTest [C:2] [TYPE Module] [SEMANTICS test, ui, input, form, component, atom]
// @BRIEF Unit tests for Input UI component — label, value, error, disabled, placeholder, id generation.
// @LAYER Tests
// @RELATION BINDS_TO -> [Input]
// @UX_STATE Idle -> Renders input with label
// @UX_STATE Error -> Shows error message below input

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import Input from '../Input.svelte';

describe('Input', () => {
	it('renders an input element', () => {
		const { container } = render(Input);
		const input = container.querySelector('input');
		expect(input).not.toBeNull();
	});

	it('renders label when provided', () => {
		const { container } = render(Input, { props: { label: 'Username' } });
		const label = container.querySelector('label');
		expect(label).not.toBeNull();
		expect(label!.textContent).toBe('Username');
	});

	it('does not render label when not provided', () => {
		const { container } = render(Input);
		const label = container.querySelector('label');
		expect(label).toBeNull();
	});

	it('sets placeholder on input', () => {
		const { container } = render(Input, { props: { placeholder: 'Enter text...' } });
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.placeholder).toBe('Enter text...');
	});

	it('sets type attribute', () => {
		const { container } = render(Input, { props: { type: 'password' } });
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.type).toBe('password');
	});

	it('renders error message when error prop is set', () => {
		const { container } = render(Input, { props: { error: 'This field is required' } });
		const errorSpan = container.querySelector('span.text-destructive');
		expect(errorSpan).not.toBeNull();
		expect(errorSpan!.textContent).toBe('This field is required');
	});

	it('does not render error span when error is empty', () => {
		const { container } = render(Input);
		const errorSpan = container.querySelector('span.text-destructive');
		expect(errorSpan).toBeNull();
	});

	it('applies error border class when error is set', () => {
		const { container } = render(Input, { props: { error: 'Error' } });
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.className).toContain('border-destructive');
	});

	it('sets disabled attribute on input', () => {
		const { container } = render(Input, { props: { disabled: true } });
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.disabled).toBe(true);
	});

	it('generates an id starting with input- when not provided', () => {
		const { container } = render(Input);
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.id).toMatch(/^input-/);
	});

	it('uses external id when provided', () => {
		const { container } = render(Input, { props: { id: 'my-custom-id' } });
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.id).toBe('my-custom-id');
	});

	it('applies custom class name', () => {
		const { container } = render(Input, { props: { class: 'custom-class' } });
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.className).toContain('custom-class');
	});

	it('renders with default text type', () => {
		const { container } = render(Input);
		const input = container.querySelector('input') as HTMLInputElement;
		expect(input.type).toBe('text');
	});

	it('links label to input via for/id attribute', () => {
		const { container } = render(Input, { props: { label: 'Email', id: 'email-input' } });
		const label = container.querySelector('label') as HTMLLabelElement;
		const input = container.querySelector('input') as HTMLInputElement;
		expect(label.htmlFor).toBe('email-input');
		expect(input.id).toBe('email-input');
	});
});
// #endregion InputTest
