#
#   Imandra Inc.
#
#   speclogician/presentation/builders/scenario_complement.py
#

from __future__ import annotations

from speclogician.presentation.ctx import RenderCtx
from speclogician.presentation.models.scenario_complement import (
    ScenarioComplementPM,
    ScenarioComplementRegionPM,
)

from speclogician.modeling.complement import ScenarioComplement, _fingerprint_region


def _safe_list(x) -> list:
    try:
        return list(x or [])
    except Exception:
        return []


def build_scenario_complement_pm(
    comp: ScenarioComplement | None,
    ctx: RenderCtx,
    *,
    preview_limit: int = 10,
    constraints_preview_limit: int = 3,
) -> ScenarioComplementPM:
    if comp is None:
        return ScenarioComplementPM(count_regions=0, regions_preview=[])

    regs = _safe_list(getattr(comp, "regions", None))
    count = len(regs)

    # show only a few regions in the UI
    preview_regs = regs[: max(0, int(preview_limit))]

    items: list[ScenarioComplementRegionPM] = []
    for r in preview_regs:
        fp = _fingerprint_region(r)

        constraints = _safe_list(getattr(r, "constraints_str", None))
        invariant = (getattr(r, "invariant_str", None) or None)
        model_eval = (getattr(r, "model_eval_str", None) or None)

        # model_str can be dict-like; stringify for display
        model_obj = getattr(r, "model_str", None)
        if model_obj is None:
            model_s = None
        else:
            try:
                model_s = str(model_obj)
            except Exception:
                model_s = "<unprintable>"

        # If ctx.show_code is False, keep it extra light.
        if not ctx.show_code:
            invariant = None
            model_s = None
            model_eval = None
            constraints_preview: list[str] = []
        else:
            constraints_preview = [str(c) for c in constraints[: max(0, int(constraints_preview_limit))]]

        items.append(
            ScenarioComplementRegionPM(
                fp=fp,
                num_constraints=len(constraints),
                invariant=invariant,
                model=model_s,
                model_eval=model_eval,
                constraints_preview=constraints_preview,
            )
        )

    return ScenarioComplementPM(
        count_regions=count,
        regions_preview=items,
    )