"""
Abstract base class for map-matching backends.

Defines the three-phase map-matching contract:
  1. trace  -- routing engine execution
  2. snap   -- topological alignment to the network graph
  3. enrich -- attribute projection from raw GPS onto the walk structure
"""

from abc import ABC, abstractmethod
import pandas as pd
from typing import TYPE_CHECKING, List, Optional

if TYPE_CHECKING:
    from ...core.network import Network


class BaseMatcher(ABC):
    """Interface that every map-matching backend must implement."""

    @abstractmethod
    def get_network(self) -> 'Network':
        """Return the walkingpandas Network that backs this matcher.

        The backend owns the single source of truth so the routing engine
        and the topological graph share identical topology.
        """

    @abstractmethod
    def trace(self, chunk_df: pd.DataFrame) -> pd.DataFrame:
        """Phase 1 -- Trace.

        Execute the routing engine on a chunk of GPS observations.

        Args:
            chunk_df: DataFrame with at least ``trip_id``, ``lat``, ``lon``.

        Returns:
            DataFrame with one row per trip containing raw shapes and
            engine-specific edge identifiers.
        """

    @abstractmethod
    def snap(
        self,
        raw_traces: pd.DataFrame,
        network: 'Network',
    ) -> pd.DataFrame:
        """Phase 2 -- Snap.

        Align raw trace geometry to the walkingpandas Network, prune
        overhangs, and reconstruct the discrete topological node path.

        Args:
            raw_traces: Output of :meth:`trace`.
            network: The target walkingpandas Network.

        Returns:
            DataFrame of walk rows (walk_id, sequence_idx, node_id,
            exit_edge).
        """

    @abstractmethod
    def enrich(
        self,
        snapped_df: pd.DataFrame,
        raw_traces: pd.DataFrame,
        node_attributes: Optional[List[str]] = None,
        edge_attributes: Optional[List[str]] = None,
    ) -> pd.DataFrame:
        """Phase 3 -- Enrich.

        Project attributes (e.g. timestamps, speeds) from the original GPS
        observations onto the topological walk structure produced by
        :meth:`snap`.

        Args:
            snapped_df: Output of :meth:`snap`.
            raw_traces: Output of :meth:`trace` (carries original points).
            node_attributes: Attribute names to copy onto each visited node.
            edge_attributes: Attribute names to copy onto each traversed edge.

        Returns:
            The enriched walk DataFrame.
        """
