#
#   Imandra Inc.
#
#   speclogician/presentation/renderers/state_instance.py
#

from __future__ import annotations

from rich.console import Group, RenderableType
from rich.panel import Panel

from speclogician.presentation.ctx import RenderCtx
from speclogician.presentation.models.state_instance import StateInstancePM

from speclogician.presentation.renderers.spec import render_spec
from speclogician.presentation.renderers.state_diff import render_state_diff
from speclogician.presentation.renderers.container import render_artifact_container
from speclogician.presentation.renderers.state_instance_summary import (
    render_state_instance_summary,
)
from speclogician.presentation.renderers.recommendations import render_recommendations

# NEW: trace reachability renderer
from speclogician.presentation.renderers.trace_reachability import render_trace_reachability


def render_state_instance(pm: StateInstancePM, *, ctx: RenderCtx) -> RenderableType:
    summary_panel = render_state_instance_summary(pm.summary, ctx=ctx)

    # Always show recommendations first if present (cheap + high-signal).
    rec_panel: RenderableType | None = None
    if getattr(pm, "recommendations", None) is not None:
        rec_panel = render_recommendations(pm.recommendations, ctx=ctx)

    # Trace reachability (analysis)
    trace_reach_panel: RenderableType | None = None
    if getattr(pm, "trace_reachability", None) is not None:
        trace_reach_panel = render_trace_reachability(pm.trace_reachability, ctx=ctx)

    # Stats-only: recommendations + summary + (optional) trace reachability
    if ctx.show_stats_only:
        blocks: list[RenderableType] = []
        if rec_panel is not None:
            blocks.append(rec_panel)
        blocks.append(summary_panel)
        if trace_reach_panel is not None and (getattr(ctx, "show_analyses", True) or ctx.show_empty_sections):
            blocks.append(
                Panel(
                    trace_reach_panel,
                    title="[bold]Trace reachability[/bold]",
                    border_style="blue",
                    expand=True,
                )
            )
        return Panel(
            Group(*blocks),
            title="[bold]State instance[/bold]",
            border_style="magenta",
            expand=True,
        )

    blocks: list[RenderableType] = []
    if rec_panel is not None:
        blocks.append(rec_panel)

    blocks.append(summary_panel)

    if trace_reach_panel is not None and getattr(ctx, "show_analyses", True):
        blocks.append(
            Panel(
                trace_reach_panel,
                title="[bold]Trace reachability[/bold]",
                border_style="blue",
                expand=True,
            )
        )

    if pm.state_diff is not None and getattr(ctx, "show_diff", True):
        blocks.append(
            Panel(
                render_state_diff(pm.state_diff, ctx=ctx),
                title="[bold]Diff[/bold]",
                border_style="yellow",
                expand=True,
            )
        )

    if pm.spec is not None:
        blocks.append(
            Panel(
                render_spec(pm.spec, ctx=ctx),
                title="[bold]Spec[/bold]",
                border_style="cyan",
                expand=True,
            )
        )

    if pm.artifacts is not None:
        blocks.append(
            Panel(
                render_artifact_container(pm.artifacts, ctx=ctx),
                title="[bold]Artifacts[/bold]",
                border_style="green",
                expand=True,
            )
        )

    return Panel(
        Group(*blocks),
        title="[bold]State instance[/bold]",
        border_style="magenta",
        expand=True,
    )