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

import QualityScoreSidebar, { QualityMetrics } from './QualityScoreSidebar';

const mockMetrics: QualityMetrics = {
  flesch_kincaid_grade: 8.5,
  avg_sentence_length: 15.2,
  paragraph_count: 5,
  passive_voice_percentage: 8.5,
  word_count: 800,
  h1_count: 1,
  h2_count: 3,
  h3_count: 2,
  h4_count: 0,
  h5_count: 0,
  h6_count: 0,
  image_count: 2,
  internal_link_count: 5,
  external_link_count: 3,
};

describe('QualityScoreSidebar', () => {
  // ============================================
  // Rendering tests
  // ============================================

  describe('rendering', () => {
    it('should render sidebar with all sections', () => {
      render(<QualityScoreSidebar metrics={mockMetrics} />);

      expect(screen.getByText('Quality Metrics')).toBeInTheDocument();
      expect(screen.getByText('Live content analysis')).toBeInTheDocument();

      // Check section headers
      expect(screen.getByText('Readability')).toBeInTheDocument();
      expect(screen.getByText('Content Structure')).toBeInTheDocument();
      expect(screen.getByText('Links & Media')).toBeInTheDocument();
    });

    it('should render all readability metrics', () => {
      render(<QualityScoreSidebar metrics={mockMetrics} />);

      expect(screen.getByText('Reading Level')).toBeInTheDocument();
      expect(screen.getByText('Grade 8.5')).toBeInTheDocument();

      expect(screen.getByText('Avg. Sentence Length')).toBeInTheDocument();
      expect(screen.getByText('15.2')).toBeInTheDocument();

      expect(screen.getByText('Passive Voice')).toBeInTheDocument();
      expect(screen.getByText('8.5%')).toBeInTheDocument();
    });

    it('should render all content structure metrics', () => {
      render(<QualityScoreSidebar metrics={mockMetrics} />);

      expect(screen.getByText('Word Count')).toBeInTheDocument();
      expect(screen.getByText('800')).toBeInTheDocument();

      expect(screen.getByText('Paragraphs')).toBeInTheDocument();
      // Check for paragraph count in context
      const paragraphsSection = screen.getByText('Paragraphs').closest('.rounded-lg');
      expect(paragraphsSection).toHaveTextContent('5');

      expect(screen.getByText('Heading Structure')).toBeInTheDocument();
      expect(screen.getByText('H1: 1, H2: 3, H3: 2')).toBeInTheDocument();
    });

    it('should render all link and media metrics', () => {
      render(<QualityScoreSidebar metrics={mockMetrics} />);

      expect(screen.getByText('Internal Links')).toBeInTheDocument();
      expect(screen.getByText('External Links')).toBeInTheDocument();
      expect(screen.getByText('Total Links')).toBeInTheDocument();
      expect(screen.getByText('Images')).toBeInTheDocument();

      // Check values
      const linkElements = screen.getAllByText('5');
      expect(linkElements.length).toBeGreaterThan(0); // Internal links

      expect(screen.getByText('3')).toBeInTheDocument(); // External links
      expect(screen.getByText('8')).toBeInTheDocument(); // Total links (5+3)
      expect(screen.getByText('2')).toBeInTheDocument(); // Images
    });

    it('should render loading state', () => {
      render(<QualityScoreSidebar metrics={null} isLoading={true} />);

      expect(screen.getByText('Quality Metrics')).toBeInTheDocument();
      expect(screen.getByText('Analyzing...')).toBeInTheDocument();
    });

    it('should render empty state when no metrics provided', () => {
      render(<QualityScoreSidebar metrics={null} />);

      expect(screen.getByText('Quality Metrics')).toBeInTheDocument();
      expect(screen.getByText('Start typing to see quality metrics')).toBeInTheDocument();
    });

    it('should apply custom className', () => {
      const { container } = render(
        <QualityScoreSidebar metrics={mockMetrics} className="custom-sidebar-class" />,
      );

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

  // ============================================
  // Readability status tests
  // ============================================

  describe('readability status', () => {
    it('should show good status for elementary reading level', () => {
      const metrics = { ...mockMetrics, flesch_kincaid_grade: 6.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const gradeValue = screen.getByText('Grade 6.0');
      expect(gradeValue).toHaveClass('text-success');
    });

    it('should show warning status for high school reading level', () => {
      const metrics = { ...mockMetrics, flesch_kincaid_grade: 10.5 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const gradeValue = screen.getByText('Grade 10.5');
      expect(gradeValue).toHaveClass('text-warning');
    });

    it('should show error status for college reading level', () => {
      const metrics = { ...mockMetrics, flesch_kincaid_grade: 15.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const gradeValue = screen.getByText('Grade 15.0');
      expect(gradeValue).toHaveClass('text-destructive');
    });

    it('should show good status for short sentences', () => {
      const metrics = { ...mockMetrics, avg_sentence_length: 18.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const lengthValue = screen.getByText('18.0');
      expect(lengthValue).toHaveClass('text-success');
    });

    it('should show warning status for moderately long sentences', () => {
      const metrics = { ...mockMetrics, avg_sentence_length: 23.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const lengthValue = screen.getByText('23.0');
      expect(lengthValue).toHaveClass('text-warning');
    });

    it('should show error status for very long sentences', () => {
      const metrics = { ...mockMetrics, avg_sentence_length: 30.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const lengthValue = screen.getByText('30.0');
      expect(lengthValue).toHaveClass('text-destructive');
    });

    it('should show good status for low passive voice', () => {
      const metrics = { ...mockMetrics, passive_voice_percentage: 5.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const passiveValue = screen.getByText('5.0%');
      expect(passiveValue).toHaveClass('text-success');
    });

    it('should show warning status for moderate passive voice', () => {
      const metrics = { ...mockMetrics, passive_voice_percentage: 15.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const passiveValue = screen.getByText('15.0%');
      expect(passiveValue).toHaveClass('text-warning');
    });

    it('should show error status for high passive voice', () => {
      const metrics = { ...mockMetrics, passive_voice_percentage: 25.0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const passiveValue = screen.getByText('25.0%');
      expect(passiveValue).toHaveClass('text-destructive');
    });
  });

  // ============================================
  // Word count status tests
  // ============================================

  describe('word count status', () => {
    it('should show error status for very short content', () => {
      const metrics = { ...mockMetrics, word_count: 250 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const wordCountValue = screen.getByText('250');
      expect(wordCountValue).toHaveClass('text-destructive');
      expect(
        screen.getByText('Content is too short. Aim for at least 600 words for better SEO.'),
      ).toBeInTheDocument();
    });

    it('should show warning status for short content', () => {
      const metrics = { ...mockMetrics, word_count: 500 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const wordCountValue = screen.getByText('500');
      expect(wordCountValue).toHaveClass('text-warning');
    });

    it('should show good status for comprehensive content', () => {
      const metrics = { ...mockMetrics, word_count: 1600 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const wordCountValue = screen.getByText('1,600');
      expect(wordCountValue).toHaveClass('text-success');
      expect(
        screen.getByText('Comprehensive content length that provides value to readers'),
      ).toBeInTheDocument();
    });

    it('should show neutral status for moderate content length', () => {
      const metrics = { ...mockMetrics, word_count: 800 };
      render(<QualityScoreSidebar metrics={metrics} />);

      const wordCountValue = screen.getByText('800');
      expect(wordCountValue).toHaveClass('text-foreground');
    });
  });

  // ============================================
  // Heading structure tests
  // ============================================

  describe('heading structure', () => {
    it('should show error when no H1', () => {
      const metrics = { ...mockMetrics, h1_count: 0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(
        screen.getByText('Add an H1 heading as the main title of your content'),
      ).toBeInTheDocument();
    });

    it('should show error when multiple H1s', () => {
      const metrics = { ...mockMetrics, h1_count: 2 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(
        screen.getByText('Use only one H1 heading. Use H2-H6 for subheadings.'),
      ).toBeInTheDocument();
    });

    it('should show warning when few subheadings', () => {
      const metrics = { ...mockMetrics, h2_count: 1, h3_count: 0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(
        screen.getByText('Add more subheadings (H2-H3) to improve content structure'),
      ).toBeInTheDocument();
    });

    it('should show good status with proper heading structure', () => {
      const metrics = { ...mockMetrics, h1_count: 1, h2_count: 3, h3_count: 2 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(
        screen.getByText('Good heading structure helps readers scan your content'),
      ).toBeInTheDocument();
    });
  });

  // ============================================
  // Links status tests
  // ============================================

  describe('links', () => {
    it('should show warning when no internal links', () => {
      const metrics = { ...mockMetrics, internal_link_count: 0, external_link_count: 3 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(screen.getByText('Add internal links to related content')).toBeInTheDocument();
    });

    it('should show warning when no external links', () => {
      const metrics = { ...mockMetrics, internal_link_count: 5, external_link_count: 0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(screen.getByText('Consider citing external sources')).toBeInTheDocument();
    });

    it('should show error when no links at all', () => {
      const metrics = { ...mockMetrics, internal_link_count: 0, external_link_count: 0 };
      render(<QualityScoreSidebar metrics={metrics} />);

      // Find the Total Links card specifically
      const totalLinksSection = screen.getByText('Total Links').closest('.rounded-lg');
      expect(totalLinksSection).toBeInTheDocument();

      // Check that the value within this card has error styling
      const errorElement = totalLinksSection?.querySelector('.text-destructive');
      expect(errorElement).toBeInTheDocument();
    });

    it('should show good status with balanced links', () => {
      const metrics = { ...mockMetrics, internal_link_count: 5, external_link_count: 3 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(screen.getByText('Good balance of internal and external links')).toBeInTheDocument();
    });

    it('should suggest more internal links when external exceeds internal', () => {
      const metrics = { ...mockMetrics, internal_link_count: 2, external_link_count: 5 };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(
        screen.getByText('Consider adding more internal links to keep readers on your site'),
      ).toBeInTheDocument();
    });
  });

  // ============================================
  // Null value handling tests
  // ============================================

  describe('null value handling', () => {
    it('should handle null readability values', () => {
      const metrics: QualityMetrics = {
        ...mockMetrics,
        flesch_kincaid_grade: null,
        avg_sentence_length: null,
        passive_voice_percentage: null,
      };
      render(<QualityScoreSidebar metrics={metrics} />);

      // Should render N/A for null values
      const naElements = screen.getAllByText('N/A');
      expect(naElements.length).toBe(3); // 3 null readability metrics
    });

    it('should handle partial null values', () => {
      const metrics: QualityMetrics = {
        ...mockMetrics,
        flesch_kincaid_grade: null,
        avg_sentence_length: 15.2,
        passive_voice_percentage: 8.5,
      };
      render(<QualityScoreSidebar metrics={metrics} />);

      // Should render N/A for null value
      expect(screen.getByText('N/A')).toBeInTheDocument();
      // Should render actual values for non-null
      expect(screen.getByText('15.2')).toBeInTheDocument();
      expect(screen.getByText('8.5%')).toBeInTheDocument();
    });
  });

  // ============================================
  // Edge cases tests
  // ============================================

  describe('edge cases', () => {
    it('should handle zero values correctly', () => {
      const metrics: QualityMetrics = {
        flesch_kincaid_grade: 0,
        avg_sentence_length: 0,
        paragraph_count: 0,
        passive_voice_percentage: 0,
        word_count: 0,
        h1_count: 0,
        h2_count: 0,
        h3_count: 0,
        h4_count: 0,
        h5_count: 0,
        h6_count: 0,
        image_count: 0,
        internal_link_count: 0,
        external_link_count: 0,
      };
      render(<QualityScoreSidebar metrics={metrics} />);

      // Should render zeros without errors
      const zeroElements = screen.getAllByText('0');
      expect(zeroElements.length).toBeGreaterThan(0);
    });

    it('should handle very high values', () => {
      const metrics: QualityMetrics = {
        ...mockMetrics,
        word_count: 10000,
        internal_link_count: 100,
        external_link_count: 50,
      };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(screen.getByText('10,000')).toBeInTheDocument();
      expect(screen.getByText('100')).toBeInTheDocument();
      expect(screen.getByText('50')).toBeInTheDocument();
    });

    it('should handle all headings being H1', () => {
      const metrics: QualityMetrics = {
        ...mockMetrics,
        h1_count: 5,
        h2_count: 0,
        h3_count: 0,
        h4_count: 0,
        h5_count: 0,
        h6_count: 0,
      };
      render(<QualityScoreSidebar metrics={metrics} />);

      expect(
        screen.getByText('Use only one H1 heading. Use H2-H6 for subheadings.'),
      ).toBeInTheDocument();
    });
  });

  // ============================================
  // Integration tests
  // ============================================

  describe('integration', () => {
    it('should display all metrics together correctly', () => {
      render(<QualityScoreSidebar metrics={mockMetrics} />);

      // Verify all major sections are present and populated
      expect(screen.getByText('Quality Metrics')).toBeInTheDocument();
      expect(screen.getByText('Readability')).toBeInTheDocument();
      expect(screen.getByText('Content Structure')).toBeInTheDocument();
      expect(screen.getByText('Links & Media')).toBeInTheDocument();

      // Verify some key metrics
      expect(screen.getByText('Grade 8.5')).toBeInTheDocument();
      expect(screen.getByText('800')).toBeInTheDocument();
      expect(screen.getByText('8')).toBeInTheDocument(); // Total links
    });

    it('should render ScrollArea component', () => {
      const { container } = render(<QualityScoreSidebar metrics={mockMetrics} />);

      // ScrollArea should have overflow-auto class
      const scrollArea = container.querySelector('.overflow-auto');
      expect(scrollArea).toBeInTheDocument();
    });

    it('should organize metrics in proper sections', () => {
      const { container } = render(<QualityScoreSidebar metrics={mockMetrics} />);

      // Should have 3 main metric sections
      const sections = container.querySelectorAll('h3.text-muted-foreground');
      expect(sections.length).toBe(3);
    });
  });
});
