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

import GeoScorePanel from './GeoScorePanel';
import type { GeoPillarMetrics } from './QualityScoreSidebar';

const mockPillar = (
  score: number,
  signalCount: number,
  suggestions: string[] = [],
): GeoPillarMetrics => ({
  score,
  signal_count: signalCount,
  detected: Array.from({ length: signalCount }, (_, i) => `signal-${i}`),
  suggestions,
});

describe('GeoScorePanel', () => {
  describe('rendering', () => {
    it('should render with all pillar scores', () => {
      render(
        <GeoScorePanel
          overallScore={65}
          directAnswers={mockPillar(80, 5)}
          faqStructure={mockPillar(60, 3)}
          structuredData={mockPillar(50, 2)}
          conceptClarity={mockPillar(70, 4)}
          citationReadiness={mockPillar(55, 3)}
          schemaOpportunities={mockPillar(40, 1)}
        />,
      );

      expect(screen.getByText('GEO Signals')).toBeInTheDocument();
      expect(screen.getByText('Overall GEO')).toBeInTheDocument();
      expect(screen.getByText('Direct Answers')).toBeInTheDocument();
      expect(screen.getByText('FAQ Structure')).toBeInTheDocument();
      expect(screen.getByText('Structured Data')).toBeInTheDocument();
      expect(screen.getByText('Concept Clarity')).toBeInTheDocument();
      expect(screen.getByText('Citation Readiness')).toBeInTheDocument();
      expect(screen.getByText('Schema Markup')).toBeInTheDocument();
    });

    it('should render skeleton loading state', () => {
      render(
        <GeoScorePanel
          overallScore={null}
          directAnswers={null}
          faqStructure={null}
          structuredData={null}
          conceptClarity={null}
          citationReadiness={null}
          schemaOpportunities={null}
          isLoading={true}
        />,
      );

      expect(screen.getByText('GEO Signals')).toBeInTheDocument();
      expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
    });

    it('should render empty state when no score', () => {
      render(
        <GeoScorePanel
          overallScore={null}
          directAnswers={null}
          faqStructure={null}
          structuredData={null}
          conceptClarity={null}
          citationReadiness={null}
          schemaOpportunities={null}
        />,
      );

      expect(screen.getByText('GEO Signals')).toBeInTheDocument();
      expect(screen.getByText('Start typing to see GEO analysis')).toBeInTheDocument();
    });

    it('should apply custom className', () => {
      const { container } = render(
        <GeoScorePanel
          overallScore={50}
          directAnswers={mockPillar(50, 2)}
          faqStructure={mockPillar(50, 2)}
          structuredData={mockPillar(50, 2)}
          conceptClarity={mockPillar(50, 2)}
          citationReadiness={mockPillar(50, 2)}
          schemaOpportunities={mockPillar(50, 1)}
          className="my-custom-class"
        />,
      );

      const panel = container.querySelector('.my-custom-class');
      expect(panel).toBeInTheDocument();
    });
  });

  describe('overall score status', () => {
    it('should show Strong label for high scores', () => {
      render(
        <GeoScorePanel
          overallScore={85}
          directAnswers={mockPillar(90, 5)}
          faqStructure={mockPillar(80, 4)}
          structuredData={mockPillar(85, 3)}
          conceptClarity={mockPillar(80, 4)}
          citationReadiness={mockPillar(85, 3)}
          schemaOpportunities={mockPillar(90, 2)}
        />,
      );

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

    it('should show Moderate label for medium scores', () => {
      render(
        <GeoScorePanel
          overallScore={55}
          directAnswers={mockPillar(60, 3)}
          faqStructure={mockPillar(50, 2)}
          structuredData={mockPillar(55, 2)}
          conceptClarity={mockPillar(55, 3)}
          citationReadiness={mockPillar(50, 2)}
          schemaOpportunities={mockPillar(40, 1)}
        />,
      );

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

    it('should show Weak label for low scores', () => {
      render(
        <GeoScorePanel
          overallScore={20}
          directAnswers={mockPillar(10, 1)}
          faqStructure={mockPillar(20, 1)}
          structuredData={mockPillar(25, 1)}
          conceptClarity={mockPillar(15, 1)}
          citationReadiness={mockPillar(20, 1)}
          schemaOpportunities={mockPillar(0, 0)}
        />,
      );

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

  describe('pillar scores', () => {
    it('should display signal counts in descriptions', () => {
      render(
        <GeoScorePanel
          overallScore={50}
          directAnswers={mockPillar(50, 3)}
          faqStructure={mockPillar(50, 2)}
          structuredData={mockPillar(50, 4)}
          conceptClarity={mockPillar(50, 1)}
          citationReadiness={mockPillar(50, 5)}
          schemaOpportunities={mockPillar(50, 2)}
        />,
      );

      expect(screen.getByText('3 question headings & definitions')).toBeInTheDocument();
      expect(screen.getByText('2 Q&A patterns')).toBeInTheDocument();
      expect(screen.getByText('4 tables, lists & structures')).toBeInTheDocument();
      expect(screen.getByText('1 clarity signals')).toBeInTheDocument();
      expect(screen.getByText('5 attributions & references')).toBeInTheDocument();
      expect(screen.getByText('2 JSON-LD schema blocks')).toBeInTheDocument();
    });

    it('should show good status color for high overall score', () => {
      render(
        <GeoScorePanel
          overallScore={82}
          directAnswers={mockPillar(90, 5)}
          faqStructure={mockPillar(75, 4)}
          structuredData={mockPillar(88, 3)}
          conceptClarity={mockPillar(85, 4)}
          citationReadiness={mockPillar(80, 3)}
          schemaOpportunities={mockPillar(70, 2)}
        />,
      );

      const overallValue = screen.getByText('82');
      expect(overallValue).toHaveClass('text-success');
    });

    it('should show error status color for low overall score', () => {
      render(
        <GeoScorePanel
          overallScore={12}
          directAnswers={mockPillar(8, 1)}
          faqStructure={mockPillar(5, 0)}
          structuredData={mockPillar(18, 1)}
          conceptClarity={mockPillar(10, 0)}
          citationReadiness={mockPillar(15, 1)}
          schemaOpportunities={mockPillar(0, 0)}
        />,
      );

      const overallValue = screen.getByText('12');
      expect(overallValue).toHaveClass('text-destructive');
    });
  });

  describe('suggestions', () => {
    it('should show improvement suggestion for low overall score', () => {
      render(
        <GeoScorePanel
          overallScore={20}
          directAnswers={mockPillar(10, 0)}
          faqStructure={mockPillar(20, 1)}
          structuredData={mockPillar(25, 1)}
          conceptClarity={mockPillar(15, 0)}
          citationReadiness={mockPillar(20, 1)}
          schemaOpportunities={mockPillar(0, 0)}
        />,
      );

      expect(
        screen.getByText('Content lacks GEO signals. Optimize for AI search visibility.'),
      ).toBeInTheDocument();
    });

    it('should show moderate suggestion for medium overall score', () => {
      render(
        <GeoScorePanel
          overallScore={55}
          directAnswers={mockPillar(60, 3)}
          faqStructure={mockPillar(50, 2)}
          structuredData={mockPillar(55, 2)}
          conceptClarity={mockPillar(55, 3)}
          citationReadiness={mockPillar(50, 2)}
          schemaOpportunities={mockPillar(40, 1)}
        />,
      );

      expect(
        screen.getByText('GEO signals present. Strengthen for better AI citation.'),
      ).toBeInTheDocument();
    });

    it('should show positive message for high overall score', () => {
      render(
        <GeoScorePanel
          overallScore={85}
          directAnswers={mockPillar(90, 5)}
          faqStructure={mockPillar(80, 4)}
          structuredData={mockPillar(85, 3)}
          conceptClarity={mockPillar(80, 4)}
          citationReadiness={mockPillar(85, 3)}
          schemaOpportunities={mockPillar(90, 2)}
        />,
      );

      expect(
        screen.getByText('Strong GEO signals support AI search visibility.'),
      ).toBeInTheDocument();
    });
  });

  describe('null/undefined handling', () => {
    it('should handle undefined pillar metrics', () => {
      render(
        <GeoScorePanel
          overallScore={50}
          directAnswers={undefined}
          faqStructure={undefined}
          structuredData={undefined}
          conceptClarity={undefined}
          citationReadiness={undefined}
          schemaOpportunities={undefined}
        />,
      );

      expect(screen.getByText('50')).toBeInTheDocument();

      const naElements = screen.getAllByText('N/A');
      expect(naElements.length).toBe(6);
    });

    it('should handle zero overall score', () => {
      render(
        <GeoScorePanel
          overallScore={0}
          directAnswers={mockPillar(0, 0)}
          faqStructure={mockPillar(0, 0)}
          structuredData={mockPillar(0, 0)}
          conceptClarity={mockPillar(0, 0)}
          citationReadiness={mockPillar(0, 0)}
          schemaOpportunities={mockPillar(0, 0)}
        />,
      );

      const zeroElements = screen.getAllByText('0');
      expect(zeroElements.length).toBeGreaterThan(0);
    });
  });
});
