"""Hook plugin for updating the lineage graph."""

from __future__ import annotations

from typing import Any

from phlo.hooks import LineageEvent
from phlo.logging import get_logger
from phlo.plugins.base import PluginMetadata
from phlo.plugins.hooks import HookFilter, HookPlugin, HookRegistration

from phlo_lineage.graph import get_lineage_graph
from phlo_lineage.store import LineageStore, resolve_lineage_db_url_with_postgres_fallback

logger = get_logger(__name__)


class LineageHookPlugin(HookPlugin):
    """Update the lineage graph from lineage hook events."""

    @property
    def metadata(self) -> PluginMetadata:
        """Metadata for the lineage hook plugin."""

        return PluginMetadata(
            name="lineage",
            version="0.1.0",
            description="Hook handlers for lineage updates",
        )

    def get_hooks(self) -> list[HookRegistration]:
        """Register the lineage update hook handler."""

        return [
            HookRegistration(
                hook_name="lineage_updates",
                handler=self._handle_lineage,
                filters=HookFilter(event_types={"lineage.edges"}),
            )
        ]

    def _handle_lineage(self, event: Any) -> None:
        """Apply lineage edges to the graph store."""

        if not isinstance(event, LineageEvent):
            return
        edge_count = len(event.edges)
        asset_key_count = len(event.asset_keys or [])
        graph = get_lineage_graph()
        for source, target in event.edges:
            graph.add_edge(source, target)

        connection_string = resolve_lineage_db_url_with_postgres_fallback()
        if not connection_string:
            logger.info(
                "lineage_sync_skipped_missing_db_url",
                event_type=event.event_type,
                edge_count=edge_count,
                asset_key_count=asset_key_count,
            )
            return

        logger.info(
            "lineage_sync_started",
            event_type=event.event_type,
            edge_count=edge_count,
            asset_key_count=asset_key_count,
        )
        try:
            store = LineageStore(connection_string)
            persisted_edges = store.record_asset_edges(
                event.edges,
                asset_keys=event.asset_keys,
                metadata=event.metadata,
                tags=event.tags,
            )
            logger.info(
                "lineage_sync_succeeded",
                event_type=event.event_type,
                edge_count=edge_count,
                asset_key_count=asset_key_count,
                persisted_edge_count=persisted_edges,
            )
        except Exception as exc:
            logger.warning(
                "Failed to persist asset lineage edges: %s",
                exc,
                event_type=event.event_type,
                edge_count=edge_count,
                asset_key_count=asset_key_count,
            )
