import React from 'react';
import { render, fireEvent, waitFor, screen } from '@testing-library/react';
import { AUTH0_CONNECTION } from '../constants';
import { ResetPasswordForm } from '../resetPasswordForm';

const fetchMock = vi.fn();
global.fetch = fetchMock;

const mockConfig = {
    auth0Domain: 'test.auth0.com',
    auth0ClientId: 'test-client-id',
};

vi.mock('@theorchard/suite-config', () => ({
    useAppConfig: () => mockConfig,
}));

describe('<ResetPasswordForm>', () => {
    beforeEach(() => {
        fetchMock.mockClear();
    });

    const renderComponent = () => render(<ResetPasswordForm />);

    const fillAndSubmit = (email: string) => {
        renderComponent();
        const input = screen.getByPlaceholderText('name.surname@email.com');
        fireEvent.change(input, { target: { value: email } });
        fireEvent.click(screen.getByText('Reset Password'));
    };

    test('renders email input and submit button', () => {
        renderComponent();
        expect(screen.getByPlaceholderText('name.surname@email.com')).toBeVisible();
        expect(screen.getByText('Reset Password')).toBeVisible();
    });

    test('disables button while submitting', async () => {
        fetchMock.mockReturnValue(new Promise(() => undefined));
        fillAndSubmit('test@example.com');

        await waitFor(() => {
            expect(screen.getByText('Reset Password')).toBeDisabled();
        });
    });

    test('shows success message after successful response', async () => {
        fetchMock.mockResolvedValue({ ok: true });
        fillAndSubmit('test@example.com');

        await waitFor(() => {
            expect(
                screen.getByText('Please follow the link in your email to reset your password.')
            ).toBeVisible();
        });
    });

    test('does not show success message on non-ok response', async () => {
        fetchMock.mockResolvedValue({ ok: false });
        fillAndSubmit('test@example.com');

        await waitFor(() => {
            expect(screen.getByText('Reset Password')).not.toBeDisabled();
        });
        expect(screen.getByPlaceholderText('name.surname@email.com')).toBeVisible();
    });

    test('calls fetch with correct URL, method, headers and body', async () => {
        fetchMock.mockResolvedValue({ ok: true });
        fillAndSubmit('test@example.com');

        await waitFor(() => {
            expect(fetchMock).toHaveBeenCalledWith(
                `https://${mockConfig.auth0Domain}/dbconnections/change_password`,
                {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        email: 'test@example.com',
                        connection: AUTH0_CONNECTION,
                        client_id: mockConfig.auth0ClientId,
                    }),
                }
            );
        });
    });
});
