import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';
import type { ListingDetail } from '@/lib/listings-api';
import { ComparisonTable } from '../comparison-table';

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

// Mock next-intl
vi.mock('next-intl', () => ({
  useTranslations: () => (key: string) => {
    const translations: Record<string, string> = {
      property: 'Bất động sản',
      price: 'Giá',
      transactionType: 'Loại giao dịch',
      propertyType: 'Loại BĐS',
      area: 'Diện tích',
      pricePerM2: 'Giá/m²',
      bedrooms: 'Phòng ngủ',
      bathrooms: 'Phòng tắm',
      direction: 'Hướng',
      floors: 'Số tầng',
      yearBuilt: 'Năm xây',
      legalStatus: 'Pháp lý',
      location: 'Vị trí',
      amenities: 'Tiện ích',
      projectName: 'Dự án',
      rooms: 'phòng',
      remove: 'Xóa',
      noImage: 'Chưa có ảnh',
      sale: 'Bán',
      rent: 'Cho thuê',
    };
    return translations[key] ?? key;
  },
}));

// Mock @/i18n/navigation
vi.mock('@/i18n/navigation', () => ({
  Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
    <a href={href}>{children}</a>
  ),
}));

// Mock currency
vi.mock('@/lib/currency', () => ({
  formatPrice: (price: string) => {
    const n = Number(price);
    return n >= 1_000_000_000 ? `${(n / 1_000_000_000).toFixed(1)} tỷ` : String(n);
  },
  formatPricePerM2: (price: number) => `${(price / 1_000_000).toFixed(1)} tr/m²`,
}));

// Mock image-blur
vi.mock('@/lib/image-blur', () => ({
  shimmerBlurDataURL: () => 'data:image/svg+xml;base64,mock',
}));

// Mock lucide-react
vi.mock('lucide-react', () => ({
  X: () => <span data-testid="x-icon">X</span>,
}));

function makeListing(id: string, overrides: Partial<ListingDetail> = {}): ListingDetail {
  return {
    id,
    status: 'ACTIVE',
    transactionType: 'SALE',
    priceVND: '3500000000',
    pricePerM2: 40_000_000,
    rentPriceMonthly: null,
    commissionPct: null,
    viewCount: 100,
    saveCount: 10,
    inquiryCount: 5,
    publishedAt: '2026-01-01T00:00:00Z',
    createdAt: '2025-12-01T00:00:00Z',
    valuationEstimate: null,
    agentQualityScore: null,
    similarCount: 0,
    property: {
      id: `prop-${id}`,
      propertyType: 'APARTMENT',
      title: `Căn hộ ${id}`,
      description: 'Test',
      address: '123 Test St',
      ward: 'Ward',
      district: 'Quận 1',
      city: 'HCMC',
      areaM2: 75,
      bedrooms: 2,
      bathrooms: 2,
      floors: null,
      direction: 'SOUTH',
      yearBuilt: 2020,
      legalStatus: 'SO_HONG',
      amenities: ['Gym', 'Pool'],
      projectName: 'Vinhomes',
      latitude: null,
      longitude: null,
      media: [{ id: 'm1', type: 'image', url: 'https://example.com/img.jpg', order: 0, caption: null }],
      usableAreaM2: null,
      floor: null,
      totalFloors: null,
      nearbyPOIs: null,
      metroDistanceM: null,
      furnishing: null,
      propertyCondition: null,
      balconyDirection: null,
      maintenanceFeeVND: null,
      parkingSlots: null,
      viewType: [],
      petFriendly: null,
      suitableFor: [],
      whyThisLocation: null,
    },
    seller: { id: 's1', fullName: 'Seller', phone: '0901234567' },
    agent: null,
    ...overrides,
  };
}

describe('ComparisonTable', () => {
  it('returns null when listings are empty', () => {
    const { container } = render(<ComparisonTable listings={[]} onRemove={vi.fn()} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders table with listings', () => {
    render(<ComparisonTable listings={[makeListing('1'), makeListing('2')]} onRemove={vi.fn()} />);
    expect(screen.getByText('Căn hộ 1')).toBeInTheDocument();
    expect(screen.getByText('Căn hộ 2')).toBeInTheDocument();
  });

  it('renders comparison rows', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    expect(screen.getByText('Giá')).toBeInTheDocument();
    expect(screen.getByText('Loại giao dịch')).toBeInTheDocument();
    expect(screen.getByText('Loại BĐS')).toBeInTheDocument();
    expect(screen.getByText('Diện tích')).toBeInTheDocument();
  });

  it('renders property area', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    expect(screen.getByText('75 m²')).toBeInTheDocument();
  });

  it('renders remove button', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    expect(screen.getByText('Xóa')).toBeInTheDocument();
  });

  it('calls onRemove when remove clicked', async () => {
    const user = userEvent.setup();
    const onRemove = vi.fn();
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={onRemove} />);

    await user.click(screen.getByText('Xóa'));
    expect(onRemove).toHaveBeenCalledWith('1');
  });

  it('renders direction value', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    expect(screen.getByText('Nam')).toBeInTheDocument();
  });

  it('renders amenities', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    expect(screen.getByText('Gym')).toBeInTheDocument();
    expect(screen.getByText('Pool')).toBeInTheDocument();
  });

  it('renders project name', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    expect(screen.getByText('Vinhomes')).toBeInTheDocument();
  });

  it('shows "—" for missing values', () => {
    const listing = makeListing('1');
    listing.property.floors = null;
    render(<ComparisonTable listings={[listing]} onRemove={vi.fn()} />);
    // floors row should have —
    const dashes = screen.getAllByText('—');
    expect(dashes.length).toBeGreaterThan(0);
  });

  it('renders bedrooms with room suffix', () => {
    render(<ComparisonTable listings={[makeListing('1')]} onRemove={vi.fn()} />);
    // Bedrooms and bathrooms both show "2 phòng"
    expect(screen.getAllByText('2 phòng').length).toBeGreaterThanOrEqual(1);
  });
});
