import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi, beforeEach } from 'vitest';

const mockPut = vi.fn();
const mockSetData = vi.fn();
const mockReset = vi.fn();

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    useForm: vi.fn(() => ({
      data: { current_password: '', password: '', password_confirmation: '' },
      setData: mockSetData,
      put: mockPut,
      processing: false,
      errors: {},
      reset: mockReset,
    })),
    Head: () => null,
  };
});

import UpdatePasswordForm from './UpdatePasswordForm';

describe('UpdatePasswordForm', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders all three password fields', () => {
    render(<UpdatePasswordForm />);
    expect(screen.getByLabelText(/current password/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/new password/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/confirm password/i)).toBeInTheDocument();
  });

  it('renders the Update Password submit button', () => {
    render(<UpdatePasswordForm />);
    expect(screen.getByRole('button', { name: /update password/i })).toBeInTheDocument();
  });

  it('calls setData when typing in current_password field', async () => {
    const user = userEvent.setup();
    render(<UpdatePasswordForm />);

    await user.type(screen.getByLabelText(/current password/i), 'mypassword');

    expect(mockSetData).toHaveBeenCalledWith('current_password', expect.any(String));
  });

  it('calls put on form submit', async () => {
    const user = userEvent.setup();
    render(<UpdatePasswordForm />);

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

    expect(mockPut).toHaveBeenCalledWith('/password', expect.any(Object));
  });

  it('displays field-level validation error', async () => {
    const { useForm } = await import('@inertiajs/react');
    const pwValidationMsg = 'The ' + 'password field must be at least 8 characters.';
    vi.mocked(useForm).mockReturnValueOnce({
      data: { current_password: '', password: '', password_confirmation: '' },
      setData: mockSetData,
      put: mockPut,
      processing: false,
      errors: { password: pwValidationMsg },
      reset: mockReset,
    } as unknown as ReturnType<typeof useForm>);

    render(<UpdatePasswordForm />);
    expect(screen.getByText(/must be at least 8 characters/i)).toBeInTheDocument();
  });
});
