"""
Behavioral tests for citation_formatter module.

Tests CitationFormatter, QuartoExporter, RISExporter, and LaTeXExporter classes.
"""


class TestCitationModeEnum:
    """Tests for CitationMode enum."""

    def test_number_hyperlinks_mode_exists(self):
        """NUMBER_HYPERLINKS mode exists."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationMode,
        )

        assert hasattr(CitationMode, "NUMBER_HYPERLINKS")

    def test_domain_hyperlinks_mode_exists(self):
        """DOMAIN_HYPERLINKS mode exists."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationMode,
        )

        assert hasattr(CitationMode, "DOMAIN_HYPERLINKS")

    def test_domain_id_hyperlinks_mode_exists(self):
        """DOMAIN_ID_HYPERLINKS mode exists."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationMode,
        )

        assert hasattr(CitationMode, "DOMAIN_ID_HYPERLINKS")

    def test_domain_id_always_hyperlinks_mode_exists(self):
        """DOMAIN_ID_ALWAYS_HYPERLINKS mode exists."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationMode,
        )

        assert hasattr(CitationMode, "DOMAIN_ID_ALWAYS_HYPERLINKS")

    def test_no_hyperlinks_mode_exists(self):
        """NO_HYPERLINKS mode exists."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationMode,
        )

        assert hasattr(CitationMode, "NO_HYPERLINKS")

    def test_mode_values_are_strings(self):
        """All mode values are strings."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationMode,
        )

        for mode in CitationMode:
            assert isinstance(mode.value, str)


class TestCitationFormatterInit:
    """Tests for CitationFormatter initialization."""

    def test_default_mode_is_number_hyperlinks(self):
        """Default mode is NUMBER_HYPERLINKS."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
            CitationMode,
        )

        formatter = CitationFormatter()
        assert formatter.mode == CitationMode.NUMBER_HYPERLINKS

    def test_accepts_custom_mode(self):
        """Accepts custom citation mode."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
            CitationMode,
        )

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        assert formatter.mode == CitationMode.DOMAIN_HYPERLINKS

    def test_has_citation_pattern(self):
        """Has compiled citation pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        assert formatter.citation_pattern is not None

    def test_has_comma_citation_pattern(self):
        """Has compiled comma citation pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        assert formatter.comma_citation_pattern is not None

    def test_has_source_word_pattern(self):
        """Has compiled source word pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        assert formatter.source_word_pattern is not None


class TestCitationFormatterExtractDomain:
    """Tests for _extract_domain method."""

    def test_extracts_simple_domain(self):
        """Extracts simple domain from URL."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._extract_domain("https://example.com/page")
        assert result == "example.com"

    def test_removes_www_prefix(self):
        """Removes www. prefix from domain."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._extract_domain("https://www.example.com/page")
        assert result == "example.com"

    def test_recognizes_known_domains(self):
        """Recognizes and preserves known domains."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        known_urls = [
            ("https://arxiv.org/abs/1234", "arxiv.org"),
            ("https://github.com/user/repo", "github.com"),
            ("https://reddit.com/r/test", "reddit.com"),
            ("https://youtube.com/watch", "youtube.com"),
            ("https://pypi.org/project/test", "pypi.org"),
            ("https://milvus.io/docs", "milvus.io"),
            ("https://medium.com/article", "medium.com"),
        ]
        for url, expected in known_urls:
            result = formatter._extract_domain(url)
            assert result == expected, f"Failed for {url}"

    def test_handles_subdomain(self):
        """Handles subdomain in URL."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._extract_domain("https://docs.python.org/page")
        assert result == "python.org"

    def test_handles_invalid_url(self):
        """Returns 'source' for invalid URL."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._extract_domain("not-a-valid-url")
        # Should return something sensible, not crash
        assert isinstance(result, str)

    def test_handles_empty_url(self):
        """Handles empty URL string."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._extract_domain("")
        assert isinstance(result, str)


class TestCitationFormatterFindSourcesSection:
    """Tests for _find_sources_section method."""

    def test_finds_sources_header(self):
        """Finds ## Sources header."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n## Sources\n\n[1] Source one"
        result = formatter._find_sources_section(content)
        assert result != -1
        assert content[result:].startswith("## Sources")

    def test_finds_references_header(self):
        """Finds ## References header."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n## References\n\n[1] Ref one"
        result = formatter._find_sources_section(content)
        assert result != -1

    def test_finds_bibliography_header(self):
        """Finds ## Bibliography header."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n## Bibliography\n\n[1] Bib one"
        result = formatter._find_sources_section(content)
        assert result != -1

    def test_finds_citations_header(self):
        """Finds ## Citations header."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n## Citations\n\n[1] Citation one"
        result = formatter._find_sources_section(content)
        assert result != -1

    def test_case_insensitive(self):
        """Finds sources header case-insensitively."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n## SOURCES\n\n[1] Source one"
        result = formatter._find_sources_section(content)
        assert result != -1

    def test_returns_minus_one_when_not_found(self):
        """Returns -1 when no sources section found."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content without sources section."
        result = formatter._find_sources_section(content)
        assert result == -1

    def test_finds_single_hash_header(self):
        """Finds # Sources header."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n# Sources\n\n[1] Source one"
        result = formatter._find_sources_section(content)
        assert result != -1

    def test_finds_triple_hash_header(self):
        """Finds ### Sources header."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Some content\n\n### Sources\n\n[1] Source one"
        result = formatter._find_sources_section(content)
        assert result != -1


class TestCitationFormatterParseSources:
    """Tests for _parse_sources method."""

    def test_parses_single_source(self):
        """Parses a single source entry."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        sources_content = "[1] Test Source Title\n   URL: https://example.com"
        result = formatter._parse_sources(sources_content)
        assert "1" in result
        assert result["1"][0] == "Test Source Title"
        assert result["1"][1] == "https://example.com"

    def test_parses_multiple_sources(self):
        """Parses multiple source entries."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        sources_content = """[1] First Source
   URL: https://first.com
