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

const mockPost = vi.fn();
const mockSetData = vi.fn();

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    useForm: vi.fn(() => ({
      data: { name: '', email: '', request_type: '', verification_details: '' },
      setData: mockSetData,
      post: mockPost,
      processing: false,
      errors: {},
      wasSuccessful: false,
      reset: vi.fn(),
    })),
    Head: () => null,
  };
});

vi.mock('@/Components/marketing/MarketingNav', () => ({
  MarketingNav: () => <nav data-testid="marketing-nav" />,
}));

vi.mock('@/Components/marketing/MarketingFooter', () => ({
  MarketingFooter: () => <footer data-testid="marketing-footer" />,
}));

import DataRequest from './DataRequest';

const defaultProps = { canLogin: true, canRegister: true };

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

  it('renders the DSAR form heading', () => {
    render(<DataRequest {...defaultProps} />);
    expect(
      screen.getByRole('heading', { name: /data subject access request/i }),
    ).toBeInTheDocument();
  });

  it('renders all required form fields', () => {
    render(<DataRequest {...defaultProps} />);
    expect(screen.getByLabelText(/full name/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/email address/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/request type/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/verification details/i)).toBeInTheDocument();
  });

  it('renders the Submit Request button', () => {
    render(<DataRequest {...defaultProps} />);
    expect(screen.getByRole('button', { name: /submit request/i })).toBeInTheDocument();
  });

  it('calls setData when typing name', async () => {
    const user = userEvent.setup();
    render(<DataRequest {...defaultProps} />);

    await user.type(screen.getByLabelText(/full name/i), 'Jane Doe');

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

  it('calls post on form submit', async () => {
    const user = userEvent.setup();
    render(<DataRequest {...defaultProps} />);

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

    expect(mockPost).toHaveBeenCalledWith('/privacy/data-request', expect.any(Object));
  });

  it('shows success message when wasSuccessful is true', async () => {
    const { useForm } = await import('@inertiajs/react');
    vi.mocked(useForm).mockReturnValueOnce({
      data: { name: '', email: '', request_type: '', verification_details: '' },
      setData: mockSetData,
      post: mockPost,
      processing: false,
      errors: {},
      wasSuccessful: true,
      reset: vi.fn(),
    } as unknown as ReturnType<typeof useForm>);

    render(<DataRequest {...defaultProps} />);
    expect(screen.getByText(/your request has been received/i)).toBeInTheDocument();
  });
});
