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

from __future__ import annotations

from rich import box
from rich.console import Group
from rich.panel import Panel
from rich.syntax import Syntax
from rich.table import Table
from rich.text import Text

from speclogician.presentation.ctx import RenderCtx
from speclogician.presentation.models.domain import DomainModelPM


def render_domain_model(pm: DomainModelPM, *, ctx: RenderCtx):
    b = box.MINIMAL if ctx.compact else box.SIMPLE

    c = pm.counts
    code = pm.code

    stats = Table(
        show_header=False,
        box=b,
        show_edge=False,
        pad_edge=False,
        expand=False,   # ← critical change
    )
    stats.add_column(style="dim", no_wrap=True)
    stats.add_column(justify="right")

    def hdr(label: str) -> None:
        stats.add_row(Text(label, style="bold magenta"), Text(""))

    def row(label: str, value: object, *, bold: bool = False) -> None:
        stats.add_row(
            Text("  " + label),
            Text(str(value), style="bold" if bold else "")
        )

    # ----------------------------
    # Base
    # ----------------------------
    hdr("Base")
    row("Base status", c.base_status, bold=True)
    row("Has state", c.base_has_state)
    row("Has action", c.base_has_action)

    # ----------------------------
    # Predicates
    # ----------------------------
    hdr("Predicates")
    row("State total", c.num_state_preds_total, bold=True)
    row("State valid", c.num_state_preds_valid_logic)
    row("State matched", c.num_state_preds_matched)

    row("Action total", c.num_action_preds_total, bold=True)
    row("Action valid", c.num_action_preds_valid_logic)
    row("Action matched", c.num_action_preds_matched)

    row("All total", c.num_preds_total, bold=True)
    row("All valid", c.num_preds_valid_logic)
    row("All matched", c.num_preds_matched)

    # ----------------------------
    # Transitions
    # ----------------------------
    hdr("Transitions")
    row("Total", c.num_trans_total, bold=True)
    row("Valid", c.num_trans_valid_logic)
    row("Matched", c.num_trans_matched)

    if ctx.show_stats_only or not ctx.show_code:
        return Panel(stats, title="[bold]Domain model[/bold]", border_style="magenta")

    blocks: list[object] = [
        Panel(stats, title="[bold]Stats[/bold]", border_style="magenta"),
    ]

    # Base code
    if code.base.strip():
        blocks.append(
            Panel(
                Syntax(code.base, "ocaml", word_wrap=True, line_numbers=not ctx.compact),
                title="Base",
                border_style="cyan",
            )
        )

    # Predicates code
    if code.state_preds_iml.strip():
        blocks.append(
            Panel(
                Syntax(code.state_preds_iml, "ocaml", word_wrap=True, line_numbers=not ctx.compact),
                title="State predicates",
                border_style="green",
            )
        )

    if code.action_preds_iml.strip():
        blocks.append(
            Panel(
                Syntax(code.action_preds_iml, "ocaml", word_wrap=True, line_numbers=not ctx.compact),
                title="Action predicates",
                border_style="green",
            )
        )

    # Transitions code
    if code.transitions_iml.strip():
        blocks.append(
            Panel(
                Syntax(code.transitions_iml, "ocaml", word_wrap=True, line_numbers=not ctx.compact),
                title="Transitions",
                border_style="blue",
            )
        )

    return Panel(Group(*blocks), title="[bold]Domain model[/bold]", border_style="magenta")