import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ThemeProvider } from 'styled-components';
import { MemoryRouter } from 'react-router-dom';
import { I18nextProvider } from 'react-i18next';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import '@testing-library/jest-dom';
import TicketsPage from '@/features/tickets/pages/TicketsPage';
import * as ticketService from '@/features/tickets/services/ticketService';
import type { PaginatedResponse } from '@/shared/types/pagination.types';
import type { TicketSummary } from '@/features/tickets/types/ticket.types';
import i18n from '@/locales/i18n';
import { LocaleProvider } from '@/app/providers/LocaleProvider';
import { lightTheme } from '@/styles/theme';

vi.mock('@/features/tickets/services/ticketService');

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

const mockTicket: TicketSummary = {
  id: 'ticket-1',
  ticket_number: 'TKT-100',
  subject: 'VPN outage',
  description: 'Cannot connect',
  department: { id: 'dept-1', name: 'IT', code: 'IT' },
  requester: { id: 'u1', name: 'Jane', email: 'jane@test.com' },
  assignee: { id: 'u2', name: 'John', email: 'john@test.com' },
  status: {
    id: 'st-1',
    name_en: 'Open',
    name_ar: 'مفتوح',
    color: '#f00',
    is_closed: false,
  },
  priority: {
    id: 'pr-1',
    name_en: 'High',
    name_ar: 'عالي',
    color: '#f90',
    sort_order: 1,
  },
  first_response_at: null,
  resolved_at: null,
  closed_at: null,
  created_at: '2026-05-18T10:00:00Z',
  updated_at: '2026-05-18T12:00:00Z',
  age_in_days: 1,
  is_assigned: true,
  is_open: true,
};

const paginated: PaginatedResponse<TicketSummary> = {
  data: [mockTicket],
  meta: { current_page: 1, last_page: 1, per_page: 15, total: 1 },
};

function renderTicketsPage() {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });

  return render(
    <QueryClientProvider client={queryClient}>
      <I18nextProvider i18n={i18n}>
        <LocaleProvider>
          <ThemeProvider theme={lightTheme}>
            <MemoryRouter>
              <TicketsPage />
            </MemoryRouter>
          </ThemeProvider>
        </LocaleProvider>
      </I18nextProvider>
    </QueryClientProvider>,
  );
}

describe('TicketsPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    void i18n.changeLanguage('en');
  });

  it('shows loading state while fetching tickets', () => {
    vi.mocked(ticketService.fetchTickets).mockReturnValue(new Promise(() => {}));

    renderTicketsPage();

    expect(screen.getByRole('status')).toBeInTheDocument();
    expect(screen.getByText(/loading tickets/i)).toBeInTheDocument();
  });

  it('renders ticket list on success', async () => {
    vi.mocked(ticketService.fetchTickets).mockResolvedValue(paginated);

    renderTicketsPage();

    await waitFor(() => {
      expect(screen.getByText('VPN outage')).toBeInTheDocument();
    });

    expect(screen.getByText(/TKT-100/)).toBeInTheDocument();
    expect(screen.getByText(/Jane/)).toBeInTheDocument();
  });

  it('shows error state when fetch fails', async () => {
    vi.mocked(ticketService.fetchTickets).mockRejectedValue(new Error('Server error'));

    renderTicketsPage();

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

    expect(screen.getByText('Server error')).toBeInTheDocument();
  });
});