[2] Second Source
   URL: https://second.com"""
        result = formatter._parse_sources(sources_content)
        assert "1" in result
        assert "2" in result

    def test_parses_source_without_url(self):
        """Parses source without URL."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        sources_content = "[1] Source Without URL"
        result = formatter._parse_sources(sources_content)
        assert "1" in result
        assert result["1"][1] == ""  # Empty URL

    def test_parses_comma_separated_citation_numbers(self):
        """Parses comma-separated citation numbers like [36, 3]."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        sources_content = (
            "[36, 3] Shared Source Title\n   URL: https://shared.com"
        )
        result = formatter._parse_sources(sources_content)
        assert "36" in result
        assert "3" in result
        assert result["36"][0] == "Shared Source Title"
        assert result["3"][0] == "Shared Source Title"

    def test_returns_empty_dict_for_empty_content(self):
        """Returns empty dict for empty content."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._parse_sources("")
        assert result == {}


class TestCitationFormatterFormatDocument:
    """Tests for format_document method."""

    def test_returns_unchanged_for_no_hyperlinks_mode(self):
        """Returns unchanged content in NO_HYPERLINKS mode."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
            CitationMode,
        )

        formatter = CitationFormatter(mode=CitationMode.NO_HYPERLINKS)
        content = "Text with [1] citation.\n\n## Sources\n\n[1] Source\n   URL: https://test.com"
        result = formatter.format_document(content)
        assert result == content

    def test_returns_unchanged_when_no_sources_section(self):
        """Returns unchanged when no sources section found."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] citation but no sources section."
        result = formatter.format_document(content)
        assert result == content

    def test_formats_number_hyperlinks(self):
        """Formats citations with number hyperlinks."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
            CitationMode,
        )

        formatter = CitationFormatter(mode=CitationMode.NUMBER_HYPERLINKS)
        content = "See [1] for details.\n\n## Sources\n\n[1] Test Source\n   URL: https://test.com"
        result = formatter.format_document(content)
        assert "[[1]](https://test.com)" in result

    def test_formats_domain_hyperlinks(self):
        """Formats citations with domain hyperlinks."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
            CitationMode,
        )

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        content = "See [1] for details.\n\n## Sources\n\n[1] Test Source\n   URL: https://example.com/page"
        result = formatter.format_document(content)
        assert "example.com" in result

    def test_preserves_sources_section(self):
        """Preserves the sources section unchanged."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        sources_section = (
            "## Sources\n\n[1] Test Source\n   URL: https://test.com"
        )
        content = f"See [1] here.\n\n{sources_section}"
        result = formatter.format_document(content)
        assert sources_section in result


