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

vi.mock('$lib/auth/store.svelte', () => ({
  resetPassword: vi.fn(),
}));

vi.mock('$app/navigation', () => ({
  goto: vi.fn(),
}));

vi.mock('$app/state', () => ({
  page: { params: { token: 'test-token-abc' } },
}));

import { resetPassword } from '$lib/auth/store.svelte';
import { goto } from '$app/navigation';
import ResetPasswordPage from './+page.svelte';

describe('/reset-password/[token] page', () => {
  beforeEach(() => vi.clearAllMocks());

  it('rejects mismatched passwords without calling resetPassword', async () => {
    render(ResetPasswordPage);
    await fireEvent.input(screen.getByLabelText('New password'), { target: { value: 'abcd1234' } });
    await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'differentpw' } });
    await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
    expect(resetPassword).not.toHaveBeenCalled();
    await waitFor(() => expect(screen.getByRole('alert').textContent).toMatch(/do not match/i));
  });

  it('calls resetPassword with the URL token and new password, redirects on success', async () => {
    (resetPassword as unknown as ReturnType<typeof vi.fn>).mockResolvedValue(undefined);
    render(ResetPasswordPage);
    await fireEvent.input(screen.getByLabelText('New password'), { target: { value: 'abcd1234' } });
    await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'abcd1234' } });
    await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
    expect(resetPassword).toHaveBeenCalledWith('test-token-abc', 'abcd1234');
    await waitFor(() => expect(goto).toHaveBeenCalledWith('/login?reset=ok', expect.objectContaining({ replaceState: true })));
  });

  it('shows clear error on invalid_token', async () => {
    (resetPassword as unknown as ReturnType<typeof vi.fn>).mockRejectedValueOnce({ code: 'invalid_token' });
    render(ResetPasswordPage);
    await fireEvent.input(screen.getByLabelText('New password'), { target: { value: 'abcd1234' } });
    await fireEvent.input(screen.getByLabelText('Confirm new password'), { target: { value: 'abcd1234' } });
    await fireEvent.click(screen.getByRole('button', { name: 'Set password' }));
    await waitFor(() => expect(screen.getByRole('alert').textContent).toMatch(/invalid, expired, or already used/i));
  });
});
