"""Gantt chart renderer — horizontal bar schedule diagram."""

from __future__ import annotations

from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import MSO_ANCHOR, PP_ALIGN
from pptx.slide import Slide
from pptx.util import Inches, Pt

from pptx_mcp.engine.diagrams._common import add_textbox, brand_color_at, text_color_for_shape
from pptx_mcp.engine.layouts import _add_slide_title
from pptx_mcp.engine.shapes import parse_hex_color, set_corner_radius
from pptx_mcp.models.brand import BrandConfig
from pptx_mcp.models.slides import SlideDefinition


def render_gantt_slide(
    slide: Slide,
    definition: SlideDefinition,
    brand: BrandConfig,
    slide_width: float,
) -> None:
    """Render a Gantt chart with horizontal task bars and optional phase headers."""
    _add_slide_title(slide, definition.title, brand, slide_width)

    tasks = definition.gantt_tasks or []
    if not tasks:
        return

    n = len(tasks)
    sp = brand.spacing
    content_w = slide_width - sp.margin_left - sp.margin_right
    phases = definition.gantt_phases or []

    label_w = 2.2  # width of task label column
    chart_left = sp.margin_left + label_w + 0.15
    chart_w = content_w - label_w - 0.15
    chart_top = sp.content_top + 0.3
    phase_header_h = 0.35

    # Reserve space for phase headers if phases exist
    if phases:
        chart_top += phase_header_h + 0.1

    row_h = min(0.4, (5.0 - (chart_top - sp.content_top)) / max(n, 1))
    row_gap = 0.06

    # --- phase headers ---
    if phases:
        phase_w = chart_w / len(phases)
        for j, phase_label in enumerate(phases):
            px = chart_left + j * phase_w
            py = sp.content_top + 0.3
            ph_rect = slide.shapes.add_shape(
                MSO_SHAPE.RECTANGLE,
                Inches(px), Inches(py),
                Inches(phase_w - 0.04), Inches(phase_header_h),
            )
            ph_rect.fill.solid()
            ph_rect.fill.fore_color.rgb = parse_hex_color(brand.colors.secondary)
            ph_rect.line.fill.background()

            tf = ph_rect.text_frame
            tf.word_wrap = True
            tf.vertical_anchor = MSO_ANCHOR.MIDDLE
            p = tf.paragraphs[0]
            p.text = phase_label
            p.alignment = PP_ALIGN.CENTER
            run = p.runs[0]
            run.font.name = brand.fonts.body_font
            run.font.size = Pt(10)
            run.font.bold = True
            run.font.color.rgb = parse_hex_color("#FFFFFF")

    # --- assign colors by group ---
    group_colors: dict[str | None, str] = {}
    color_idx = 0
    for task in tasks:
        g = task.group
        if g not in group_colors:
            group_colors[g] = brand_color_at(brand, color_idx)
            color_idx += 1

    # --- task rows ---
    for i, task in enumerate(tasks):
        top = chart_top + i * (row_h + row_gap)

        # Task label
        add_textbox(
            slide,
            sp.margin_left,
            top,
            label_w,
            row_h,
            text=task.label,
            font_name=brand.fonts.body_font,
            font_size=10,
            bold=False,
            color=brand.colors.text_primary,
            alignment=PP_ALIGN.LEFT,
        )

        # Task bar
        bar_left = chart_left + task.start * chart_w
        bar_w = max(task.duration * chart_w, 0.1)
        color_hex = task.color or group_colors.get(task.group, brand.colors.primary)

        bar = slide.shapes.add_shape(
            MSO_SHAPE.ROUNDED_RECTANGLE,
            Inches(bar_left), Inches(top),
            Inches(bar_w), Inches(row_h),
        )
        bar.fill.solid()
        bar.fill.fore_color.rgb = parse_hex_color(color_hex)
        bar.line.fill.background()
        set_corner_radius(bar, brand.shape_style.card_corner_radius)

        # Progress overlay (darker shade within bar)
        if task.progress > 0:
            prog_w = bar_w * min(task.progress, 1.0)
            prog = slide.shapes.add_shape(
                MSO_SHAPE.ROUNDED_RECTANGLE,
                Inches(bar_left), Inches(top),
                Inches(prog_w), Inches(row_h),
            )
            # Darken the bar color for the progress portion
            base_rgb = parse_hex_color(color_hex)
            dark_r = max(int(base_rgb[0] * 0.7), 0)
            dark_g = max(int(base_rgb[1] * 0.7), 0)
            dark_b = max(int(base_rgb[2] * 0.7), 0)
            prog.fill.solid()
            prog.fill.fore_color.rgb = RGBColor(dark_r, dark_g, dark_b)
            prog.line.fill.background()
            set_corner_radius(prog, brand.shape_style.card_corner_radius)

        # Bar label text (task name inside bar if wide enough)
        if bar_w > 0.8:
            tf = bar.text_frame
            tf.word_wrap = True
            tf.vertical_anchor = MSO_ANCHOR.MIDDLE
            p = tf.paragraphs[0]
            p.text = task.label
            p.alignment = PP_ALIGN.CENTER
            run = p.runs[0]
            run.font.name = brand.fonts.body_font
            run.font.size = Pt(10)
            run.font.color.rgb = parse_hex_color(text_color_for_shape(color_hex, brand))
