"""Data catalog workflow — asset registration and lineage.

Reuses:
    - ``databridge.catalog.catalog_asset(name, asset_type, ...)``
    - ``databridge.catalog.list_assets(asset_type, database, tag)``
    - ``databridge.catalog.catalog_lineage(...)``

IKE integration (optional):
    - P1 Knowledge Base: Ingest catalog entries into IKE for institutional memory
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from databridge_core.sdk.core.context import SDKContext
from databridge_core.sdk.core.exceptions import NotImplementedStubError
from databridge_core.sdk.core.types import CompiledArtifact, Result
from databridge_core.sdk.workflows.base import BaseWorkflow
from databridge_core.sdk.workflows.result import WorkflowResult
from databridge_core.sdk.workflows.step import workflow_step


class CatalogWorkflow(BaseWorkflow):
    """Register and query data catalog assets with lineage tracking.

    When IKE is available, registered assets are also ingested into
    IKE's P1 knowledge base for cross-tenant institutional memory.

    Reuses:
        - ``databridge.catalog.catalog_asset(name, asset_type, ...)``
        - ``databridge.catalog.list_assets(...)``
        - ``databridge.catalog.catalog_lineage(...)``
        - ``databridge.catalog.get_lineage(...)``
    """

    name = "knowledge_base.catalog"
    category = "knowledge_base"
    description = "Register data catalog assets and track lineage"
    required_params = ["name"]
    optional_params = {
        "asset_type": "table",
        "database": None,
        "schema_name": None,
        "description": None,
        "tags": [],
        "owner": None,
        "ike_ingest": True,
    }

    def validate(self, params: Dict[str, Any]) -> Dict[str, Any]:
        self._check_required(params)
        return self._apply_defaults(params)

    def execute(
        self, params: Dict[str, Any], ctx: Optional[SDKContext] = None
    ) -> Result:
        steps = [self._register(params, ctx)]
        # IKE P1: Ingest catalog entry into institutional KB
        if params.get("ike_ingest") and ctx and ctx.ike.available:
            steps.append(self._ike_ingest_asset(params, ctx))
        # Graph integration
        if ctx and ctx.graphs.available:
            steps.append(self._graph_record_lineage(params, ctx))
            steps.append(self._graph_index_vectors(params, ctx))
            steps.append(self._graph_ingest_kb(params, ctx))
        return WorkflowResult.from_steps(self.name, steps)

    def compile_to_snowflake(
        self, params: Dict[str, Any], ctx: Optional[SDKContext] = None
    ) -> List[CompiledArtifact]:
        raise NotImplementedStubError(
            self.name,
            "compile_to_snowflake",
            "Generate COMMENT ON TABLE/VIEW for Snowflake catalog metadata, "
            "or TAG-based governance objects",
        )

    @workflow_step("register", "Register asset in catalog")
    def _register(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # REUSE: databridge.catalog.catalog_asset(
        #     name=params["name"],
        #     asset_type=params.get("asset_type", "table"),
        #     database=params.get("database"),
        #     schema_name=params.get("schema_name"),
        #     description=params.get("description"),
        #     tags=params.get("tags", []),
        #     owner=params.get("owner"),
        # )
        raise NotImplementedStubError(
            self.name,
            "register",
            "databridge.catalog.catalog_asset(name, asset_type, database, schema_name, ...)",
        )

    @workflow_step("ike_ingest_asset", "Ingest asset into IKE knowledge base")
    def _ike_ingest_asset(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # IKE P1: Ingest the registered catalog asset into IKE's
        # knowledge base for institutional memory and cross-tenant search.
        #
        # ctx.ike.ingest_knowledge(
        #     content=f"Catalog asset: {params['name']} ({params['asset_type']})",
        #     source_type="correction",
        #     tags=params.get("tags", []) + ["catalog"],
        # )
        raise NotImplementedStubError(
            self.name,
            "ike_ingest_asset",
            "ctx.ike.ingest_knowledge(content, source_type='correction', tags) — IKE P1 KB ingest",
        )

    # --- Graph integration ---

    @workflow_step("graph_record_lineage", "Record TABLE/COLUMN/SCHEMA nodes in lineage")
    def _graph_record_lineage(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # ctx.graphs.record_lineage_node("sdk", params["name"],
        #     params.get("asset_type", "TABLE").upper(),
        #     database=params.get("database"), schema_name=params.get("schema_name"),
        #     description=params.get("description"), tags=params.get("tags", []))
        raise NotImplementedStubError(
            self.name,
            "graph_record_lineage",
            "ctx.graphs.record_lineage_node — TABLE/COLUMN/SCHEMA from catalog registration",
        )

    @workflow_step("graph_index_vectors", "Index catalog asset in vector store")
    def _graph_index_vectors(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # ctx.graphs.index_content(
        #     doc_id=f"catalog_{params['name']}", content=asset_description,
        #     source_type="catalog_asset", metadata={"asset_type": ..., "database": ...},
        # )
        raise NotImplementedStubError(
            self.name,
            "graph_index_vectors",
            "ctx.graphs.index_content(doc_id, content, 'catalog_asset', metadata)",
        )

    @workflow_step("graph_ingest_kb", "Ingest catalog asset into KB graph")
    def _graph_ingest_kb(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # ctx.graphs.ingest_kb_nodes(
        #     nodes=[{"id": params["name"], "type": params.get("asset_type", "Table"),
        #             "properties": {"database": ..., "schema": ...}}],
        # )
        raise NotImplementedStubError(
            self.name,
            "graph_ingest_kb",
            "ctx.graphs.ingest_kb_nodes(nodes) — catalog asset as KB node",
        )