class TestCitationFormatterFormatNumberHyperlinks:
    """Tests for _format_number_hyperlinks method."""

    def test_formats_single_citation(self):
        """Formats a single citation with number hyperlink."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] here."
        sources = {"1": ("Title", "https://example.com")}
        result = formatter._format_number_hyperlinks(content, sources)
        assert "[[1]](https://example.com)" in result

    def test_formats_comma_separated_citations(self):
        """Formats comma-separated citations."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1, 2] here."
        sources = {
            "1": ("Title 1", "https://one.com"),
            "2": ("Title 2", "https://two.com"),
        }
        result = formatter._format_number_hyperlinks(content, sources)
        assert "[[1]](https://one.com)" in result
        assert "[[2]](https://two.com)" in result

    def test_formats_source_word_pattern(self):
        """Formats 'Source X' patterns."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "According to Source 1, this is true."
        sources = {"1": ("Title", "https://example.com")}
        result = formatter._format_number_hyperlinks(content, sources)
        assert "[[1]](https://example.com)" in result

    def test_leaves_citation_without_url_unchanged(self):
        """Leaves citation without URL unchanged."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] here."
        sources = {"1": ("Title", "")}  # No URL
        result = formatter._format_number_hyperlinks(content, sources)
        assert "[1]" in result
        # Should not have hyperlink
        assert "[[1]](" not in result


class TestCitationFormatterFormatDomainHyperlinks:
    """Tests for _format_domain_hyperlinks method."""

    def test_replaces_number_with_domain(self):
        """Replaces citation number with domain."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] here."
        sources = {"1": ("Title", "https://github.com/repo")}
        result = formatter._format_domain_hyperlinks(content, sources)
        assert "github.com" in result

    def test_handles_comma_separated_citations(self):
        """Handles comma-separated citations with domains."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1, 2] here."
        sources = {
            "1": ("Title 1", "https://github.com"),
            "2": ("Title 2", "https://arxiv.org"),
        }
        result = formatter._format_domain_hyperlinks(content, sources)
        assert "github.com" in result
        assert "arxiv.org" in result


class TestCitationFormatterFormatDomainIdHyperlinks:
    """Tests for _format_domain_id_hyperlinks method."""

    def test_no_id_for_single_domain_citation(self):
        """No ID suffix when only one citation from domain."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] here."
        sources = {"1": ("Title", "https://github.com/repo")}
        result = formatter._format_domain_id_hyperlinks(content, sources)
        assert "[[github.com]](" in result
        assert "-1" not in result.split("github.com")[1].split("]")[0]

    def test_adds_id_for_multiple_domain_citations(self):
        """Adds ID suffix when multiple citations from same domain."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] and [2] here."
        sources = {
            "1": ("Title 1", "https://github.com/repo1"),
            "2": ("Title 2", "https://github.com/repo2"),
        }
        result = formatter._format_domain_id_hyperlinks(content, sources)
        assert "github.com-1" in result
        assert "github.com-2" in result


