from __future__ import annotations

import importlib.util
from pathlib import Path


ROOT = Path(__file__).resolve().parents[2]
SCRIPT = ROOT / "scripts" / "discover_1c_moxel_schema.py"
SPEC = importlib.util.spec_from_file_location("discover_1c_moxel_schema", SCRIPT)
assert SPEC and SPEC.loader
discovery = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(discovery)


def test_analyze_marker_matrix_infers_inline_text_column_from_last_preceding_scalar() -> None:
    payload = {
        "schema": "codex_1c_template_marker_matrix.v1",
        "rows": [
            {"text": "10-2", "expected_row": 10, "expected_col": 2, "decoded_row": 10, "decoded_col": 3, "preceding": ["9", "0", "3", "1"]},
            {"text": "10-3", "expected_row": 10, "expected_col": 3, "decoded_row": 10, "decoded_col": 4, "preceding": ["2"]},
            {"text": "10-4", "expected_row": 10, "expected_col": 4, "decoded_row": 10, "decoded_col": 11, "preceding": ["3"]},
        ],
    }

    analysis = discovery.analyze_marker_matrix([payload])
    rule = analysis["candidate_rules"][0]

    assert analysis["current_decoder"]["row_accuracy"] == {"ok": 3, "total": 3}
    assert analysis["current_decoder"]["column_accuracy"] == {"ok": 0, "total": 3}
    assert rule["target"] == "moxel.inline_text_cell.column"
    assert rule["confidence"] == "high"
    assert rule["evidence"] == {"ok": 3, "total": 3}
    assert analysis["row_runs"][0]["sequence_ok"] is True


def test_infer_named_range_rules_from_history_matrix_moves() -> None:
    history_matrix = {
        "transitions": [
            {
                "named_range_changes": {
                    "one_based": {
                        "before": {"row_start": 7, "row_end": 7, "column_start": 3, "column_end": 3},
                        "after": {"row_start": 8, "row_end": 8, "column_start": 3, "column_end": 3},
                    },
                    "raw_scalars": {
                        "before": ["1", "3", "2", "6", "2", "6", "00000000-0000-0000-0000-000000000000", "0"],
                        "after": ["1", "3", "2", "7", "2", "7", "00000000-0000-0000-0000-000000000000", "0"],
                    },
                }
            },
            {
                "named_range_changes": {
                    "one_based": {
                        "before": {"row_start": 8, "row_end": 8, "column_start": 3, "column_end": 3},
                        "after": {"row_start": 8, "row_end": 8, "column_start": 4, "column_end": 4},
                    },
                    "raw_scalars": {
                        "before": ["1", "3", "2", "7", "2", "7", "00000000-0000-0000-0000-000000000000", "0"],
                        "after": ["1", "3", "3", "7", "3", "7", "00000000-0000-0000-0000-000000000000", "0"],
                    },
                }
            },
        ]
    }

    result = discovery.infer_named_range_rules(history_matrix, {})
    rules_by_target = {rule["target"]: rule for rule in result["rules"]}

    assert rules_by_target["moxel.named_range.top"]["raw_scalar_indexes"] == [3, 5]
    assert rules_by_target["moxel.named_range.bottom"]["raw_scalar_indexes"] == [3, 5]
    assert rules_by_target["moxel.named_range.left"]["raw_scalar_indexes"] == [2, 4]
    assert rules_by_target["moxel.named_range.right"]["raw_scalar_indexes"] == [2, 4]
