import { act } from 'react';
import { describe, expect, it } from 'vitest';
import { useEditableForm } from '../../src/hooks/useEditableForm';
import { renderHook } from '../helpers/renderHook';

type FormValues = {
    username: string;
    email: string;
};

const INITIAL_VALUES: FormValues = {
    username: '',
    email: '',
};

function validate(values: FormValues) {
    return {
        username: values.username.trim().length < 3 ? 'Username too short' : undefined,
        email: values.email.includes('@') ? undefined : 'Invalid email',
    };
}

describe('useEditableForm', () => {
    it('supports load/start/discard/commit edit lifecycle', () => {
        const { result } = renderHook(() =>
            useEditableForm({
                initialValues: INITIAL_VALUES,
                validate,
            }),
        );

        expect(result.current.isEditing).toBe(false);

        act(() => {
            result.current.loadFromSource({ username: 'alice', email: 'alice@example.com' });
        });
        expect(result.current.values).toEqual({ username: 'alice', email: 'alice@example.com' });
        expect(result.current.errors).toEqual({});

        act(() => {
            result.current.startEditing({ username: 'al', email: 'aliceexample.com' });
        });
        expect(result.current.isEditing).toBe(true);

        act(() => {
            result.current.setFieldValue('username', 'a');
        });
        expect(result.current.errors.username).toBe('Username too short');

        act(() => {
            result.current.discardChanges({ username: 'alice', email: 'alice@example.com' });
        });
        expect(result.current.isEditing).toBe(false);
        expect(result.current.values).toEqual({ username: 'alice', email: 'alice@example.com' });

        act(() => {
            result.current.startEditing({ username: 'alice', email: 'alice@example.com' });
            result.current.setFieldValue('username', 'alice_2');
            result.current.commitSaved({ username: 'alice_2', email: 'alice@example.com' });
        });
        expect(result.current.isEditing).toBe(false);
        expect(result.current.values.username).toBe('alice_2');
    });

    it('exposes direct editing toggles and field error injection', () => {
        const { result } = renderHook(() =>
            useEditableForm({
                initialValues: INITIAL_VALUES,
                validate,
            }),
        );

        act(() => {
            result.current.setIsEditing(true);
            result.current.setFieldError('username', 'Username already taken');
        });

        expect(result.current.isEditing).toBe(true);
        expect(result.current.errors.username).toBe('Username already taken');
    });
});
