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

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

function makeSuggestion(overrides: Record<string, unknown> = {}) {
  return {
    id: 1,
    suggestion_type: 'expand_hub',
    missing_entity: {
      entity_text: 'marathon training tips',
      entity_type: 'phrase',
    },
    target_page_url: 'https://example.com/running-guide',
    impact_score: 75.5,
    confidence_score: 0.85,
    effort_score: 0.3,
    risk_score: 0.15,
    title: 'Add coverage for "marathon training tips" to hub page',
    reasoning:
      'High demand entity with minimal coverage. Adding this topic would address significant user interest.',
    evidence: {
      entity_text: 'marathon training tips',
      entity_type: 'phrase',
      demand_volume: 1200,
      coverage_strength: 15.5,
      gap_severity: 84.5,
      cluster_coverage: 65.0,
      cluster_total_demand: 5000,
      source: 'query',
    },
    ...overrides,
  };
}

beforeEach(() => {
  vi.stubGlobal(
    'route',
    vi.fn(() => '/mock-route'),
  );
});

describe('GapSuggestionCard', () => {
  it('renders suggestion title', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);
    expect(
      screen.getByText('Add coverage for "marathon training tips" to hub page'),
    ).toBeInTheDocument();
  });

  it('renders suggestion type badge for expand_hub', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ suggestion_type: 'expand_hub' })} />);
    expect(screen.getByText('Expand Hub')).toBeInTheDocument();
  });

  it('renders suggestion type badge for create_page', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ suggestion_type: 'create_page' })} />);
    expect(screen.getByText('Create Page')).toBeInTheDocument();
  });

  it('renders suggestion type badge for add_section', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ suggestion_type: 'add_section' })} />);
    expect(screen.getByText('Add Section')).toBeInTheDocument();
  });

  it('renders suggestion type badge for add_faq', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ suggestion_type: 'add_faq' })} />);
    expect(screen.getByText('Add FAQ')).toBeInTheDocument();
  });

  it('renders missing entity text and type', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);
    expect(screen.getByText('marathon training tips')).toBeInTheDocument();
    expect(screen.getByText('phrase')).toBeInTheDocument();
  });

  it('renders target page URL with external link', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);
    const link = screen.getByRole('link', { name: /https:\/\/example\.com\/running-guide/i });
    expect(link).toBeInTheDocument();
    expect(link).toHaveAttribute('href', 'https://example.com/running-guide');
    expect(link).toHaveAttribute('target', '_blank');
    expect(link).toHaveAttribute('rel', 'noopener noreferrer');
  });

  it('does not render target page section when target_page_url is null', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ target_page_url: null })} />);
    expect(screen.queryByRole('link', { name: /https:\/\// })).not.toBeInTheDocument();
  });

  it('renders reasoning text', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);
    expect(
      screen.getByText(
        'High demand entity with minimal coverage. Adding this topic would address significant user interest.',
      ),
    ).toBeInTheDocument();
  });

  it('renders impact score', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ impact_score: 85.7 })} />);
    expect(screen.getByText('Impact')).toBeInTheDocument();
    expect(screen.getByText('86')).toBeInTheDocument();
  });

  it('renders effort score as percentage', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ effort_score: 0.45 })} />);
    expect(screen.getByText('Effort')).toBeInTheDocument();
    expect(screen.getByText('45')).toBeInTheDocument();
  });

  it('renders Generate Brief button as disabled', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);
    const button = screen.getByRole('button', { name: 'Generate Brief' });
    expect(button).toBeInTheDocument();
    expect(button).toBeDisabled();
    expect(button).toHaveAttribute('title', 'Brief creation coming soon');
  });

  it('renders Generate Draft button as disabled', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);
    const button = screen.getByRole('button', { name: 'Generate Draft' });
    expect(button).toBeInTheDocument();
    expect(button).toBeDisabled();
    expect(button).toHaveAttribute('title', 'Section draft generation coming soon');
  });

  it('toggles evidence section on click', async () => {
    const user = userEvent.setup();
    const { container } = render(<GapSuggestionCard suggestion={makeSuggestion()} />);

    const evidenceButton = screen.getByText('View evidence');

    // Initially hidden (grid-rows-[0fr])
    const collapsibleContainer = container.querySelector('.grid');
    expect(collapsibleContainer).toHaveClass('grid-rows-[0fr]');
    expect(collapsibleContainer).toHaveClass('opacity-0');

    // Click to expand
    await user.click(evidenceButton);
    expect(collapsibleContainer).toHaveClass('grid-rows-[1fr]');
    expect(collapsibleContainer).toHaveClass('opacity-100');

    // Click to collapse
    await user.click(evidenceButton);
    expect(collapsibleContainer).toHaveClass('grid-rows-[0fr]');
    expect(collapsibleContainer).toHaveClass('opacity-0');
  });

  it('renders evidence details when expanded', async () => {
    const user = userEvent.setup();
    render(<GapSuggestionCard suggestion={makeSuggestion()} />);

    const evidenceButton = screen.getByText('View evidence');
    await user.click(evidenceButton);

    expect(screen.getByText('Demand Volume')).toBeInTheDocument();
    expect(screen.getByText('1,200')).toBeInTheDocument();

    expect(screen.getByText('Coverage Strength')).toBeInTheDocument();
    expect(screen.getByText('15.5%')).toBeInTheDocument();

    expect(screen.getByText('Gap Severity')).toBeInTheDocument();
    expect(screen.getByText('84.5%')).toBeInTheDocument();

    expect(screen.getByText('Cluster Coverage')).toBeInTheDocument();
    expect(screen.getByText('65.0%')).toBeInTheDocument();

    expect(screen.getByText('Source')).toBeInTheDocument();
    expect(screen.getByText('query')).toBeInTheDocument();
  });

  it('renders confidence and risk scores in evidence section', async () => {
    const user = userEvent.setup();
    render(
      <GapSuggestionCard
        suggestion={makeSuggestion({ confidence_score: 0.92, risk_score: 0.08 })}
      />,
    );

    const evidenceButton = screen.getByText('View evidence');
    await user.click(evidenceButton);

    expect(screen.getByText('Confidence')).toBeInTheDocument();
    expect(screen.getByText('92%')).toBeInTheDocument();

    expect(screen.getByText('Risk')).toBeInTheDocument();
    expect(screen.getByText('8%')).toBeInTheDocument();
  });

  it('formats large demand volume with commas', async () => {
    const user = userEvent.setup();
    const suggestion = makeSuggestion({
      evidence: {
        entity_text: 'test',
        entity_type: 'keyword',
        demand_volume: 12345,
        coverage_strength: 10,
        gap_severity: 90,
        cluster_coverage: 50,
        cluster_total_demand: 20000,
        source: 'query',
      },
    });
    render(<GapSuggestionCard suggestion={suggestion} />);

    const evidenceButton = screen.getByText('View evidence');
    await user.click(evidenceButton);

    expect(screen.getByText('12,345')).toBeInTheDocument();
  });

  it('handles unknown suggestion type gracefully', () => {
    render(<GapSuggestionCard suggestion={makeSuggestion({ suggestion_type: 'unknown_type' })} />);
    expect(screen.getByText('unknown_type')).toBeInTheDocument();
  });

  it('applies correct progress bar colors for high impact', () => {
    const { container } = render(
      <GapSuggestionCard suggestion={makeSuggestion({ impact_score: 85 })} />,
    );
    const progressBars = container.querySelectorAll('[role="progressbar"]');
    const impactBar = Array.from(progressBars).find((bar) =>
      bar.getAttribute('aria-label')?.includes('Impact'),
    );
    expect(impactBar).toHaveClass('bg-green-500');
  });

  it('applies correct progress bar colors for medium impact', () => {
    const { container } = render(
      <GapSuggestionCard suggestion={makeSuggestion({ impact_score: 55 })} />,
    );
    const progressBars = container.querySelectorAll('[role="progressbar"]');
    const impactBar = Array.from(progressBars).find((bar) =>
      bar.getAttribute('aria-label')?.includes('Impact'),
    );
    expect(impactBar).toHaveClass('bg-yellow-500');
  });

  it('applies correct progress bar colors for low impact', () => {
    const { container } = render(
      <GapSuggestionCard suggestion={makeSuggestion({ impact_score: 25 })} />,
    );
    const progressBars = container.querySelectorAll('[role="progressbar"]');
    const impactBar = Array.from(progressBars).find((bar) =>
      bar.getAttribute('aria-label')?.includes('Impact'),
    );
    expect(impactBar).toHaveClass('bg-red-500');
  });

  it('sets correct aria attributes for impact progress bar', () => {
    const { container } = render(
      <GapSuggestionCard suggestion={makeSuggestion({ impact_score: 75.5 })} />,
    );
    const progressBars = container.querySelectorAll('[role="progressbar"]');
    const impactBar = Array.from(progressBars).find((bar) =>
      bar.getAttribute('aria-label')?.includes('Impact'),
    );

    expect(impactBar).toHaveAttribute('aria-valuenow', '75.5');
    expect(impactBar).toHaveAttribute('aria-valuemin', '0');
    expect(impactBar).toHaveAttribute('aria-valuemax', '100');
    expect(impactBar).toHaveAttribute('aria-label', 'Impact: 75.5');
  });

  it('sets correct aria attributes for effort progress bar', () => {
    const { container } = render(
      <GapSuggestionCard suggestion={makeSuggestion({ effort_score: 0.3 })} />,
    );
    const progressBars = container.querySelectorAll('[role="progressbar"]');
    const effortBar = Array.from(progressBars).find((bar) =>
      bar.getAttribute('aria-label')?.includes('Effort'),
    );

    expect(effortBar).toHaveAttribute('aria-valuenow', '30');
    expect(effortBar).toHaveAttribute('aria-valuemin', '0');
    expect(effortBar).toHaveAttribute('aria-valuemax', '100');
    expect(effortBar).toHaveAttribute('aria-label', 'Effort: 30');
  });
});
