import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';

import ClusterOverview from '@/Components/TopicClusters/ClusterOverview';

function makeCluster(overrides: Record<string, unknown> = {}) {
  return {
    id: 1,
    name: 'Running Shoes',
    total_demand: 5000,
    coverage_percentage: 65.5,
    hub_page_url: 'https://example.com/running-shoes',
    metadata: {
      representative_queries: ['best running shoes', 'running shoes for beginners'],
    },
    ...overrides,
  };
}

function makeMembers(overrides: { queries?: number; pages?: number } = {}) {
  const queryCount = overrides.queries ?? 10;
  const pageCount = overrides.pages ?? 5;

  const queries = Array.from({ length: queryCount }, (_, i) => ({
    id: i + 1,
    member_type: 'query' as const,
    member_value: `query ${i + 1}`,
    clicks: 100 + i,
    impressions: 1000 + i,
    position: 5.5 + i * 0.1,
    is_hub: false,
  }));

  const pages = Array.from({ length: pageCount }, (_, i) => ({
    id: queryCount + i + 1,
    member_type: 'page' as const,
    member_value: `https://example.com/page-${i + 1}`,
    clicks: 200 + i,
    impressions: 2000 + i,
    position: 3.5 + i * 0.1,
    is_hub: i === 0,
  }));

  return [...queries, ...pages];
}

describe('ClusterOverview', () => {
  it('renders total demand with formatting', () => {
    const cluster = makeCluster({ total_demand: 12345 });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('12,345')).toBeInTheDocument();
    expect(screen.getByText('Total Demand')).toBeInTheDocument();
    expect(screen.getByText('Clicks + Impressions')).toBeInTheDocument();
  });

  it('renders coverage percentage with formatting', () => {
    const cluster = makeCluster({ coverage_percentage: 75.789 });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('75.8%')).toBeInTheDocument();
    expect(screen.getByText('Coverage')).toBeInTheDocument();
    expect(screen.getByText('Entity Coverage')).toBeInTheDocument();
  });

  it('renders query count correctly', () => {
    const cluster = makeCluster();
    const members = makeMembers({ queries: 15, pages: 5 });
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('15')).toBeInTheDocument();
    const queriesElements = screen.getAllByText('Queries');
    expect(queriesElements.length).toBe(2); // title and subtitle
  });

  it('renders query count with singular form', () => {
    const cluster = makeCluster();
    const members = makeMembers({ queries: 1, pages: 5 });
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('1')).toBeInTheDocument();
    expect(screen.getByText('Query')).toBeInTheDocument();
  });

  it('renders page count correctly', () => {
    const cluster = makeCluster();
    const members = makeMembers({ queries: 10, pages: 8 });
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('8')).toBeInTheDocument();
    const pagesElements = screen.getAllByText('Pages');
    expect(pagesElements.length).toBe(2); // title and subtitle
  });

  it('renders page count with singular form', () => {
    const cluster = makeCluster();
    const members = makeMembers({ queries: 10, pages: 1 });
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('1')).toBeInTheDocument();
    expect(screen.getByText('Page')).toBeInTheDocument();
  });

  it('renders hub page URL when present', () => {
    const cluster = makeCluster({ hub_page_url: 'https://example.com/hub' });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('Hub Page')).toBeInTheDocument();
    const link = screen.getByRole('link', { name: /https:\/\/example\.com\/hub/i });
    expect(link).toBeInTheDocument();
    expect(link).toHaveAttribute('href', 'https://example.com/hub');
    expect(link).toHaveAttribute('target', '_blank');
    expect(link).toHaveAttribute('rel', 'noopener noreferrer');
  });

  it('does not render hub page section when URL is null', () => {
    const cluster = makeCluster({ hub_page_url: null });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.queryByText('Hub Page')).not.toBeInTheDocument();
  });

  it('handles zero queries and pages', () => {
    const cluster = makeCluster();
    const members = makeMembers({ queries: 0, pages: 0 });
    render(<ClusterOverview cluster={cluster} members={members} />);
    const zeros = screen.getAllByText('0');
    expect(zeros.length).toBeGreaterThanOrEqual(2); // at least queries and pages
    const queriesElements = screen.getAllByText('Queries');
    expect(queriesElements.length).toBe(2); // title and subtitle
  });

  it('formats large demand numbers with commas', () => {
    const cluster = makeCluster({ total_demand: 1234567 });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('1,234,567')).toBeInTheDocument();
  });

  it('renders all four data cards', () => {
    const cluster = makeCluster();
    const members = makeMembers();
    const { container } = render(<ClusterOverview cluster={cluster} members={members} />);
    const cards = container.querySelectorAll('.rounded-lg.border.bg-card');
    // 4 data cards + 1 hub page card = 5 total
    expect(cards.length).toBeGreaterThanOrEqual(4);
  });

  it('handles coverage percentage of 0', () => {
    const cluster = makeCluster({ coverage_percentage: 0 });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('0.0%')).toBeInTheDocument();
  });

  it('handles coverage percentage of 100', () => {
    const cluster = makeCluster({ coverage_percentage: 100 });
    const members = makeMembers();
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('100.0%')).toBeInTheDocument();
  });

  it('filters members by type correctly', () => {
    const cluster = makeCluster();
    const members = [
      {
        id: 1,
        member_type: 'query' as const,
        member_value: 'q1',
        clicks: 10,
        impressions: 100,
        position: 5,
        is_hub: false,
      },
      {
        id: 2,
        member_type: 'query' as const,
        member_value: 'q2',
        clicks: 20,
        impressions: 200,
        position: 5,
        is_hub: false,
      },
      {
        id: 3,
        member_type: 'page' as const,
        member_value: 'p1',
        clicks: 30,
        impressions: 300,
        position: 3,
        is_hub: true,
      },
      {
        id: 4,
        member_type: 'query' as const,
        member_value: 'q3',
        clicks: 40,
        impressions: 400,
        position: 5,
        is_hub: false,
      },
    ];
    render(<ClusterOverview cluster={cluster} members={members} />);
    expect(screen.getByText('3')).toBeInTheDocument(); // 3 queries
    expect(screen.getByText('1')).toBeInTheDocument(); // 1 page
    expect(screen.getByText('Page')).toBeInTheDocument(); // singular
  });

  it('renders external link icon for hub page', () => {
    const cluster = makeCluster({ hub_page_url: 'https://example.com/hub' });
    const members = makeMembers();
    const { container } = render(<ClusterOverview cluster={cluster} members={members} />);
    // Check for lucide-react ExternalLink icon (has specific class)
    const icon = container.querySelector('svg.lucide-external-link');
    expect(icon).toBeInTheDocument();
  });
});
