# ABOUTME: Tests for the table_format module that formats DataFrames for console output.
# ABOUTME: Covers markdown/csv formats, ANSI column colorization, and edge cases.

import pandas as pd
import pytest

from Capricho.core.table_format import format_dataframe

RESET = "\033[0m"
COLORS = ["\033[97m", "\033[94m", "\033[91m", "\033[92m", "\033[93m", "\033[96m"]


@pytest.fixture
def sample_df():
    return pd.DataFrame({"name": ["alice", "bob", "charlie"], "score": [10, 20, 30]})


@pytest.fixture
def empty_df():
    return pd.DataFrame(columns=["name", "score"])


class TestMarkdownFormat:
    def test_contains_pipe_separators(self, sample_df):
        result = format_dataframe(sample_df, "markdown", colorize=False)
        assert "|" in result

    def test_contains_header_separator(self, sample_df):
        result = format_dataframe(sample_df, "markdown", colorize=False)
        lines = result.strip().split("\n")
        assert any("---" in line for line in lines)


class TestCsvFormat:
    def test_contains_commas(self, sample_df):
        result = format_dataframe(sample_df, "csv", colorize=False)
        assert "," in result

    def test_no_pipe_separators(self, sample_df):
        result = format_dataframe(sample_df, "csv", colorize=False)
        assert "|" not in result

    def test_header_row_present(self, sample_df):
        result = format_dataframe(sample_df, "csv", colorize=False)
        first_line = result.strip().split("\n")[0]
        assert "name" in first_line
        assert "score" in first_line


class TestUnsupportedFormat:
    def test_raises_on_unknown_format(self, sample_df):
        with pytest.raises(ValueError, match="Unsupported format"):
            format_dataframe(sample_df, "grid", colorize=False)


class TestColorizeOff:
    def test_no_ansi_codes(self, sample_df):
        result = format_dataframe(sample_df, "markdown", colorize=False)
        assert "\033[" not in result

    def test_no_ansi_codes_csv(self, sample_df):
        result = format_dataframe(sample_df, "csv", colorize=False)
        assert "\033[" not in result


class TestColorizeOn:
    def test_ansi_codes_present_markdown(self, sample_df):
        result = format_dataframe(sample_df, "markdown", colorize=True)
        assert "\033[" in result

    def test_ansi_codes_present_csv(self, sample_df):
        result = format_dataframe(sample_df, "csv", colorize=True)
        assert "\033[" in result

    def test_same_column_same_color_across_rows(self, sample_df):
        """Column 0 should get the same color in the header and all data rows."""
        result = format_dataframe(sample_df, "markdown", colorize=True)
        lines = result.strip().split("\n")
        data_lines = [l for l in lines if "|" in l and "---" not in l]
        for line in data_lines:
            assert COLORS[0] in line, f"First column color missing: {line}"

    def test_different_columns_get_different_colors(self, sample_df):
        """With 2 columns, both COLORS[0] and COLORS[1] should appear in each data row."""
        result = format_dataframe(sample_df, "markdown", colorize=True)
        lines = result.strip().split("\n")
        data_lines = [l for l in lines if "alice" in l]
        assert len(data_lines) == 1
        assert COLORS[0] in data_lines[0]
        assert COLORS[1] in data_lines[0]

    def test_column_color_cycling_wraps(self):
        """With more columns than colors, colors cycle."""
        cols = {f"c{i}": [i] for i in range(8)}
        df = pd.DataFrame(cols)
        result = format_dataframe(df, "markdown", colorize=True)
        lines = result.strip().split("\n")
        header_line = [l for l in lines if "c0" in l][0]
        # Column 0 and column 6 should share a color
        assert header_line.count(COLORS[0]) >= 2

    def test_csv_column_coloring(self, sample_df):
        """CSV colorize should color each cell, resetting per row."""
        result = format_dataframe(sample_df, "csv", colorize=True)
        lines = result.strip().split("\n")
        for line in lines:
            assert COLORS[0] in line

    def test_markdown_separator_not_colored(self, sample_df):
        result = format_dataframe(sample_df, "markdown", colorize=True)
        lines = result.strip().split("\n")
        sep_lines = [l for l in lines if "---" in l]
        for line in sep_lines:
            assert "\033[" not in line, f"Separator line should not be colored: {line}"


class TestEmptyDataFrame:
    def test_empty_markdown_no_error(self, empty_df):
        result = format_dataframe(empty_df, "markdown", colorize=False)
        assert isinstance(result, str)

    def test_empty_csv_no_error(self, empty_df):
        result = format_dataframe(empty_df, "csv", colorize=False)
        assert isinstance(result, str)

    def test_empty_colorize_no_error(self, empty_df):
        result = format_dataframe(empty_df, "markdown", colorize=True)
        assert isinstance(result, str)
