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

vi.mock('@/Components/Shared/MetricDelta', () => ({
  default: ({ value, format }: { value: number; format: string }) => (
    <span data-testid="metric-delta" data-value={value} data-format={format}>
      {value}%
    </span>
  ),
}));

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Link: ({ href, children, ...props }: { href: string; children: React.ReactNode }) => (
      <a href={href} {...props}>
        {children}
      </a>
    ),
  };
});

import UnifiedCard from '@/Components/OpportunityMap/UnifiedCard';

function makeOpportunity(overrides: Record<string, unknown> = {}) {
  return {
    opportunity_type: 'recommendation' as const,
    opportunity_id: 1,
    page_url: '/test-page',
    demand: {
      clicks_before: 1200,
      clicks_after: 800,
      delta_percent: -33.3,
    },
    issue: 'Declining traffic on this page',
    action: 'content_rewrite',
    confidence: 85,
    impact_score: 75,
    reasoning: 'This page has declining traffic and needs fresh content',
    evidence: { test: 'data' },
    status: 'open',
    lifecycle_status: 'pending',
    ...overrides,
  };
}

beforeEach(() => {
  const mockRoute = vi.fn((name: string, params?: Record<string, unknown>): string => {
    const baseUrl = 'http://localhost:8000';
    // Return a valid route based on the route name
    if (name === 'content-briefs.create') {
      return `${baseUrl}/sites/${params?.site}/content-briefs/create`;
    }
    if (name === 'recommendations.show') {
      return `${baseUrl}/sites/${params?.site}/recommendations/${params?.recommendation}`;
    }
    if (name === 'topic-clusters.show') {
      return `${baseUrl}/sites/${params?.site}/content-intelligence/topic-clusters/${params?.cluster}`;
    }
    return `${baseUrl}/mock-route`;
  });
  vi.stubGlobal('route', mockRoute);
});

