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

// Mock next-intl with Vietnamese messages
const viMessages = await import('@/messages/vi.json');
vi.mock('next-intl', () => ({
  useTranslations: (namespace?: string) => {
    const messages = viMessages.default ?? viMessages;
    const ns = namespace
      ? (messages[namespace as keyof typeof messages] as Record<string, unknown> | undefined)
      : (messages as unknown as Record<string, unknown>);
    return (key: string, params?: Record<string, unknown>) => {
      if (!ns) return key;
      const parts = key.split('.');
      let val: unknown = ns;
      for (const p of parts) {
        val = (val as Record<string, unknown>)?.[p];
      }
      if (typeof val === 'string' && params) {
        return val.replace(/\{(\w+)\}/g, (_, k: string) => String(params[k] ?? `{${k}}`));
      }
      return typeof val === 'string' ? val : key;
    };
  },
  useLocale: () => 'vi',
  NextIntlClientProvider: ({ children }: { children: React.ReactNode }) => children,
}));

const mockPush = vi.fn();
const mockReplace = vi.fn();
const mockSearchParams = new URLSearchParams();
vi.mock('next/navigation', () => ({
  useRouter: () => ({ push: mockPush, replace: mockReplace }),
  useSearchParams: () => mockSearchParams,
}));

vi.mock('next/link', () => ({
  default: ({ children, href, ...props }: { children: React.ReactNode; href: string; [key: string]: unknown }) => (
    <a href={href} {...props}>{children}</a>
  ),
}));

vi.mock('next/image', () => ({
  default: (props: Record<string, unknown>) => <img {...props} />,
}));

// Mock dynamic import for map component
vi.mock('next/dynamic', () => ({
  default: () => {
    const MockMap = () => <div data-testid="map-placeholder">Map</div>;
    MockMap.displayName = 'MockMap';
    return MockMap;
  },
}));

const mockListings = {
  data: [
    {
      id: '1',
      status: 'ACTIVE',
      transactionType: 'SALE',
      priceVND: '5000000000',
      pricePerM2: null,
      rentPriceMonthly: null,
      commissionPct: null,
      viewCount: 10,
      saveCount: 2,
      inquiryCount: 1,
      publishedAt: '2024-01-01',
      createdAt: '2024-01-01',
      property: {
        id: 'p1',
        propertyType: 'APARTMENT',
        title: 'Căn hộ Quận 7',
        description: 'Căn hộ view sông',
        address: '123 Nguyễn Hữu Thọ',
        ward: 'Phường Tân Hưng',
        district: 'Quận 7',
        city: 'Hồ Chí Minh',
        areaM2: 75,
        bedrooms: 2,
        bathrooms: 2,
        floors: null,
        direction: null,
        yearBuilt: null,
        legalStatus: null,
        amenities: null,
        projectName: null,
        media: [],
      },
      seller: { id: 's1', fullName: 'Nguyen Van A', phone: '0912345678' },
      agent: null,
    },
  ],
  total: 1,
  page: 1,
  limit: 12,
  totalPages: 1,
};

vi.mock('@/lib/listings-api', () => ({
  listingsApi: {
    search: vi.fn(),
  },
}));

vi.mock('@/lib/hooks/use-saved-searches', () => ({
  useCreateSavedSearch: () => ({
    mutateAsync: vi.fn(),
    isPending: false,
  }),
  useSavedSearches: () => ({ data: [], isLoading: false }),
}));

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { listingsApi } from '@/lib/listings-api';
import SearchPage from '../page';

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

function Wrapper({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  );
}

const mockedListingsApi = vi.mocked(listingsApi);

describe('SearchPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockedListingsApi.search.mockResolvedValue(mockListings as never);
  });

  it('renders the search page title', async () => {
    render(<SearchPage />, { wrapper: Wrapper });

    await waitFor(() => {
      expect(screen.getByText('Tìm kiếm bất động sản')).toBeInTheDocument();
    });
  });

  it('renders view mode toggle buttons', async () => {
    render(<SearchPage />, { wrapper: Wrapper });

    await waitFor(() => {
      expect(screen.getByRole('button', { name: /danh sách/i })).toBeInTheDocument();
      expect(screen.getByRole('button', { name: /bản đồ/i })).toBeInTheDocument();
    });
  });

  it('calls listings API on mount', async () => {
    render(<SearchPage />, { wrapper: Wrapper });

    await waitFor(() => {
      expect(mockedListingsApi.search).toHaveBeenCalled();
    });
  });

  it('displays listing results after loading', async () => {
    render(<SearchPage />, { wrapper: Wrapper });

    await waitFor(() => {
      expect(screen.getByText(/căn hộ quận 7/i)).toBeInTheDocument();
    });
  });

  it('switches to map view when map button is clicked', async () => {
    render(<SearchPage />, { wrapper: Wrapper });

    await waitFor(() => {
      expect(screen.getByRole('button', { name: /bản đồ/i })).toBeInTheDocument();
    });

    await userEvent.click(screen.getByRole('button', { name: /bản đồ/i }));

    await waitFor(() => {
      expect(screen.getByTestId('map-placeholder')).toBeInTheDocument();
    });
  });
});
