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

describe('MarkdownMessage', () => {
  it('renders bold text correctly', () => {
    const { container } = render(<MarkdownMessage content="Hello **bold**" />);
    const strong = container.querySelector('strong');
    expect(strong).toBeInTheDocument();
    expect(strong?.textContent).toBe('bold');
  });

  it('renders links correctly', () => {
    const { container } = render(<MarkdownMessage content="Visit [Google](https://google.com)" />);
    const link = container.querySelector('a');
    expect(link).toBeInTheDocument();
    expect(link).toHaveAttribute('href', 'https://google.com');
    expect(link?.textContent).toBe('Google');
  });

  it('renders h1 headers correctly', () => {
    const { container } = render(<MarkdownMessage content="# Header 1" />);
    console.log('H1 HTML Output:', container.innerHTML);
    expect(container.querySelector('h1')).toBeInTheDocument();
  });

  it('renders h2 headers correctly', () => {
    const { container } = render(<MarkdownMessage content="## Header 2" />);
    console.log('H2 HTML Output:', container.innerHTML);
    expect(container.querySelector('h2')).toBeInTheDocument();
  });

  it('renders h4 headers correctly', () => {
    const { container } = render(<MarkdownMessage content="#### Header 4" />);
    expect(container.querySelector('h4')).toBeInTheDocument();
  });

  it('renders a fenced code block via CodeBlock, without leaking stray backticks', () => {
    const { container } = render(
      <MarkdownMessage content={'```python\ndef greet():\n    return "hi"\n```'} />
    );
    expect(container.textContent).not.toContain('`');
    // react-syntax-highlighter splits the string across many spans, so match
    // on textContent rather than a single node's text.
    expect(container.textContent).toContain('def greet():');
  });

  it('does not mangle special markdown characters inside a fenced code block', () => {
    const { container } = render(<MarkdownMessage content={'```python\nx = a**2 + _b_\n```'} />);
    expect(container.querySelector('strong')).not.toBeInTheDocument();
    expect(container.querySelector('em')).not.toBeInTheDocument();
    expect(container.textContent).toContain('x = a**2 + _b_');
  });

  it('renders text before and after a fenced code block as separate segments', () => {
    const { container } = render(
      <MarkdownMessage content={'Before\n\n```js\nconst x = 1;\n```\n\nAfter'} />
    );
    expect(container.textContent).toContain('Before');
    expect(container.textContent).toContain('const x = 1;');
    expect(container.textContent).toContain('After');
  });

  it('renders blockquotes correctly', () => {
    const { container } = render(<MarkdownMessage content="> A quoted line" />);
    const quote = container.querySelector('blockquote');
    expect(quote).toBeInTheDocument();
    expect(quote?.textContent).toBe('A quoted line');
  });

  it('renders multi-line blockquotes as a single element', () => {
    const { container } = render(<MarkdownMessage content="> Line one\n> Line two" />);
    const quotes = container.querySelectorAll('blockquote');
    expect(quotes).toHaveLength(1);
    expect(quotes[0].innerHTML).toContain('Line one');
    expect(quotes[0].innerHTML).toContain('Line two');
  });

  it('renders strikethrough correctly', () => {
    const { container } = render(<MarkdownMessage content="~~deleted~~" />);
    const del = container.querySelector('del');
    expect(del).toBeInTheDocument();
    expect(del?.textContent).toBe('deleted');
  });

  it('renders a GFM table correctly', () => {
    const { container } = render(
      <MarkdownMessage content={'| A | B |\n|---|---|\n| 1 | 2 |'} />
    );
    expect(container.querySelector('table')).toBeInTheDocument();
    expect(container.querySelectorAll('th')).toHaveLength(2);
    expect(container.querySelectorAll('td')).toHaveLength(2);
  });

  it('renders a "*"-marker bullet list correctly, not as literal asterisks', () => {
    const { container } = render(
      <MarkdownMessage content={'* Primeiro item\n* Segundo item\n* Terceiro item'} />
    );
    const items = container.querySelectorAll('ul > li');
    expect(items).toHaveLength(3);
    expect(items[0].textContent).toBe('Primeiro item');
    expect(container.textContent).not.toContain('*');
  });

  it('renders bold terms inside a "*"-marker bullet list without leaking the leading asterisk', () => {
    const { container } = render(
      <MarkdownMessage
        content={
          '* **Abrangência**: Cobre desde primitivas de UI até temas.\n* **Requisitos**: Node.js >= 18.'
        }
      />
    );
    const items = container.querySelectorAll('ul > li');
    expect(items).toHaveLength(2);
    expect(items[0].querySelector('strong')?.textContent).toBe('Abrangência');
    expect(items[0].textContent).toBe('Abrangência: Cobre desde primitivas de UI até temas.');
    expect(container.textContent).not.toMatch(/^\*|[^*]\*[^*]/);
  });

  it('does not let a bullet list\'s leading "*" pair up with real italics later in the item', () => {
    const { container } = render(
      <MarkdownMessage content={'* Item with *real italic* text inside it'} />
    );
    const items = container.querySelectorAll('ul > li');
    expect(items).toHaveLength(1);
    expect(items[0].querySelector('em')?.textContent).toBe('real italic');
    expect(items[0].textContent).toBe('Item with real italic text inside it');
  });
});
