"""Streamlit entry point for the Cerbero Bite dashboard.

Launch with::

    cerbero-bite gui

or directly::

    uv run streamlit run src/cerbero_bite/gui/main.py \
        --server.address 127.0.0.1 \
        --server.port 8765 \
        --server.headless true

The dashboard is **read-mostly**: it reads SQLite + the audit log and
never imports ``runtime/`` modules. Each Streamlit page is in
``gui/pages/`` and Streamlit auto-discovers them.
"""

from __future__ import annotations

import os
from pathlib import Path

import streamlit as st

from cerbero_bite.gui.data_layer import (
    DEFAULT_AUDIT_PATH,
    DEFAULT_DB_PATH,
    humanize_age,
    humanize_dt,
    load_engine_snapshot,
)

PAGE_TITLE = "Cerbero Bite — Cruscotto"
PAGE_ICON = str(Path(__file__).parent / "assets" / "cerbero_logo.png")


# ---------------------------------------------------------------------------
# Path resolution
# ---------------------------------------------------------------------------


def _resolve_paths() -> tuple[Path, Path]:
    """Read DB / audit paths from env (settable by ``cerbero-bite gui``)."""
    db_path = Path(os.environ.get("CERBERO_BITE_GUI_DB", DEFAULT_DB_PATH))
    audit_path = Path(os.environ.get("CERBERO_BITE_GUI_AUDIT", DEFAULT_AUDIT_PATH))
    return db_path, audit_path


# ---------------------------------------------------------------------------
# Sidebar
# ---------------------------------------------------------------------------


_HEALTH_BADGES: dict[str, tuple[str, str]] = {
    "running": ("🟢", "ATTIVO"),
    "degraded": ("🟡", "DEGRADATO"),
    "killed": ("🔴", "KILL SWITCH"),
    "stopped": ("⚫", "FERMO"),
    "unknown": ("⚪", "SCONOSCIUTO"),
}


def _render_sidebar(db_path: Path, audit_path: Path) -> None:
    snap = load_engine_snapshot(db_path=db_path)
    icon, label = _HEALTH_BADGES.get(snap.health, ("⚪", "SCONOSCIUTO"))

    logo_path = Path(__file__).parent / "assets" / "cerbero_logo.png"
    if logo_path.is_file():
        st.sidebar.image(str(logo_path), use_container_width=True)
    st.sidebar.markdown(f"### {icon} {label}")
    if snap.kill_switch_armed:
        st.sidebar.error(
            f"**Kill switch armato**\n\n"
            f"motivo: {snap.kill_reason or '—'}\n\n"
            f"da: {humanize_dt(snap.kill_at)}"
        )

    st.sidebar.metric(
        "Ultimo health check",
        humanize_age(snap.last_health_check_age_s),
    )
    st.sidebar.metric("Posizioni aperte", snap.open_positions)
    st.sidebar.caption(f"config: `{snap.config_version or '—'}`")

    st.sidebar.divider()
    st.sidebar.caption("Sola lettura • solo localhost")
    st.sidebar.caption(f"db: `{db_path}`")
    st.sidebar.caption(f"audit: `{audit_path}`")


# ---------------------------------------------------------------------------
# Home page
# ---------------------------------------------------------------------------


def main() -> None:
    st.set_page_config(
        page_title=PAGE_TITLE,
        page_icon=PAGE_ICON,
        layout="wide",
        initial_sidebar_state="expanded",
    )

    db_path, audit_path = _resolve_paths()
    _render_sidebar(db_path, audit_path)

    logo_path = Path(__file__).parent / "assets" / "cerbero_logo.png"
    header_cols = st.columns([1, 6])
    if logo_path.is_file():
        header_cols[0].image(str(logo_path), use_container_width=True)
    header_cols[1].title("Cerbero Bite")
    st.caption(
        "Motore rule-based per credit spread su ETH — cruscotto in sola lettura"
    )

    st.markdown(
        """
        Usa la barra laterale per navigare:

        - **Stato** — salute del motore, kill switch, posizioni aperte, ancora audit
        - **Audit** — streaming del registro audit + verifica integrità della catena
        - **Equity** — P&L cumulato, drawdown, distribuzione per chiusura, statistiche mensili
        - **Storico** — trade chiusi con filtri, KPI, esportazione CSV
        - **Posizione** — drilldown sulla singola posizione con grafico payoff

        Il cruscotto legge `data/state.sqlite` e `data/audit.log` direttamente;
        non interroga mai i servizi MCP né il broker. L'unico canale di
        scrittura è la coda `manual_actions` per arm/disarm del kill switch.
        """
    )

    snap = load_engine_snapshot(db_path=db_path)
    cols = st.columns(4)
    cols[0].metric("Salute motore", _HEALTH_BADGES[snap.health][1])
    cols[1].metric(
        "Kill switch",
        "ARMATO" if snap.kill_switch_armed else "DISARMATO",
    )
    cols[2].metric("Posizioni aperte", snap.open_positions)
    cols[3].metric(
        "Ultimo health check",
        humanize_age(snap.last_health_check_age_s),
    )


if __name__ == "__main__":
    main()
