"""Static topology (DAG) for the E2E assessment pipeline.

Defines 22 phases as nodes with tier-based layout and dependency edges.
Used by WorkflowController.get_graph() to merge live status onto the DAG.

Also provides WORKFLOW_HIERARCHY for the vis.js Bloom-style graph with
collapsible groups, phases, tools, and parameters.

plan_to_topology() converts a PlannerAgent WorkflowPlan into the same
format so plan-generated workflows render in the Flow and Flowchart tabs.
"""

from __future__ import annotations

from typing import Any, Dict, List

# ── Hierarchical Graph Data (vis.js Bloom-style) ────────────────────

WORKFLOW_HIERARCHY = {
    "project": {
        "id": "project_root",
        "label": "E2E Assessment Pipeline",
        "type": "project",
    },
    "groups": [
        {
            "id": "grp_discovery",
            "label": "Discovery",
            "color": "#38bdf8",
            "phases": [
                {
                    "id": "load_metadata",
                    "label": "Load Metadata",
                    "tools": [
                        {
                            "id": "tool_discover_data_model",
                            "label": "_discover_data_model()",
                            "module": "src.data_modeling.mcp_adapter",
                            "params": [
                                "source_type", "database", "schema", "tables",
                                "sample_limit", "min_overlap", "snowflake_connection",
                                "return_samples", "sf_connection",
                            ],
                        },
                    ],
                },
                {
                    "id": "ai_relationship_discovery",
                    "label": "AI Relationships",
                    "tools": [
                        {
                            "id": "tool_ai_schema_analysis",
                            "label": "analyze_schema_for_orchestrator()",
                            "module": "src.ai_relationship_discovery.plugin",
                            "params": [
                                "sf_client", "database", "schema", "model",
                            ],
                        },
                    ],
                },
                {
                    "id": "group_tables",
                    "label": "Group Tables",
                    "tools": [
                        {
                            "id": "tool_prefix_grouping",
                            "label": "PrefixGroupingStrategy.group()",
                            "module": "src.data_modeling.grouping",
                            "params": ["erp"],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_classification",
            "label": "Classification",
            "color": "#818cf8",
            "phases": [
                {
                    "id": "hierarchy",
                    "label": "Hierarchy",
                    "tools": [
                        {
                            "id": "tool_create_hierarchy",
                            "label": "create_hierarchy()",
                            "module": "src.hierarchy.builder",
                            "params": ["project_id", "hierarchy_name"],
                        },
                        {
                            "id": "tool_import_hierarchy",
                            "label": "import_flexible_hierarchy()",
                            "module": "src.hierarchy.builder",
                            "params": ["file_path", "project_id", "format"],
                        },
                    ],
                },
                {
                    "id": "ai_classify",
                    "label": "AI Classify",
                    "tools": [
                        {
                            "id": "tool_auto_classify",
                            "label": "auto_classify_columns()",
                            "module": "src.ai_relationship_discovery.datashield",
                            "params": ["cols", "sample_data", "row_count"],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_modeling",
            "label": "Modeling",
            "color": "#2dd4bf",
            "phases": [
                {
                    "id": "detect_dimensions",
                    "label": "Detect Dimensions",
                    "tools": [
                        {
                            "id": "tool_dim_classify",
                            "label": "DimensionDetector.classify_tables()",
                            "module": "src.data_modeling.dimension_detector",
                            "params": ["rels", "threshold", "table_columns", "erp_type"],
                        },
                        {
                            "id": "tool_table_analyzer",
                            "label": "TableAnalyzer.analyze_all()",
                            "module": "src.data_modeling.table_analyzer",
                            "params": ["table_names"],
                        },
                    ],
                },
                {
                    "id": "bus_matrix",
                    "label": "Bus Matrix",
                    "tools": [
                        {
                            "id": "tool_bus_matrix_gen",
                            "label": "BusMatrixGenerator.generate()",
                            "module": "src.data_modeling.bus_matrix",
                            "params": ["rels", "classification"],
                        },
                    ],
                },
                {
                    "id": "dm_spec_generate",
                    "label": "DM Spec Generate",
                    "tools": [
                        {
                            "id": "tool_dm_spec",
                            "label": "DMSpecGenerator.generate()",
                            "module": "src.data_modeling.dm_spec",
                            "params": [
                                "erp", "relationships", "classification", "run_id",
                            ],
                        },
                    ],
                },
                {
                    "id": "dm_load",
                    "label": "DM Load",
                    "tools": [
                        {
                            "id": "tool_dm_loader",
                            "label": "GenericDMLoader.load()",
                            "module": "src.data_modeling.dm_loader",
                            "params": [
                                "specs", "parallel", "dim_limit", "txn_limit", "txn_where",
                            ],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_quality",
            "label": "Quality",
            "color": "#facc15",
            "phases": [
                {
                    "id": "quality",
                    "label": "Quality",
                    "tools": [
                        {
                            "id": "tool_quality_suite",
                            "label": "ClassificationExpectationBridge.generate_suite()",
                            "module": "src.data_quality.expectations",
                            "params": [
                                "suite_name", "classifications", "table_name",
                                "database", "schema_name",
                            ],
                        },
                    ],
                },
                {
                    "id": "quality_from_classification",
                    "label": "Quality from Class.",
                    "tools": [
                        {
                            "id": "tool_quality_from_class",
                            "label": "ClassificationExpectationBridge.generate_suite()",
                            "module": "src.data_quality.expectations",
                            "params": [
                                "suite_name", "classifications", "table_name",
                            ],
                        },
                    ],
                },
                {
                    "id": "observability",
                    "label": "Observability",
                    "tools": [
                        {
                            "id": "tool_obs_record",
                            "label": "obs_record_metric()",
                            "module": "src.observability.metrics",
                            "params": ["metric_name", "value", "tags"],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_output",
            "label": "Output",
            "color": "#4ade80",
            "phases": [
                {
                    "id": "artifact_bundle",
                    "label": "Artifact Bundle",
                    "tools": [
                        {
                            "id": "tool_report_gen",
                            "label": "ReportGenerator.from_run_result()",
                            "module": "src.workflows.report_generator",
                            "params": ["run_id", "output_dir"],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_integration",
            "label": "Integration",
            "color": "#a78bfa",
            "phases": [
                {
                    "id": "graph_sync",
                    "label": "Graph Sync",
                    "tools": [
                        {
                            "id": "tool_kb_ingest",
                            "label": "KBIngestionPipeline.ingest_graph()",
                            "module": "src.codex_graphrag.ingestion",
                            "params": ["nodes", "edges"],
                        },
                    ],
                },
                {
                    "id": "wright",
                    "label": "Wright Pipelines",
                    "tools": [
                        {
                            "id": "tool_wright_from_hierarchy",
                            "label": "wright_from_hierarchy()",
                            "module": "src.wright.generator",
                            "params": ["hierarchy_project_id"],
                        },
                    ],
                },
                {
                    "id": "dbt",
                    "label": "dbt Scaffold",
                    "tools": [
                        {
                            "id": "tool_dbt_project",
                            "label": "create_dbt_project()",
                            "module": "src.dbt.generator",
                            "params": ["dbt_project_name", "dbt_run", "dbt_docs"],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_enterprise",
            "label": "Enterprise",
            "color": "#60a5fa",
            "phases": [
                {
                    "id": "enterprise_grain_analysis",
                    "label": "Grain Analysis",
                    "tools": [
                        {
                            "id": "tool_grain_analyzer",
                            "label": "GrainAnalyzer.register_system()",
                            "module": "src.enterprise.grain",
                            "params": ["system_name", "tables"],
                        },
                    ],
                },
                {
                    "id": "enterprise_dim_master",
                    "label": "Dim Master",
                    "tools": [
                        {
                            "id": "tool_conformed_dim",
                            "label": "ConformedDimMaster.detect_conformed()",
                            "module": "src.enterprise.conformed",
                            "params": ["conformed_dim", "system_data", "strategy"],
                        },
                    ],
                },
                {
                    "id": "enterprise_consolidation",
                    "label": "Consolidation",
                    "tools": [
                        {
                            "id": "tool_fact_harmonizer",
                            "label": "FactHarmonizer.align_facts()",
                            "module": "src.enterprise.harmonizer",
                            "params": ["grain_analysis", "dim_master", "dest_db", "dest_schema"],
                        },
                    ],
                },
            ],
        },
        {
            "id": "grp_parity",
            "label": "Parity",
            "color": "#f472b6",
            "phases": [
                {
                    "id": "report_parity_compile",
                    "label": "Parity Compile",
                    "tools": [
                        {
                            "id": "tool_spec_compiler",
                            "label": "ReportSpecCompiler.compile()",
                            "module": "src.report_parity.compiler",
                            "params": ["report_specs_json", "report_analyses", "blce_ctx"],
                        },
                    ],
                },
                {
                    "id": "report_parity_validate",
                    "label": "Parity Validate",
                    "tools": [
                        {
                            "id": "tool_progressive_runner",
                            "label": "ProgressiveRunner.run_progressive()",
                            "module": "src.report_parity.runner",
                            "params": ["spec", "all_actual_values", "tolerance_pct"],
                        },
                    ],
                },
                {
                    "id": "report_parity_certificate",
                    "label": "Parity Certificate",
                    "tools": [
                        {
                            "id": "tool_parity_cert",
                            "label": "ParityCertificate.generate()",
                            "module": "src.report_parity.certificate",
                            "params": ["state"],
                        },
                    ],
                },
            ],
        },
    ],
}


# ── Flat DAG topology (backward compat — used by get_graph()) ───────

WORKFLOW_TOPOLOGY = {
    "nodes": [
        {"id": "load_metadata",              "label": "Load Metadata",       "tier": 0, "group": "discovery"},
        {"id": "ai_relationship_discovery",  "label": "AI Relationships",    "tier": 1, "group": "discovery"},
        {"id": "group_tables",               "label": "Group Tables",        "tier": 1, "group": "discovery"},
        {"id": "hierarchy",                  "label": "Hierarchy",           "tier": 1, "group": "discovery"},
        {"id": "ai_classify",                "label": "AI Classify",         "tier": 1, "group": "classification"},
        {"id": "detect_dimensions",          "label": "Detect Dimensions",   "tier": 2, "group": "classification"},
        {"id": "wright",                     "label": "Wright Pipelines",    "tier": 3, "group": "modeling"},
        {"id": "dbt",                        "label": "dbt Scaffold",        "tier": 3, "group": "modeling"},
        {"id": "quality",                    "label": "Quality",             "tier": 3, "group": "quality"},
        {"id": "observability",              "label": "Observability",       "tier": 4, "group": "quality"},
        {"id": "artifact_bundle",            "label": "Artifact Bundle",     "tier": 5, "group": "output"},
        {"id": "bus_matrix",                 "label": "Bus Matrix",          "tier": 3, "group": "modeling"},
        {"id": "dm_spec_generate",           "label": "DM Spec Generate",   "tier": 4, "group": "modeling"},
        {"id": "dm_load",                    "label": "DM Load",            "tier": 5, "group": "modeling"},
        {"id": "quality_from_classification","label": "Quality from Class.", "tier": 3, "group": "quality"},
        {"id": "graph_sync",                 "label": "Graph Sync",         "tier": 3, "group": "integration"},
        {"id": "enterprise_grain_analysis",  "label": "Grain Analysis",     "tier": 6, "group": "enterprise"},
        {"id": "enterprise_dim_master",      "label": "Dim Master",         "tier": 6, "group": "enterprise"},
        {"id": "enterprise_consolidation",   "label": "Consolidation",      "tier": 7, "group": "enterprise"},
        {"id": "report_parity_compile",      "label": "Parity Compile",     "tier": 6, "group": "parity"},
        {"id": "report_parity_validate",     "label": "Parity Validate",    "tier": 7, "group": "parity"},
        {"id": "report_parity_certificate",  "label": "Parity Certificate", "tier": 8, "group": "parity"},
    ],
    "edges": [
        {"source": "load_metadata", "target": "ai_relationship_discovery"},
        {"source": "load_metadata", "target": "group_tables"},
        {"source": "load_metadata", "target": "hierarchy"},
        {"source": "load_metadata", "target": "ai_classify"},
        {"source": "load_metadata", "target": "detect_dimensions"},
        {"source": "ai_relationship_discovery", "target": "detect_dimensions"},
        {"source": "detect_dimensions", "target": "wright"},
        {"source": "detect_dimensions", "target": "dbt"},
        {"source": "detect_dimensions", "target": "quality"},
        {"source": "detect_dimensions", "target": "bus_matrix"},
        {"source": "detect_dimensions", "target": "quality_from_classification"},
        {"source": "detect_dimensions", "target": "graph_sync"},
        {"source": "ai_classify", "target": "quality_from_classification"},
        {"source": "quality", "target": "observability"},
        {"source": "observability", "target": "artifact_bundle"},
        {"source": "bus_matrix", "target": "dm_spec_generate"},
        {"source": "dm_spec_generate", "target": "dm_load"},
        {"source": "dm_load", "target": "enterprise_grain_analysis"},
        {"source": "detect_dimensions", "target": "enterprise_grain_analysis"},
        {"source": "detect_dimensions", "target": "enterprise_dim_master"},
        {"source": "enterprise_grain_analysis", "target": "enterprise_consolidation"},
        {"source": "enterprise_dim_master", "target": "enterprise_consolidation"},
        {"source": "report_parity_compile", "target": "report_parity_validate"},
        {"source": "report_parity_validate", "target": "report_parity_certificate"},
    ],
}


# ── Agent type → group/color mapping for plan-generated topologies ────

_AGENT_TYPE_GROUPS: Dict[str, Dict[str, str]] = {
    "SchemaScanner":     {"group": "discovery",       "color": "#38bdf8"},
    "LogicExtractor":    {"group": "discovery",       "color": "#38bdf8"},
    "WarehouseArchitect":{"group": "modeling",        "color": "#2dd4bf"},
    "DeployValidator":   {"group": "integration",     "color": "#a78bfa"},
    "HierarchyBuilder":  {"group": "classification",  "color": "#818cf8"},
    "DataReconciler":    {"group": "quality",         "color": "#facc15"},
    "BookManipulator":   {"group": "integration",     "color": "#a78bfa"},
    "LibrarianSync":     {"group": "integration",     "color": "#a78bfa"},
    "ResearcherAnalyst": {"group": "quality",         "color": "#facc15"},
    "CortexAgent":       {"group": "enterprise",      "color": "#60a5fa"},
    "SkillAgent":        {"group": "skills",          "color": "#4ade80"},
    "LangGraphAgent":    {"group": "enterprise",      "color": "#60a5fa"},
    "DomainToolAgent":   {"group": "integration",     "color": "#a78bfa"},
}

_DEFAULT_GROUP = {"group": "custom", "color": "#94a3b8"}


def plan_to_topology(plan_dict: Dict[str, Any]) -> Dict[str, Any]:
    """Convert a PlannerAgent plan dict to WORKFLOW_TOPOLOGY format.

    Args:
        plan_dict: The plan as returned by WorkflowPlan.to_dict(), with keys
                   'name', 'description', 'steps' (list of step dicts).

    Returns:
        Dict with 'nodes' and 'edges' lists in the same shape as
        WORKFLOW_TOPOLOGY, plus 'plan_id' and 'plan_name' metadata.
    """
    steps = plan_dict.get("steps", [])
    if not steps:
        return {"nodes": [], "edges": [], "plan_id": plan_dict.get("id", ""), "plan_name": plan_dict.get("name", "")}

    # Compute tiers from dependency graph (topological order)
    step_ids = {s["id"] for s in steps}
    tier_map: Dict[str, int] = {}
    for step in steps:
        deps = [d for d in step.get("depends_on", []) if d in step_ids]
        if not deps:
            tier_map[step["id"]] = 0
        else:
            tier_map[step["id"]] = max(tier_map.get(d, 0) for d in deps) + 1

    nodes: List[Dict[str, Any]] = []
    edges: List[Dict[str, Any]] = []

    for step in steps:
        agent_type = step.get("agent_type", "")
        ginfo = _AGENT_TYPE_GROUPS.get(agent_type, _DEFAULT_GROUP)

        nodes.append({
            "id": step["id"],
            "label": step.get("name", step["id"]),
            "tier": tier_map.get(step["id"], 0),
            "group": ginfo["group"],
            "color": ginfo["color"],
            "agent_type": agent_type,
            "capability": step.get("capability", ""),
            "description": step.get("description", ""),
            "reasoning": step.get("reasoning", ""),
            "config": step.get("config", {}),
        })

        for dep_id in step.get("depends_on", []):
            if dep_id in step_ids:
                edges.append({"source": dep_id, "target": step["id"]})

    return {
        "nodes": nodes,
        "edges": edges,
        "plan_id": plan_dict.get("id", ""),
        "plan_name": plan_dict.get("name", ""),
        "plan_description": plan_dict.get("description", ""),
        "step_count": len(steps),
    }


def plan_to_hierarchy(plan_dict: Dict[str, Any]) -> Dict[str, Any]:
    """Convert a PlannerAgent plan dict to WORKFLOW_HIERARCHY format.

    Produces a Bloom-style hierarchy with the plan as project, agent-type
    groups, and individual steps as phases with their config as params.

    Args:
        plan_dict: The plan as returned by WorkflowPlan.to_dict().

    Returns:
        Dict in the same shape as WORKFLOW_HIERARCHY.
    """
    steps = plan_dict.get("steps", [])
    plan_name = plan_dict.get("name", "Custom Workflow")
    plan_id = plan_dict.get("id", "plan")

    # Group steps by agent_type
    groups_map: Dict[str, List[Dict[str, Any]]] = {}
    for step in steps:
        agent_type = step.get("agent_type", "unknown")
        groups_map.setdefault(agent_type, []).append(step)

    groups: List[Dict[str, Any]] = []
    for agent_type, group_steps in groups_map.items():
        ginfo = _AGENT_TYPE_GROUPS.get(agent_type, _DEFAULT_GROUP)

        phases = []
        for step in group_steps:
            # Build tool entry from the step
            tool = {
                "id": f"tool_{step['id']}",
                "label": f"{step.get('capability', step['id'])}()",
                "module": agent_type,
                "params": list(step.get("input_mapping", {}).keys())
                          + list(step.get("config", {}).keys()),
            }

            phases.append({
                "id": step["id"],
                "label": step.get("name", step["id"]),
                "tools": [tool],
            })

        groups.append({
            "id": f"grp_{agent_type.lower().replace(' ', '_')}",
            "label": agent_type.replace("Agent", "").replace("_", " ").strip().title(),
            "color": ginfo["color"],
            "phases": phases,
        })

    return {
        "project": {
            "id": f"plan_{plan_id}",
            "label": plan_name,
            "type": "project",
        },
        "groups": groups,
    }
