import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { SupportPage } from './SupportPage';

// Mock dependencies
vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, fallback?: string) => fallback || key,
  }),
}));

vi.mock('@/features/auth/hooks/useUser', () => ({
  useUser: () => ({ data: { email: 'test@example.com', username: 'testuser' } }),
}));

vi.mock('@/features/auth/store/authStore', () => ({
  useAuthStore: () => ({ isAuthenticated: true }),
}));

vi.mock('@/components/layout/DashboardLayout', () => ({
  DashboardLayout: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
}));

const mockPost = vi.fn().mockResolvedValue({ data: { ticket_id: 'ticket-123' } });
vi.mock('@/services/api/client', () => ({
  apiClient: { post: (...args: unknown[]) => mockPost(...args) },
}));

function renderWithProviders(ui: React.ReactElement) {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });
  return render(
    <QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>,
  );
}

describe('SupportPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockPost.mockResolvedValue({ data: { ticket_id: 'ticket-123' } });
  });

  it('should render the support form', () => {
    renderWithProviders(<SupportPage />);
    expect(screen.getByText('Support')).toBeDefined();
    expect(screen.getByLabelText('Email address')).toBeDefined();
    expect(screen.getByLabelText('Subject')).toBeDefined();
    expect(screen.getByLabelText('Message')).toBeDefined();
  });

  it('should pre-fill email from authenticated user', () => {
    renderWithProviders(<SupportPage />);
    const emailInput = screen.getByLabelText('Email address') as HTMLInputElement;
    expect(emailInput.value).toBe('test@example.com');
  });

  it('should disable submit when form is incomplete', () => {
    renderWithProviders(<SupportPage />);
    const submitBtn = screen.getByRole('button', { name: /send message/i });
    expect(submitBtn).toBeDisabled();
  });

  it('should enable submit when form is complete', async () => {
    const user = userEvent.setup();
    renderWithProviders(<SupportPage />);

    await user.type(screen.getByLabelText('Subject'), 'Payment issue');
    await user.type(screen.getByLabelText('Message'), 'I have a problem with my recent purchase.');

    const submitBtn = screen.getByRole('button', { name: /send message/i });
    expect(submitBtn).not.toBeDisabled();
  });

  it('should submit the form and show success message', async () => {
    const user = userEvent.setup();
    renderWithProviders(<SupportPage />);

    await user.type(screen.getByLabelText('Subject'), 'Payment issue');
    await user.type(screen.getByLabelText('Message'), 'I have a problem with my recent purchase.');
    await user.click(screen.getByRole('button', { name: /send message/i }));

    await waitFor(() => {
      expect(screen.getByText('Message sent!')).toBeDefined();
    });

    expect(mockPost).toHaveBeenCalledWith('/support/tickets', expect.objectContaining({
      email: 'test@example.com',
      subject: 'Payment issue',
      category: 'general',
    }));
  });

  it('should show error on submission failure', async () => {
    mockPost.mockRejectedValueOnce(new Error('Network error'));
    const user = userEvent.setup();
    renderWithProviders(<SupportPage />);

    await user.type(screen.getByLabelText('Subject'), 'Payment issue');
    await user.type(screen.getByLabelText('Message'), 'I have a problem with my recent purchase.');
    await user.click(screen.getByRole('button', { name: /send message/i }));

    await waitFor(() => {
      expect(screen.getByRole('alert')).toBeDefined();
    });
  });

  it('should render quick help links', () => {
    renderWithProviders(<SupportPage />);
    expect(screen.getByText('Quick help')).toBeDefined();
    expect(screen.getByText('Payment issues')).toBeDefined();
    expect(screen.getByText('Account settings')).toBeDefined();
  });
});
