/**
 * @jest-environment jsdom
 */

/*
 * Runtime Web – Unified Serverless Framework for Full-Stack TypeScript Applications
 * Documentation: https://runtimeweb.com/docs/getting-started
 *
 * @template: ai-chat
 */

/**
 * Property-based tests for InputArea component.
 *
 * Feature: ai-chat-template
 * - Property 3: Input Validation Rejects Empty and Whitespace Messages
 * - Property 4: Input Area Disabled During Loading State
 * - Property 5: Input Cleared After Successful Send
 *
 * Validates: Requirements 3.4, 3.5, 3.8
 */

import * as React from 'react';
import * as fc from 'fast-check';
import { render, cleanup, fireEvent, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { InputArea } from '../InputArea';

afterEach(() => {
    cleanup();
    jest.clearAllMocks();
});

const whitespaceOnlyArbitrary = fc.oneof(
    fc.constant(''),
    fc.array(fc.constantFrom(' ', '\t', '\n', '\r'), { minLength: 1, maxLength: 20 })
        .map((chars) => chars.join('')),
);

const nonEmptyMessageArbitrary = fc.string({ minLength: 1, maxLength: 100 })
    .filter((s) => s.trim().length > 0);

describe('InputArea Property Tests', () => {
    describe('Property 3: Input Validation Rejects Empty and Whitespace Messages', () => {
        it('does not invoke onSend for whitespace-only input', () => {
            fc.assert(
                fc.property(whitespaceOnlyArbitrary, (whitespaceInput) => {
                    const onSend = jest.fn();
                    const { unmount } = render(<InputArea onSend={onSend} disabled={false} />);
                    const textarea = screen.getByRole('textbox');
                    const button = screen.getByRole('button', { name: /send/i });
                    fireEvent.change(textarea, { target: { value: whitespaceInput } });
                    fireEvent.click(button);
                    expect(onSend).not.toHaveBeenCalled();
                    unmount();
                }),
                { numRuns: 100 },
            );
        });
    });

    describe('Property 4: Input Area Disabled During Loading State', () => {
        it('textarea and button are disabled when disabled prop is true', () => {
            fc.assert(
                fc.property(nonEmptyMessageArbitrary, (message) => {
                    const onSend = jest.fn();
                    const { unmount } = render(<InputArea onSend={onSend} disabled={true} />);
                    const textarea = screen.getByRole('textbox');
                    const button = screen.getByRole('button', { name: /send/i });
                    expect(textarea).toBeDisabled();
                    expect(button).toBeDisabled();
                    fireEvent.change(textarea, { target: { value: message } });
                    fireEvent.click(button);
                    expect(onSend).not.toHaveBeenCalled();
                    unmount();
                }),
                { numRuns: 100 },
            );
        });
    });

    describe('Property 5: Input Cleared After Successful Send', () => {
        it('clears input after successful send', () => {
            fc.assert(
                fc.property(nonEmptyMessageArbitrary, (message) => {
                    const onSend = jest.fn();
                    const { unmount } = render(<InputArea onSend={onSend} disabled={false} />);
                    const textarea = screen.getByRole('textbox') as HTMLTextAreaElement;
                    fireEvent.change(textarea, { target: { value: message } });
                    fireEvent.keyDown(textarea, { key: 'Enter', shiftKey: false });
                    expect(onSend).toHaveBeenCalledWith(message.trim());
                    expect(textarea.value).toBe('');
                    unmount();
                }),
                { numRuns: 100 },
            );
        });
    });
});
