"""Tests del visual heredado del Group (issue 0035e).

El binario C++ implementa `apply_group_inherited_visuals` en data.cpp:
para cada nodo Group del grafo, consulta `SELECT DISTINCT type_ref
FROM entities WHERE group_id = ? AND type_ref != 'Group'`. Si la
familia es homogenea (un solo tipo), reasigna el `type_id` del nodo
Group al de ese tipo y fija `shape_override = SHAPE_SQUARE`. Si es
heterogenea o vacia, conserva el visual generico.

El subcomando `gx-cli group visual <id>` espejea exactamente esa SQL,
asi estos tests verifican el contrato (homogeneo vs heterogeneo,
type heredado y shape=square preservado) sin depender del binario.
"""
from __future__ import annotations

import sqlite3

from test_gx_cli import OPS_SCHEMA, APP_SCHEMA, env_dirs, run_gx  # noqa: F401


def _seed_group_with_children(ops_db, group_id: str,
                                child_specs: list[tuple[str, str]]):
    """Inserta el contenedor Group + cada hijo (id, type_ref).

    `child_specs` = [(child_id, type_ref), ...]. Se anaden con group_id
    apuntando al contenedor.
    """
    cn = sqlite3.connect(ops_db)
    try:
        cn.execute(
            "INSERT INTO entities(id, name, type_ref, status, source, "
            "                     metadata, created_at, updated_at) "
            "VALUES (?, ?, 'Group', 'active', 'manual', '{}', "
            "        '2026-05-04T10:00:00.000Z', '2026-05-04T10:00:00.000Z')",
            (group_id, "test-group"),
        )
        for i, (cid, type_ref) in enumerate(child_specs):
            cn.execute(
                "INSERT INTO entities(id, name, type_ref, status, source, "
                "                     metadata, group_id, "
                "                     created_at, updated_at) "
                "VALUES (?, ?, ?, 'active', 'manual', '{}', ?, ?, ?)",
                (cid, f"name-{i}", type_ref, group_id,
                 f"2026-05-04T11:{i:02d}:00.000Z",
                 f"2026-05-04T11:{i:02d}:00.000Z"),
            )
        cn.commit()
    finally:
        cn.close()


def test_group_inherits_visual_from_homogeneous_children(env_dirs):
    """5 Urls como hijos -> visual heredado a 'Url' (homogeneo)."""
    children = [(f"u_{i:02d}", "Url") for i in range(5)]
    _seed_group_with_children(env_dirs["ops"], "G_homogeneous", children)
    out = run_gx(env_dirs, "group", "visual", "G_homogeneous")
    assert out["homogeneous"] is True, out
    assert out["inherited"] == "Url", out
    assert out["child_types"] == ["Url"], out
    # La forma siempre se queda como square — distintivo de contenedor.
    assert out["shape"] == "square", out


def test_group_falls_back_to_generic_for_heterogeneous(env_dirs):
    """Url + Email en el mismo Group -> visual generico Group."""
    children = [
        ("u_00", "Url"),    ("u_01", "Url"),    ("u_02", "Url"),
        ("e_00", "Email"),  ("e_01", "Email"),
    ]
    _seed_group_with_children(env_dirs["ops"], "G_heterogeneous", children)
    out = run_gx(env_dirs, "group", "visual", "G_heterogeneous")
    assert out["homogeneous"] is False, out
    assert out["inherited"] == "Group", out
    # child_types ordenado alfabeticamente — verifica ambos presentes.
    assert out["child_types"] == ["Email", "Url"], out
    assert out["shape"] == "square", out


def test_group_with_no_children_falls_back_to_generic(env_dirs):
    """Group vacio (sin hijos con group_id apuntando a el) -> generico."""
    _seed_group_with_children(env_dirs["ops"], "G_empty", [])
    out = run_gx(env_dirs, "group", "visual", "G_empty")
    assert out["homogeneous"] is False, out
    assert out["inherited"] == "Group", out
    assert out["child_types"] == [], out


def test_group_visual_ignores_nested_subgroups(env_dirs):
    """Subgrupos anidados (type_ref='Group') no cuentan — siguen scope fase 1."""
    cn = sqlite3.connect(env_dirs["ops"])
    try:
        cn.execute(
            "INSERT INTO entities(id, name, type_ref, status, source, "
            "                     metadata, created_at, updated_at) "
            "VALUES ('G_outer', 'outer', 'Group', 'active', 'manual', '{}', "
            "        '2026-05-04T10:00:00.000Z', '2026-05-04T10:00:00.000Z')"
        )
        for i in range(3):
            cn.execute(
                "INSERT INTO entities(id, name, type_ref, status, source, "
                "                     metadata, group_id, "
                "                     created_at, updated_at) "
                "VALUES (?, ?, 'Url', 'active', 'manual', '{}', 'G_outer', "
                "        '2026-05-04T11:00:00.000Z', '2026-05-04T11:00:00.000Z')",
                (f"u_{i}", f"url-{i}"),
            )
        # Subgrupo anidado — el resolver lo excluye via type_ref != 'Group'.
        cn.execute(
            "INSERT INTO entities(id, name, type_ref, status, source, "
            "                     metadata, group_id, "
            "                     created_at, updated_at) "
            "VALUES ('G_nested', 'nested', 'Group', 'active', 'manual', "
            "        '{}', 'G_outer', "
            "        '2026-05-04T11:00:00.000Z', '2026-05-04T11:00:00.000Z')"
        )
        cn.commit()
    finally:
        cn.close()
    out = run_gx(env_dirs, "group", "visual", "G_outer")
    assert out["homogeneous"] is True, out
    assert out["inherited"] == "Url", out
