"""NEUROVAULT Brain Visualizer dashboard."""

from __future__ import annotations

import json
from pathlib import Path

try:
    import streamlit as st

    HAS_DASHBOARD_DEPS = True
except Exception:  # pragma: no cover
    HAS_DASHBOARD_DEPS = False

from neurovault.engine import NeurovaultEngine


def check_deps() -> None:
    if not HAS_DASHBOARD_DEPS:
        raise ImportError(
            "Dashboard requires streamlit. Install: pip install neurovault[dashboard]"
        )


def run_dashboard(vault_name: str = "default") -> None:
    """Launch the NEUROVAULT dashboard."""
    check_deps()

    st.set_page_config(page_title="NEUROVAULT", page_icon="🧠", layout="wide")

    st.sidebar.title("🧠 NEUROVAULT")
    page = st.sidebar.radio(
        "Navigate",
        ["Brain Overview", "Knowledge Graph", "Memory Timeline", "Consolidation", "Sensors & Plugins"],
    )

    engine = _get_engine(vault_name)

    if page == "Brain Overview":
        render_overview(engine)
    elif page == "Knowledge Graph":
        render_knowledge_graph(engine)
    elif page == "Memory Timeline":
        render_timeline(engine)
    elif page == "Consolidation":
        render_consolidation(engine)
    elif page == "Sensors & Plugins":
        render_sensors(engine)


if HAS_DASHBOARD_DEPS:

    @st.cache_resource  # type: ignore[misc]
    def _get_engine(vault_name: str):
        return NeurovaultEngine.open(vault_name)

else:

    def _get_engine(vault_name: str):
        return NeurovaultEngine.open(vault_name)


def render_overview(engine: NeurovaultEngine) -> None:
    st.title("🧠 Brain Overview")
    stats = engine.stats()

    c1, c2, c3, c4 = st.columns(4)
    c1.metric("Memories", stats.get("memory_count", 0))
    c2.metric("Entities", stats.get("entity_count", 0))
    c3.metric("Relationships", stats.get("relationship_count", 0))
    c4.metric("Concepts", stats.get("concept_count", 0))

    st.subheader("Memory Tier Distribution")
    tiers = stats.get("tier_distribution", {})
    if tiers:
        st.bar_chart(tiers)

    st.subheader("Memory Sources")
    sources = stats.get("source_distribution", {})
    if sources:
        st.bar_chart(sources)


def render_knowledge_graph(engine: NeurovaultEngine) -> None:
    st.title("🔗 Knowledge Graph")

    entity_name = st.text_input("Entity", value="python")
    depth = st.slider("Depth", min_value=1, max_value=5, value=2)

    if not entity_name:
        return

    graph = engine.get_entity_graph(entity_name, depth=depth)
    if graph is None:
        st.info("No graph found for this entity.")
        return

    st.write({
        "root": graph.root_entity.name,
        "nodes": [n.name for n in graph.nodes],
        "relationships": len(graph.relationships),
    })


def render_timeline(engine: NeurovaultEngine) -> None:
    st.title("📅 Memory Timeline")

    query = st.text_input("Search", value="")
    limit = st.slider("Limit", min_value=5, max_value=50, value=20)
    mode = st.selectbox("Mode", ["keyword", "semantic", "graph", "multi"], index=3)

    results = engine.recall(query, limit=limit, mode=mode)
    for item in results:
        st.markdown(f"- **[{item.memory.source}]** {item.memory.content[:140]}")


def render_consolidation(engine: NeurovaultEngine) -> None:
    st.title("⚡ Consolidation")

    phases = st.multiselect(
        "Phases",
        ["entities", "llm_relations", "clusters", "insights", "promote", "decay", "calibrate"],
        default=["entities", "clusters", "insights", "promote", "decay"],
    )

    if st.button("Run Consolidation"):
        report = engine.consolidate(force=True, phases=phases)
        st.success(f"Consolidation finished in {report.duration_seconds:.2f}s")
        st.json(
            {
                "entities_extracted": report.entities_extracted,
                "relationships_found": report.relationships_found,
                "clusters_formed": report.clusters_formed,
                "insights_generated": report.insights_generated,
                "memories_promoted": report.memories_promoted,
                "memories_decayed": report.memories_decayed,
                "memories_archived": report.memories_archived,
            }
        )


def render_sensors(engine: NeurovaultEngine) -> None:
    st.title("🔌 Sensors & Plugins")

    st.subheader("Sensors")
    st.json(engine.sensor_status())

    st.subheader("Plugins")
    st.json(engine.plugin_status())

    st.subheader("Pipeline")
    st.json(engine.pipeline_stats())


def main() -> None:
    import sys

    vault = sys.argv[1] if len(sys.argv) > 1 else "default"
    run_dashboard(vault)


if __name__ == "__main__":
    main()