describe('UnifiedCard', () => {
  it('renders opportunity type badge', () => {
    render(<UnifiedCard opportunity={makeOpportunity()} siteId={1} />);

    expect(screen.getByText('Recommendation')).toBeInTheDocument();
  });

  it('renders page URL', () => {
    render(<UnifiedCard opportunity={makeOpportunity({ page_url: '/example-page' })} siteId={1} />);

    expect(screen.getByText('/example-page')).toBeInTheDocument();
  });

  it('renders impact and confidence scores', () => {
    render(
      <UnifiedCard
        opportunity={makeOpportunity({ impact_score: 82, confidence: 91 })}
        siteId={1}
      />,
    );

    expect(screen.getByText('82')).toBeInTheDocument();
    expect(screen.getByText('91')).toBeInTheDocument();
    expect(screen.getByText('Impact')).toBeInTheDocument();
    expect(screen.getByText('Confidence')).toBeInTheDocument();
  });

  it('renders demand section with clicks data for recommendations', () => {
    render(<UnifiedCard opportunity={makeOpportunity()} siteId={1} />);

    expect(screen.getByText('Demand')).toBeInTheDocument();
    expect(screen.getByText('Clicks')).toBeInTheDocument();
    expect(screen.getByText((1200).toLocaleString())).toBeInTheDocument();
    expect(screen.getByText((800).toLocaleString())).toBeInTheDocument();
  });

  it('renders issue section', () => {
    render(
      <UnifiedCard
        opportunity={makeOpportunity({ issue: 'Page needs optimization' })}
        siteId={1}
      />,
    );

    expect(screen.getByText('Issue')).toBeInTheDocument();
    expect(screen.getByText('Page needs optimization')).toBeInTheDocument();
  });

  it('renders action section', () => {
    render(
      <UnifiedCard opportunity={makeOpportunity({ action: 'meta_tag_optimization' })} siteId={1} />,
    );

    expect(screen.getByText('Action')).toBeInTheDocument();
    expect(screen.getByText('meta tag optimization')).toBeInTheDocument();
  });

  it('shows details when toggle is clicked', async () => {
    const user = userEvent.setup();
    render(
      <UnifiedCard
        opportunity={makeOpportunity({ reasoning: 'Test reasoning goes here' })}
        siteId={1}
      />,
    );

    // Check button aria-expanded is false initially
    const toggleButton = screen.getByRole('button', { name: /view details/i });
    expect(toggleButton).toHaveAttribute('aria-expanded', 'false');

    // Click to expand
    await user.click(toggleButton);

    // Button aria-expanded should now be true
    expect(toggleButton).toHaveAttribute('aria-expanded', 'true');

    // Details content should be in the document
    expect(screen.getByText('Reasoning')).toBeInTheDocument();
    expect(screen.getByText('Test reasoning goes here')).toBeInTheDocument();
  });

  it('renders freshness opportunity with days declining', () => {
    render(
      <UnifiedCard
        opportunity={makeOpportunity({
          opportunity_type: 'freshness',
          demand: {
            clicks_before: 500,
            clicks_after: 200,
            delta_percent: -60,
            days_declining: 14,
          },
        })}
        siteId={1}
      />,
    );

    expect(screen.getByText('Freshness')).toBeInTheDocument();
    expect(screen.getByText('Declining for 14 days')).toBeInTheDocument();
  });

  it('renders cannibalization opportunity with competing pages', () => {
    render(
      <UnifiedCard
        opportunity={makeOpportunity({
          opportunity_type: 'cannibalization',
          demand: {
            query_cluster: 'test keyword',
            competing_pages: 5,
            total_clicks: 1500,
            volatility: 0.75,
          },
        })}
        siteId={1}
      />,
    );

    expect(screen.getByText('Cannibalization')).toBeInTheDocument();
    expect(screen.getByText('test keyword')).toBeInTheDocument();
    expect(screen.getByText('5 competing pages')).toBeInTheDocument();
    expect(screen.getByText((1500).toLocaleString())).toBeInTheDocument();
    expect(screen.getByText('0.75')).toBeInTheDocument();
  });

  it('renders topic gap opportunity with cluster data', () => {
    render(
      <UnifiedCard
        opportunity={makeOpportunity({
          opportunity_type: 'topic_gap',
          demand: {
            cluster_name: 'SEO Tools',
            cluster_demand: 5000,
            coverage_percentage: 67.5,
            missing_entity: 'keyword research',
          },
        })}
        siteId={1}
      />,
    );

    expect(screen.getByText('Topic Gap')).toBeInTheDocument();
    expect(screen.getByText('SEO Tools')).toBeInTheDocument();
    expect(screen.getByText((5000).toLocaleString())).toBeInTheDocument();
    expect(screen.getByText('67.5%')).toBeInTheDocument();
    expect(screen.getByText('keyword research')).toBeInTheDocument();
  });

  it('handles null demand gracefully', () => {
    render(<UnifiedCard opportunity={makeOpportunity({ demand: null })} siteId={1} />);

    expect(screen.getByText('Demand')).toBeInTheDocument();
    expect(screen.getByText('No demand data')).toBeInTheDocument();
  });

  it('renders checkbox when onToggleSelection is provided', () => {
    const onToggleSelection = vi.fn();
    render(
      <UnifiedCard
        opportunity={makeOpportunity()}
        siteId={1}
        selected={false}
        onToggleSelection={onToggleSelection}
      />,
    );

    const checkbox = screen.getByRole('checkbox');
    expect(checkbox).toBeInTheDocument();
    expect(checkbox).not.toBeChecked();
  });

  it('calls onToggleSelection when checkbox is clicked', async () => {
    const user = userEvent.setup();
    const onToggleSelection = vi.fn();
    render(
      <UnifiedCard
        opportunity={makeOpportunity()}
        siteId={1}
        selected={false}
        onToggleSelection={onToggleSelection}
      />,
    );

    const checkbox = screen.getByRole('checkbox');
    await user.click(checkbox);

    expect(onToggleSelection).toHaveBeenCalledTimes(1);
  });

  it('does not render checkbox when onToggleSelection is not provided', () => {
    render(<UnifiedCard opportunity={makeOpportunity()} siteId={1} />);

    expect(screen.queryByRole('checkbox')).not.toBeInTheDocument();
  });

  it('renders evidence when available', async () => {
    const user = userEvent.setup();
    render(
      <UnifiedCard
        opportunity={makeOpportunity({
          evidence: { key1: 'value1', key2: 'value2' },
        })}
        siteId={1}
      />,
    );

    await user.click(screen.getByText('View details'));

    expect(screen.getByText('Evidence')).toBeInTheDocument();
    expect(screen.getByText(/"key1": "value1"/)).toBeInTheDocument();
  });

  it('renders status when available', async () => {
    const user = userEvent.setup();
    render(<UnifiedCard opportunity={makeOpportunity({ status: 'in_progress' })} siteId={1} />);

    await user.click(screen.getByText('View details'));

    expect(screen.getByText('Status:')).toBeInTheDocument();
    expect(screen.getByText('in progress')).toBeInTheDocument();
  });

  it('renders MetricDelta with correct delta_percent', () => {
    render(<UnifiedCard opportunity={makeOpportunity()} siteId={1} />);

    const metricDelta = screen.getByTestId('metric-delta');
    expect(metricDelta).toHaveAttribute('data-value', '-33.3');
    expect(metricDelta).toHaveAttribute('data-format', 'percent');
  });
});
