"""Batch triage workflow — scan and classify files.

Reuses:
    - ``databridge.triage.scan_and_classify(directory, output_dir, ...)``
    - ``databridge.triage.BatchExcelScanner``

IKE integration (optional):
    - P4 Scoring: Calibrate classification confidence via Thompson + SPRT
    - P1 Knowledge Base: Ingest classification results 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 BatchTriageWorkflow(BaseWorkflow):
    """Scan a directory of files and classify them by type and quality.

    When IKE is available, classification results are scored through
    IKE's P4 engine for calibrated confidence, and results are
    ingested into IKE's P1 KB for institutional memory.

    Reuses:
        - ``databridge.triage.scan_and_classify(directory, ...)``
        - ``databridge.triage.BatchExcelScanner``
        - ``databridge.triage.ArchetypeClassifier``
    """

    name = "triage.batch_scan"
    category = "triage"
    description = "Scan and classify a directory of data files"
    required_params = ["directory"]
    optional_params = {
        "output_dir": "data/triage",
        "max_workers": 4,
        "deep_scan": False,
        "ike_scoring": 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._scan(params, ctx)]
        # IKE P4: Score classification results for calibrated confidence
        if params.get("ike_scoring") and ctx and ctx.ike.available:
            steps.append(self._ike_score_classifications(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 Snowflake Task + Stage for recurring file ingestion "
            "with triage classification via Snowpark UDF",
        )

    @workflow_step("scan", "Scan and classify files")
    def _scan(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # REUSE: databridge.triage.scan_and_classify(
        #     directory=params["directory"],
        #     output_dir=params["output_dir"],
        #     max_workers=params["max_workers"],
        #     deep_scan=params["deep_scan"],
        # )
        raise NotImplementedStubError(
            self.name,
            "scan",
            "databridge.triage.scan_and_classify(directory, output_dir, max_workers, deep_scan)",
        )

    @workflow_step("ike_score_classifications", "Score classifications via IKE P4")
    def _ike_score_classifications(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # IKE P4: Batch-score classification results through Thompson
        # Sampling + SPRT + Platt calibration for confidence calibration.
        #
        # ctx.ike.batch_score([
        #     {"bandit_id": f"triage_{archetype}",
        #      "item_id": file_path,
        #      "raw_confidence": classification_confidence}
        #     for file_path, archetype, classification_confidence in scan_results
        # ])
        raise NotImplementedStubError(
            self.name,
            "ike_score_classifications",
            "ctx.ike.batch_score(classifications) — IKE P4 calibrated scoring",
        )

    # --- Graph integration ---

    @workflow_step("graph_record_lineage", "Record file classification nodes in lineage")
    def _graph_record_lineage(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # For each classified file:
        #   ctx.graphs.record_lineage_node("sdk", file_path, "EXTERNAL",
        #       description=f"archetype={archetype}", tags=[archetype])
        raise NotImplementedStubError(
            self.name,
            "graph_record_lineage",
            "ctx.graphs.record_lineage_node — file classification nodes",
        )

    @workflow_step("graph_index_vectors", "Index classifications in vector store")
    def _graph_index_vectors(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # ctx.graphs.index_content(
        #     doc_id=f"triage_{file_hash}", content=classification_summary,
        #     source_type="triage_classification", metadata={...},
        # )
        raise NotImplementedStubError(
            self.name,
            "graph_index_vectors",
            "ctx.graphs.index_content(doc_id, content, 'triage_classification', metadata)",
        )

    @workflow_step("graph_ingest_kb", "Ingest file metadata into KB graph")
    def _graph_ingest_kb(self, params: Dict[str, Any], ctx: Optional[SDKContext] = None):
        # ctx.graphs.ingest_kb_nodes(
        #     nodes=[{"id": file_path, "type": "Table", "properties": {"archetype": ...}}],
        # )
        raise NotImplementedStubError(
            self.name,
            "graph_ingest_kb",
            "ctx.graphs.ingest_kb_nodes(nodes) — file metadata as KB nodes",
        )