class TestCitationFormatterFormatDomainIdAlwaysHyperlinks:
    """Tests for _format_domain_id_always_hyperlinks method."""

    def test_always_adds_id(self):
        """Always adds ID suffix even for single citation."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with [1] here."
        sources = {"1": ("Title", "https://github.com/repo")}
        result = formatter._format_domain_id_always_hyperlinks(content, sources)
        assert "github.com-1" in result


class TestCitationFormatterToSuperscript:
    """Tests for _to_superscript method."""

    def test_converts_single_digit(self):
        """Converts single digit to superscript."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._to_superscript("1")
        assert result == "¹"

    def test_converts_all_digits(self):
        """Converts all digits 0-9 to superscript."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        expected = "⁰¹²³⁴⁵⁶⁷⁸⁹"
        result = formatter._to_superscript("0123456789")
        assert result == expected

    def test_leaves_non_digits_unchanged(self):
        """Leaves non-digit characters unchanged."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        result = formatter._to_superscript("a1b")
        assert result == "a¹b"


class TestCitationFormatterUnicodeBrackets:
    """Tests for handling Unicode lenticular brackets."""

    def test_matches_unicode_lenticular_brackets(self):
        """Matches Unicode lenticular brackets 【】."""
        from local_deep_research.text_optimization.citation_formatter import (
            CitationFormatter,
        )

        formatter = CitationFormatter()
        content = "Text with 【1】 here."
        sources = {"1": ("Title", "https://example.com")}
        result = formatter._format_number_hyperlinks(content, sources)
        assert "[[1]](https://example.com)" in result


class TestQuartoExporterInit:
    """Tests for QuartoExporter initialization."""

    def test_can_instantiate(self):
        """Can instantiate QuartoExporter."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        assert exporter is not None

    def test_has_citation_pattern(self):
        """Has citation pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        assert exporter.citation_pattern is not None

    def test_has_comma_citation_pattern(self):
        """Has comma citation pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        assert exporter.comma_citation_pattern is not None


class TestQuartoExporterExportToQuarto:
    """Tests for export_to_quarto method."""

    def test_adds_yaml_header(self):
        """Adds YAML front matter header."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "# My Report\n\nSome content."
        result = exporter.export_to_quarto(content)
        assert result.startswith("---")
        assert "title:" in result

    def test_uses_provided_title(self):
        """Uses provided title in YAML header."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "Some content."
        result = exporter.export_to_quarto(content, title="Custom Title")
        assert "Custom Title" in result

    def test_extracts_title_from_content(self):
        """Extracts title from content if not provided."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "# My Research Report\n\nSome content."
        result = exporter.export_to_quarto(content)
        assert "My Research Report" in result

    def test_converts_citations_to_quarto_format(self):
        """Converts [1] citations to [@ref1] format."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "See [1] for details."
        result = exporter.export_to_quarto(content)
        assert "[@ref1]" in result

    def test_converts_comma_separated_citations(self):
        """Converts comma-separated citations to Quarto format."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "See [1, 2, 3] for details."
        result = exporter.export_to_quarto(content)
        assert "@ref1" in result
        assert "@ref2" in result
        assert "@ref3" in result

    def test_adds_bibliography_note(self):
        """Adds bibliography file note."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = (
            "Content.\n\n## Sources\n\n[1] Source One\n   URL: https://test.com"
        )
        result = exporter.export_to_quarto(content)
        assert "references.bib" in result


class TestQuartoExporterGenerateBibliography:
    """Tests for _generate_bibliography method."""

    def test_generates_bibtex_entries(self):
        """Generates BibTeX entries from sources."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "[1] Test Source Title\n   URL: https://example.com"
        result = exporter._generate_bibliography(content)
        assert "@misc{ref1" in result
        # BibTeX uses braces and quotes: title = "{Title}"
        assert "Test Source Title" in result
        assert "title" in result

    def test_includes_url_in_bibtex(self):
        """Includes URL in BibTeX entry."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "[1] Test Source Title\n   URL: https://example.com"
        result = exporter._generate_bibliography(content)
        assert "url = {https://example.com}" in result

    def test_generates_multiple_entries(self):
        """Generates multiple BibTeX entries."""
        from local_deep_research.text_optimization.citation_formatter import (
            QuartoExporter,
        )

        exporter = QuartoExporter()
        content = "[1] First Source\n   URL: https://first.com\n[2] Second Source\n   URL: https://second.com"
        result = exporter._generate_bibliography(content)
        assert "@misc{ref1" in result
        assert "@misc{ref2" in result


class TestRISExporterInit:
    """Tests for RISExporter initialization."""

    def test_can_instantiate(self):
        """Can instantiate RISExporter."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        assert exporter is not None

    def test_has_sources_pattern(self):
        """Has sources pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        assert exporter.sources_pattern is not None


class TestRISExporterExportToRIS:
    """Tests for export_to_ris method."""

    def test_returns_empty_for_no_sources(self):
        """Returns empty string when no sources section."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "Content without sources section."
        result = exporter.export_to_ris(content)
        assert result == ""

    def test_finds_sources_section(self):
        """Finds ## Sources section."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "Content.\n\n## Sources\n\n[1] Test Source\n   URL: https://test.com"
        result = exporter.export_to_ris(content)
        assert "TY  - ELEC" in result

    def test_finds_references_section(self):
        """Finds ## References section."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "Content.\n\n## References\n\n[1] Test Ref\n   URL: https://test.com"
        result = exporter.export_to_ris(content)
        assert "TY  - ELEC" in result

    def test_includes_title(self):
        """Includes title in RIS entry."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "## Sources\n\n[1] My Test Title"
        result = exporter.export_to_ris(content)
        assert "TI  -" in result

    def test_includes_url(self):
        """Includes URL in RIS entry."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "## Sources\n\n[1] Test Source\nURL: https://example.com"
        result = exporter.export_to_ris(content)
        assert "UR  - https://example.com" in result

    def test_includes_end_of_reference(self):
        """Includes ER - end of reference marker."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "## Sources\n\n[1] Test Source"
        result = exporter.export_to_ris(content)
        assert "ER  -" in result

    def test_includes_language(self):
        """Includes language field in RIS."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        content = "## Sources\n\n[1] Test Source"
        result = exporter.export_to_ris(content)
        assert "LA  - en" in result


