import React from 'react';
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, waitFor, within } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ContactsListPage } from '@/pages/ContactsList';

const mockContacts = [
  {
    id: '1',
    type: 'company',
    displayname: 'TestCorp GmbH',
    name: 'TestCorp GmbH',
    email_1: 'info@test.de',
    phone_1: '+49 30 123',
    mailing_city: 'Berlin',
    tags: 'VIP, IT',
    discount_crew: 0,
    discount_transport: 0,
    discount_rental: 0,
    discount_sale: 0,
    discount_subrent: 0,
    discount_total: 0,
    created_at: '2025-01-01T00:00:00Z',
    updated_at: '2025-01-01T00:00:00Z',
  },
  {
    id: '2',
    type: 'person',
    displayname: 'Max Mustermann',
    firstname: 'Max',
    surname: 'Mustermann',
    email_1: 'max@test.de',
    phone_1: '+49 89 987',
    mailing_city: 'München',
    tags: null,
    discount_crew: 0,
    discount_transport: 0,
    discount_rental: 0,
    discount_sale: 0,
    discount_subrent: 0,
    discount_total: 0,
    created_at: '2025-01-02T00:00:00Z',
    updated_at: '2025-01-02T00:00:00Z',
  },
];

let mockListData: any = { items: mockContacts, total: 2, page: 1, page_size: 25 };
let mockIsLoading = false;
let mockDetailData: any = undefined;
let mockDetailLoading = false;

vi.mock('@/api/hooks', () => ({
  useUnifiedContacts: () => ({ data: mockListData, isLoading: mockIsLoading }),
  useUnifiedContact: () => ({ data: mockDetailData, isLoading: mockDetailLoading }),
  useCreateUnifiedContact: () => ({ mutateAsync: vi.fn().mockResolvedValue({ id: 'new-1' }), isPending: false }),
  useUpdateUnifiedContact: () => ({ mutateAsync: vi.fn(), isPending: false }),
  useDeleteUnifiedContact: () => ({ mutateAsync: vi.fn(), isPending: false }),
  useCreateContactPerson: () => ({ mutateAsync: vi.fn(), isPending: false }),
  useUpdateContactPerson: () => ({ mutateAsync: vi.fn(), isPending: false }),
  useDeleteContactPerson: () => ({ mutateAsync: vi.fn(), isPending: false }),
  useContactFolders: () => ({ data: [], isLoading: false }),
  useCreateContactFolder: () => ({ mutate: vi.fn(), isPending: false }),
  useUpdateContactFolder: () => ({ mutate: vi.fn(), isPending: false }),
  useDeleteContactFolder: () => ({ mutate: vi.fn(), isPending: false }),
  useMoveContactToFolder: () => ({ mutate: vi.fn(), isPending: false }),
}));

vi.mock('@/components/ui/Toast', () => ({
  useToast: () => ({ success: vi.fn(), error: vi.fn(), info: vi.fn() }),
}));

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

// jsdom renders both desktop (hidden md:flex) and mobile (flex md:hidden) views
// because it doesn't process CSS media queries. Use getAllByTestId to handle duplicates.
function getFirstByTestId(testId: string) {
  const elements = screen.getAllByTestId(testId);
  return elements[0];
}

// Helper: click 'Alle Kontakte' folder to switch to list view (mobile)
function goToList() {
  const folderTree = getFirstByTestId('contact-folder-tree');
  fireEvent.click(within(folderTree).getByText('Alle Kontakte'));
}

describe('ContactsListPage (Unified)', () => {
  beforeEach(() => {
    mockListData = { items: mockContacts, total: 2, page: 1, page_size: 25 };
    mockIsLoading = false;
    mockDetailData = undefined;
    mockDetailLoading = false;
  });

  afterEach(() => {
    mockListData = { items: mockContacts, total: 2, page: 1, page_size: 25 };
    mockIsLoading = false;
    mockDetailData = undefined;
    mockDetailLoading = false;
  });

  it('renders the page', () => {
    renderWithProviders();
    expect(getFirstByTestId('contacts-list-page')).toBeInTheDocument();
  });

  it('renders folder tree with all contacts filter', () => {
    renderWithProviders();
    const folderTree = getFirstByTestId('contact-folder-tree');
    expect(folderTree).toBeInTheDocument();
    expect(within(folderTree).getByText('Alle Kontakte')).toBeInTheDocument();
  });

  it('renders contact list with contacts', () => {
    renderWithProviders();
    goToList();
    expect(screen.getAllByText('TestCorp GmbH').length).toBeGreaterThan(0);
    expect(screen.getAllByText('Max Mustermann').length).toBeGreaterThan(0);
  });

  it('renders new button', () => {
    renderWithProviders();
    goToList();
    expect(screen.getAllByTestId('contacts-new-btn').length).toBeGreaterThan(0);
  });

  it('renders search input', () => {
    renderWithProviders();
    goToList();
    expect(screen.getAllByPlaceholderText('Kontakte durchsuchen...').length).toBeGreaterThan(0);
  });

  it('shows empty detail panel when no contact selected', () => {
    renderWithProviders();
    expect(screen.getAllByText('Kein Kontakt ausgewählt').length).toBeGreaterThan(0);
  });

  it('shows contact detail when contact is selected', async () => {
    mockDetailData = {
      ...mockContacts[0],
      contact_persons: [],
    };
    renderWithProviders();
    goToList();
    // Click on first contact in list (mobile view)
    const contactButtons = screen.getAllByText('TestCorp GmbH');
    fireEvent.click(contactButtons[0]);
    await waitFor(() => {
      expect(screen.getAllByTestId('contact-detail').length).toBeGreaterThan(0);
    });
  });

  it('renders tags in folder tree from contacts', () => {
    renderWithProviders();
    const folderTree = getFirstByTestId('contact-folder-tree');
    expect(within(folderTree).getByText('VIP')).toBeInTheDocument();
    expect(within(folderTree).getByText('IT')).toBeInTheDocument();
  });

  it('shows loading state', () => {
    mockIsLoading = true;
    mockListData = undefined;
    renderWithProviders();
    goToList();
    expect(screen.getAllByTestId('contact-list-loading').length).toBeGreaterThan(0);
  });

  it('opens edit modal when new button clicked', () => {
    renderWithProviders();
    goToList();
    const newBtns = screen.getAllByTestId('contacts-new-btn');
    fireEvent.click(newBtns[0]);
    expect(screen.getByTestId('contact-type-select')).toBeInTheDocument();
  });

  it('shows empty state when no contacts', () => {
    mockListData = { items: [], total: 0, page: 1, page_size: 25 };
    renderWithProviders();
    goToList();
    expect(screen.getAllByTestId('contact-list-empty').length).toBeGreaterThan(0);
  });
});
