"""Build URL × entity-type pivot tables from exported TTL graphs."""

from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
from typing import Any

try:
    from wordlift_sdk.graph.audit import build_entity_matrix as _sdk_build_entity_matrix
except ImportError as _exc:  # pragma: no cover
    raise ImportError(
        "wordlift-sdk>=6.13.0 is required for entity-matrix. "
        "Install it with: pip install 'wordlift-sdk>=6.13.0'"
    ) from _exc


@dataclass
class EntityMatrixOptions:
    filename: str
    exclude_types: list[str] = field(default_factory=list)
    cluster: bool = False
    subgraph_depth: int = 1


def _merge_duplicate_wildcards(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """Merge wildcard rows that share the same URL by summing their counts.

    The SDK's _cluster_rows emits one wildcard row per signature sub-group,
    so a parent with multiple distinct-signature sub-groups each of size ≥ 2
    produces several rows with the same ``parent/*`` URL.  This pass collapses
    them into one row with summed counts, preserving insertion order for the
    first occurrence.
    """
    seen: dict[str, dict[str, Any]] = {}
    order: list[str] = []
    for row in rows:
        url = row["url"]
        if url in seen:
            for k, v in row.items():
                if k != "url":
                    seen[url][k] = seen[url].get(k, 0) + v
        else:
            seen[url] = dict(row)
            order.append(url)
    return [seen[u] for u in order]


def build_entity_matrix(options: EntityMatrixOptions) -> list[dict[str, Any]]:
    """Parse an RDF file and return a URL × entity-type pivot as a list of dicts.

    Delegates to ``wordlift_sdk.graph.audit.build_entity_matrix`` and applies
    a post-processing pass to merge duplicate wildcard rows produced by the SDK
    when a parent path has multiple distinct type-signature sub-groups.

    Each row has a ``url`` key plus one key per entity-type short name found
    anywhere in the URL's subgraph.  Cell values are integer counts (0 when
    the type is absent for that URL).
    """
    if not Path(options.filename).exists():
        raise FileNotFoundError(f"No such file: '{options.filename}'")

    rows = _sdk_build_entity_matrix(
        options.filename,
        exclude_types=options.exclude_types or None,
        cluster=options.cluster,
        subgraph_depth=options.subgraph_depth,
    )

    if options.cluster:
        rows = _merge_duplicate_wildcards(rows)

    return rows