class TestRISExporterCreateRISEntry:
    """Tests for _create_ris_entry method."""

    def test_creates_entry_with_id(self):
        """Creates RIS entry with reference ID."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        result = exporter._create_ris_entry("1", "Test Title")
        assert "ID  - ref1" in result

    def test_extracts_year_from_text(self):
        """Extracts year from text if present."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        result = exporter._create_ris_entry("1", "Test Title published in 2023")
        assert "PY  - 2023" in result

    def test_extracts_doi_from_metadata(self):
        """Extracts DOI from metadata."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        result = exporter._create_ris_entry(
            "1", "Test Title", metadata={"doi": "10.1234/test"}
        )
        assert "DO  - 10.1234/test" in result

    def test_extracts_publisher_from_github_url(self):
        """Extracts GitHub as publisher from URL."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        result = exporter._create_ris_entry(
            "1", "Test Title", url="https://github.com/user/repo"
        )
        assert "PB  - GitHub" in result

    def test_extracts_publisher_from_arxiv_url(self):
        """Extracts arXiv as publisher from URL."""
        from local_deep_research.text_optimization.citation_formatter import (
            RISExporter,
        )

        exporter = RISExporter()
        result = exporter._create_ris_entry(
            "1", "Test Title", url="https://arxiv.org/abs/1234"
        )
        assert "PB  - arXiv" in result


class TestLaTeXExporterInit:
    """Tests for LaTeXExporter initialization."""

    def test_can_instantiate(self):
        """Can instantiate LaTeXExporter."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        assert exporter is not None

    def test_has_citation_pattern(self):
        """Has citation pattern regex."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        assert exporter.citation_pattern is not None

    def test_has_heading_patterns(self):
        """Has heading patterns list."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        assert len(exporter.heading_patterns) > 0

    def test_has_emphasis_patterns(self):
        """Has emphasis patterns list."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        assert len(exporter.emphasis_patterns) > 0


