"""Data visualization tools."""

from pydantic_ai.toolsets import FunctionToolset

from pydanticai_multiagent.dependencies import BaseDeps

visualization_toolset: FunctionToolset[BaseDeps] = FunctionToolset()


@visualization_toolset.tool
def create_ascii_bar_chart(
    labels: list[str],
    values: list[float],
    max_width: int = 40,
) -> str:
    """Create a simple ASCII bar chart.

    Args:
        labels: Labels for each bar.
        values: Numeric values for each bar.
        max_width: Maximum width of the bars in characters.
    """
    if len(labels) != len(values):
        return "Error: Labels and values must have the same length."

    if not values:
        return "Error: No data provided."

    max_val = max(values)
    if max_val == 0:
        max_val = 1

    # Find longest label for padding
    max_label_len = max(len(str(label)) for label in labels)

    lines = []
    for label, value in zip(labels, values, strict=False):
        bar_len = int((value / max_val) * max_width)
        bar = "█" * bar_len
        padded_label = str(label).ljust(max_label_len)
        lines.append(f"{padded_label} | {bar} {value:.1f}")

    return "\n".join(lines)


@visualization_toolset.tool
def create_ascii_line_chart(
    values: list[float],
    height: int = 10,
    width: int = 50,
) -> str:
    """Create a simple ASCII line chart.

    Args:
        values: Sequential numeric values to plot.
        height: Height of the chart in lines.
        width: Width of the chart in characters.
    """
    if not values:
        return "Error: No data provided."

    min_val = min(values)
    max_val = max(values)
    val_range = max_val - min_val if max_val != min_val else 1

    # Resample values to fit width
    if len(values) > width:
        step = len(values) / width
        resampled = [values[int(i * step)] for i in range(width)]
    else:
        resampled = values

    # Create the chart
    chart = []
    for row in range(height, 0, -1):
        threshold = min_val + (row / height) * val_range
        line = ""
        for val in resampled:
            if val >= threshold:
                line += "●"
            else:
                line += " "
        chart.append(f"{threshold:8.1f} |{line}")

    # Add x-axis
    chart.append(" " * 9 + "+" + "-" * len(resampled))

    return "\n".join(chart)


@visualization_toolset.tool
def create_histogram(
    data: list[float],
    bins: int = 10,
    max_width: int = 40,
) -> str:
    """Create an ASCII histogram.

    Args:
        data: Numeric values to create histogram from.
        bins: Number of bins for the histogram.
        max_width: Maximum width of the bars.
    """
    if not data:
        return "Error: No data provided."

    min_val = min(data)
    max_val = max(data)
    bin_width = (max_val - min_val) / bins if max_val != min_val else 1

    # Count values in each bin
    counts = [0] * bins
    for val in data:
        bin_idx = min(int((val - min_val) / bin_width), bins - 1)
        counts[bin_idx] += 1

    max_count = max(counts)
    if max_count == 0:
        max_count = 1

    lines = []
    for i in range(bins):
        bin_start = min_val + i * bin_width
        bin_end = bin_start + bin_width
        bar_len = int((counts[i] / max_count) * max_width)
        bar = "█" * bar_len
        lines.append(f"[{bin_start:6.1f}-{bin_end:6.1f}) | {bar} ({counts[i]})")

    return "\n".join(lines)
