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

import EeatScorePanel from './EeatScorePanel';
import type { EeatPillarMetrics } from './QualityScoreSidebar';

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

describe('EeatScorePanel', () => {
  describe('rendering', () => {
    it('should render with all pillar scores', () => {
      render(
        <EeatScorePanel
          overallScore={65}
          experience={mockPillar(80, 5)}
          expertise={mockPillar(60, 3)}
          authoritativeness={mockPillar(50, 2)}
          trustworthiness={mockPillar(70, 4)}
        />,
      );

      expect(screen.getByText('EEAT Signals')).toBeInTheDocument();
      expect(screen.getByText('Overall EEAT')).toBeInTheDocument();
      expect(screen.getByText('Experience')).toBeInTheDocument();
      expect(screen.getByText('Expertise')).toBeInTheDocument();
      expect(screen.getByText('Authoritativeness')).toBeInTheDocument();
      expect(screen.getByText('Trustworthiness')).toBeInTheDocument();
    });

    it('should render loading state', () => {
      render(
        <EeatScorePanel
          overallScore={null}
          experience={null}
          expertise={null}
          authoritativeness={null}
          trustworthiness={null}
          isLoading={true}
        />,
      );

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

    it('should render empty state when no score', () => {
      render(
        <EeatScorePanel
          overallScore={null}
          experience={null}
          expertise={null}
          authoritativeness={null}
          trustworthiness={null}
        />,
      );

      expect(screen.getByText('EEAT Signals')).toBeInTheDocument();
      expect(
        screen.getByText(/As you write, we'll score your content for Experience/),
      ).toBeInTheDocument();
    });

    it('should apply custom className', () => {
      const { container } = render(
        <EeatScorePanel
          overallScore={50}
          experience={mockPillar(50, 2)}
          expertise={mockPillar(50, 2)}
          authoritativeness={mockPillar(50, 2)}
          trustworthiness={mockPillar(50, 2)}
          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(
        <EeatScorePanel
          overallScore={85}
          experience={mockPillar(90, 5)}
          expertise={mockPillar(80, 4)}
          authoritativeness={mockPillar(85, 3)}
          trustworthiness={mockPillar(85, 4)}
        />,
      );

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

    it('should show Moderate label for medium scores', () => {
      render(
        <EeatScorePanel
          overallScore={55}
          experience={mockPillar(60, 3)}
          expertise={mockPillar(50, 2)}
          authoritativeness={mockPillar(55, 2)}
          trustworthiness={mockPillar(55, 3)}
        />,
      );

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

    it('should show Weak label for low scores', () => {
      render(
        <EeatScorePanel
          overallScore={20}
          experience={mockPillar(10, 1)}
          expertise={mockPillar(20, 1)}
          authoritativeness={mockPillar(25, 1)}
          trustworthiness={mockPillar(25, 1)}
        />,
      );

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

  describe('pillar scores', () => {
    it('should display signal counts in descriptions', () => {
      render(
        <EeatScorePanel
          overallScore={50}
          experience={mockPillar(50, 3)}
          expertise={mockPillar(50, 2)}
          authoritativeness={mockPillar(50, 4)}
          trustworthiness={mockPillar(50, 1)}
        />,
      );

      expect(screen.getByText('3 first-person experience markers')).toBeInTheDocument();
      expect(screen.getByText('2 data/research citations')).toBeInTheDocument();
      expect(screen.getByText('4 authority signals')).toBeInTheDocument();
      expect(screen.getByText('1 trust indicators')).toBeInTheDocument();
    });

    it('should show good status color for high overall score', () => {
      render(
        <EeatScorePanel
          overallScore={82}
          experience={mockPillar(90, 5)}
          expertise={mockPillar(75, 4)}
          authoritativeness={mockPillar(88, 3)}
          trustworthiness={mockPillar(85, 4)}
        />,
      );

      // Find the overall score value (unique) and check it has green class
      const overallValue = screen.getByText('82');
      expect(overallValue).toHaveClass('text-success');
    });

    it('should show error status color for low overall score', () => {
      render(
        <EeatScorePanel
          overallScore={12}
          experience={mockPillar(8, 1)}
          expertise={mockPillar(5, 0)}
          authoritativeness={mockPillar(18, 1)}
          trustworthiness={mockPillar(17, 1)}
        />,
      );

      // Find the overall score value (unique) and check it has red class
      const overallValue = screen.getByText('12');
      expect(overallValue).toHaveClass('text-destructive');
    });
  });

  describe('suggestions', () => {
    it('should show improvement suggestion for low overall score', () => {
      render(
        <EeatScorePanel
          overallScore={20}
          experience={mockPillar(10, 0)}
          expertise={mockPillar(20, 1)}
          authoritativeness={mockPillar(25, 1)}
          trustworthiness={mockPillar(25, 1)}
        />,
      );

      expect(
        screen.getByText('Content lacks EEAT signals. Strengthen to improve rankings.'),
      ).toBeInTheDocument();
    });

    it('should show moderate suggestion for medium overall score', () => {
      render(
        <EeatScorePanel
          overallScore={55}
          experience={mockPillar(60, 3)}
          expertise={mockPillar(50, 2)}
          authoritativeness={mockPillar(55, 2)}
          trustworthiness={mockPillar(55, 3)}
        />,
      );

      expect(
        screen.getByText('EEAT signals present. Add more to boost credibility.'),
      ).toBeInTheDocument();
    });

    it('should show positive message for high overall score', () => {
      render(
        <EeatScorePanel
          overallScore={85}
          experience={mockPillar(90, 5)}
          expertise={mockPillar(80, 4)}
          authoritativeness={mockPillar(85, 3)}
          trustworthiness={mockPillar(85, 4)}
        />,
      );

      expect(screen.getByText('Strong EEAT signals support search rankings.')).toBeInTheDocument();
    });
  });

  describe('null/undefined handling', () => {
    it('should handle undefined pillar metrics', () => {
      render(
        <EeatScorePanel
          overallScore={50}
          experience={undefined}
          expertise={undefined}
          authoritativeness={undefined}
          trustworthiness={undefined}
        />,
      );

      // Should still render overall score
      expect(screen.getByText('50')).toBeInTheDocument();

      // Pillar scores should show N/A
      const naElements = screen.getAllByText('N/A');
      expect(naElements.length).toBe(4);
    });

    it('should handle zero overall score', () => {
      render(
        <EeatScorePanel
          overallScore={0}
          experience={mockPillar(0, 0)}
          expertise={mockPillar(0, 0)}
          authoritativeness={mockPillar(0, 0)}
          trustworthiness={mockPillar(0, 0)}
        />,
      );

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