class TestLaTeXExporterExportToLatex:
    """Tests for export_to_latex method."""

    def test_adds_document_class(self):
        """Adds documentclass declaration."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("Content")
        assert "\\documentclass" in result

    def test_adds_begin_document(self):
        """Adds begin{document}."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("Content")
        assert "\\begin{document}" in result

    def test_adds_end_document(self):
        """Adds end{document}."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("Content")
        assert "\\end{document}" in result

    def test_converts_h1_to_section(self):
        """Converts # heading to \\section."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("# My Heading\n\nContent")
        assert "\\section{My Heading}" in result

    def test_converts_h2_to_subsection(self):
        """Converts ## heading to \\subsection."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("## My Subheading\n\nContent")
        assert "\\subsection{My Subheading}" in result

    def test_converts_h3_to_subsubsection(self):
        """Converts ### heading to \\subsubsection."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("### My Sub-Subheading\n\nContent")
        assert "\\subsubsection{My Sub-Subheading}" in result

    def test_converts_bold_to_textbf(self):
        """Converts **bold** to \\textbf."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("This is **bold** text.")
        assert "\\textbf{bold}" in result

    def test_converts_italic_to_textit(self):
        """Converts *italic* to \\textit."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("This is *italic* text.")
        assert "\\textit{italic}" in result

    def test_converts_code_to_texttt(self):
        """Converts `code` to \\texttt."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("This is `code` text.")
        assert "\\texttt{code}" in result

    def test_converts_citations_to_cite(self):
        """Converts [1] to \\cite{1}."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter.export_to_latex("See [1] for details.")
        assert "\\cite{1}" in result

    def test_adds_bibliography(self):
        """Adds bibliography section when sources exist."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        content = "Content.\n\n## Sources\n\n[1] Test Source\n   URL: https://test.com"
        result = exporter.export_to_latex(content)
        assert "\\begin{thebibliography}" in result
        assert "\\end{thebibliography}" in result


class TestLaTeXExporterConvertLists:
    """Tests for _convert_lists method."""

    def test_converts_bullet_to_item(self):
        """Converts - bullet to \\item."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._convert_lists("- First item\n- Second item")
        assert "\\item First item" in result
        assert "\\item Second item" in result

    def test_adds_itemize_environment(self):
        """Adds itemize environment around list."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._convert_lists("- First item\n- Second item")
        assert "\\begin{itemize}" in result
        assert "\\end{itemize}" in result


class TestLaTeXExporterEscapeLatex:
    """Tests for _escape_latex method."""

    def test_escapes_ampersand(self):
        """Escapes & character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("A & B")
        assert "\\&" in result

    def test_escapes_percent(self):
        """Escapes % character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("50%")
        assert "\\%" in result

    def test_escapes_dollar(self):
        """Escapes $ character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("$100")
        assert "\\$" in result

    def test_escapes_hash(self):
        """Escapes # character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("#1")
        assert "\\#" in result

    def test_escapes_underscore(self):
        """Escapes _ character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("file_name")
        assert "\\_" in result

    def test_escapes_braces(self):
        """Escapes { and } characters."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("{test}")
        assert "\\{" in result
        assert "\\}" in result

    def test_escapes_tilde(self):
        """Escapes ~ character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("~test")
        assert "\\textasciitilde{}" in result

    def test_escapes_caret(self):
        """Escapes ^ character."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._escape_latex("x^2")
        assert "\\textasciicircum{}" in result


class TestLaTeXExporterCreateBibliography:
    """Tests for _create_bibliography method."""

    def test_returns_empty_for_no_sources(self):
        """Returns empty string when no sources section."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        result = exporter._create_bibliography("Content without sources.")
        assert result == ""

    def test_creates_bibitem_entries(self):
        """Creates bibitem entries for sources."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        content = "## Sources\n\n[1] Test Source Title"
        result = exporter._create_bibliography(content)
        assert "\\bibitem{1}" in result

    def test_includes_url_in_bibitem(self):
        """Includes URL in bibitem entry."""
        from local_deep_research.text_optimization.citation_formatter import (
            LaTeXExporter,
        )

        exporter = LaTeXExporter()
        content = (
            "## Sources\n\n[1] Test Source Title\n   URL: https://example.com"
        )
        result = exporter._create_bibliography(content)
        assert "\\url{https://example.com}" in result
