"""Shared helpers for diagram renderers."""

from __future__ import annotations

from pptx.slide import Slide
from pptx.util import Inches, Pt

from pptx_mcp.engine.shapes import ensure_readable_text_color, parse_hex_color
from pptx_mcp.models.brand import BrandConfig


def brand_color_at(brand: BrandConfig, index: int) -> str:
    """Return chart_colors[index % len] or fall back to accent."""
    colors = brand.colors.chart_colors
    if not colors:
        return brand.colors.accent
    return colors[index % len(colors)]


def add_freeform_connector(
    slide: Slide,
    x1: float,
    y1: float,
    x2: float,
    y2: float,
    color: str,
    width: float = 1.0,
) -> None:
    """Draw a straight connector line between two points (inches)."""
    connector = slide.shapes.add_connector(
        1,  # MSO_CONNECTOR_TYPE.STRAIGHT
        Inches(x1),
        Inches(y1),
        Inches(x2),
        Inches(y2),
    )
    connector.line.color.rgb = parse_hex_color(color)
    connector.line.width = Pt(width)


def text_color_for_shape(fill_hex: str, brand: BrandConfig) -> str:
    """Return a readable text color for a shape with the given fill.

    Prefers white text; falls back to the brand's primary text color
    when the fill is too light for white text to be readable.
    """
    return ensure_readable_text_color(
        fill_hex, "#FFFFFF",
        fallback_dark=brand.colors.text_primary,
        fallback_light="#FFFFFF",
    )


def add_textbox(
    slide: Slide,
    left: float,
    top: float,
    width: float,
    height: float,
    text: str,
    font_name: str = "Calibri",
    font_size: int = 10,
    bold: bool = False,
    color: str | None = None,
    alignment: object | None = None,
) -> object:
    """Add a simple textbox and return the shape."""
    from pptx.enum.text import PP_ALIGN

    tb = slide.shapes.add_textbox(
        Inches(left), Inches(top), Inches(width), Inches(height),
    )
    tf = tb.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = text
    if alignment is not None:
        p.alignment = alignment
    else:
        p.alignment = PP_ALIGN.CENTER
    run = p.runs[0]
    run.font.name = font_name
    run.font.size = Pt(font_size)
    run.font.bold = bold
    if color:
        run.font.color.rgb = parse_hex_color(color)
    return tb
