import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import ResetPasswordPage from '../ResetPasswordPage';
import { authService } from '../../../services/auth/auth.service';

jest.mock('../../../services/auth/auth.service', () => ({
  authService: {
    resetPassword: jest.fn(),
  },
}));

const mockedAuthService = authService as jest.Mocked<typeof authService>;
const mockedResetPassword = mockedAuthService.resetPassword;

const setLocation = (url: string) => {
  window.history.replaceState({}, 'Test', url);
};

describe('ResetPasswordPage', () => {
  beforeEach(() => {
    mockedResetPassword.mockReset();
  });

  test('renders invalid token state when no token provided', () => {
    setLocation('http://localhost/reset-password');

    render(React.createElement(ResetPasswordPage));

    expect(screen.getByText('Password Reset Link Invalid')).toBeInTheDocument();
    expect(
      screen.getByRole('button', { name: /back to sign in/i })
    ).toBeInTheDocument();
  });

  test('shows validation error when passwords do not match', async () => {
    setLocation('http://localhost/reset-password?token=abc123');

    render(React.createElement(ResetPasswordPage));

    fireEvent.change(screen.getByLabelText('New Password'), {
      target: { value: 'Password1!' },
    });
    fireEvent.change(screen.getByLabelText('Confirm Password'), {
      target: { value: 'SomethingElse' },
    });

    fireEvent.click(screen.getByRole('button', { name: /update password/i }));

    expect(
      await screen.findByText('Passwords do not match.')
    ).toBeInTheDocument();
    expect(mockedResetPassword).not.toHaveBeenCalled();
  });

  test('submits password reset and displays success state', async () => {
    setLocation('http://localhost/reset-password?token=token123');
    mockedResetPassword.mockResolvedValue({
      user: {
        _id: 'user-1',
        _rev: '1',
        username: 'Reset User',
      } as any,
      message: 'Password reset successfully',
    });

    render(React.createElement(ResetPasswordPage));

    fireEvent.change(screen.getByLabelText('New Password'), {
      target: { value: 'Password1!' },
    });
    fireEvent.change(screen.getByLabelText('Confirm Password'), {
      target: { value: 'Password1!' },
    });

    fireEvent.click(screen.getByRole('button', { name: /update password/i }));

    await waitFor(() => {
      expect(mockedResetPassword).toHaveBeenCalledWith(
        'token123',
        'Password1!'
      );
    });

    expect(await screen.findByText('Password Updated')).toBeInTheDocument();
    expect(
      screen.getByRole('button', { name: /go to sign in/i })
    ).toBeInTheDocument();
  });
});
