#
#   Imandra Inc.
#
#   speclogician/presentation/preview/fixtures/state_diff.py
#

from __future__ import annotations

from rich.console import RenderableType

from speclogician.presentation.ctx import RenderCtx
from speclogician.presentation.models.state_diff import StateDiffPM, DiffSectionPM, DiffRowPM
from speclogician.state.diff import ComparisonOutcome
from speclogician.presentation.renderers.state_diff import render_state_diff


def make_state_diff_pm(ctx: RenderCtx, variant: str) -> StateDiffPM:
    # keep fixtures deterministic, not dependent on real state
    if variant == "minimal":
        return StateDiffPM(has_changes=False, sections=[])

    if variant == "edge":
        return StateDiffPM(
            has_changes=True,
            sections=[
                DiffSectionPM(
                    title="Domain Model: Base",
                    rows=[
                        DiffRowPM(
                            label="base_status",
                            before="UNKNOWN",
                            after="VALID",
                            outcome=ComparisonOutcome.IMPROVED,
                            message="base_status improved",
                        ),
                        DiffRowPM(
                            label="base_has_action",
                            before=False,
                            after=False,
                            outcome=ComparisonOutcome.NO_CHANGE_BAD,
                            message="still missing action",
                        ),
                        DiffRowPM(
                            label="base_src",
                            before="type state = ...\n" * 3,
                            after="type state = int\ntype action = int\n",
                            outcome=ComparisonOutcome.UNKNOWN,
                            message="multi-line (unknown comparator)",
                        ),
                    ],
                ),
                DiffSectionPM(
                    title="Scenarios",
                    rows=[
                        DiffRowPM(
                            label="num_sc_total",
                            before=3,
                            after=5,
                            outcome=ComparisonOutcome.IMPROVED,
                            message="more scenarios",
                        ),
                        DiffRowPM(
                            label="num_sc_inconsistent",
                            before=0,
                            after=1,
                            outcome=ComparisonOutcome.DECLINED,
                            message="introduced inconsistency",
                        ),
                    ],
                ),
                DiffSectionPM(
                    title="Coverage: Complement",
                    rows=[
                        DiffRowPM(
                            label="scenario_comp_present",
                            before=False,
                            after=True,
                            outcome=ComparisonOutcome.IMPROVED,
                            message="complement now computed",
                        ),
                        DiffRowPM(
                            label="num_comp_regions_total",
                            before=12,
                            after=4,
                            outcome=ComparisonOutcome.IMPROVED,
                            message="fewer uncovered regions",
                        ),
                    ],
                ),
            ],
        )

    return StateDiffPM(
        has_changes=True,
        sections=[
            DiffSectionPM(
                title="Domain Model: Base",
                rows=[
                    DiffRowPM(
                        label="base_status",
                        before="UNKNOWN",
                        after="VALID",
                        outcome=ComparisonOutcome.IMPROVED,
                        message="base status improved",
                    ),
                    DiffRowPM(
                        label="base_has_state",
                        before=False,
                        after=True,
                        outcome=ComparisonOutcome.IMPROVED,
                        message="now has state",
                    ),
                ],
            ),
            DiffSectionPM(
                title="Scenarios",
                rows=[
                    DiffRowPM(
                        label="num_sc_total",
                        before=3,
                        after=5,
                        outcome=ComparisonOutcome.IMPROVED,
                        message="more scenarios",
                    ),
                    DiffRowPM(
                        label="num_sc_inconsistent",
                        before=0,
                        after=1,
                        outcome=ComparisonOutcome.DECLINED,
                        message="inconsistency added",
                    ),
                ],
            ),
            DiffSectionPM(
                title="Coverage: Complement",
                rows=[
                    DiffRowPM(
                        label="scenario_comp_present",
                        before=True,
                        after=True,
                        outcome=ComparisonOutcome.NO_CHANGE_GOOD,
                        message="complement still present",
                    ),
                    DiffRowPM(
                        label="num_comp_regions_total",
                        before=6,
                        after=6,
                        outcome=ComparisonOutcome.NO_CHANGE_BAD,
                        message="coverage not improving yet",
                    ),
                ],
            ),
        ],
    )


def render(pm: StateDiffPM, ctx: RenderCtx) -> RenderableType:
    return render_state_diff(pm, ctx=ctx)
