import streamlit as st
import pandas as pd
import psutil
import os
import time
import json
import paho.mqtt.client as mqtt
import requests

def get_system_metrics():
    """Recupera statistiche hardware del server."""
    return {
        "cpu": psutil.cpu_percent(interval=None),
        "ram": psutil.virtual_memory().percent,
        "disk": psutil.disk_usage('/').percent,
        "net_recv": psutil.net_io_counters().bytes_recv / (1024**2)
    }

def get_api_data(cfg, sec):
    """Fetch reale dei beacon dalle API OIDC."""
    if not sec or 'oidc' not in sec:
        return None, "Segreti mancanti"
    try:
        auth_res = requests.post(
            cfg['api']['token_url'],
            data={
                "grant_type": "password",
                "client_id": cfg['api']['client_id'],
                "client_secret": sec['oidc']['client_secret'],
                "username": sec['oidc']['username'],
                "password": sec['oidc']['password'],
            },
            verify=cfg['api'].get('verify_tls', False),
            timeout=5
        )
        token = auth_res.json().get("access_token")
        res = requests.get(
            cfg['api']['get_beacons_url'],
            headers={"Authorization": f"Bearer {token}"},
            verify=cfg['api'].get('verify_tls', False),
            timeout=5
        )
        return res.json(), "OK"
    except Exception as e:
        return None, str(e)

def show_system_status(cfg, sec=None):
    st.title("🛰️ Diagnostica & Sniffer")

    # --- 1. RISORSE DI SISTEMA ---
    st.subheader("🖥️ Risorse Hardware")
    m = get_system_metrics()
    c1, c2, c3, c4 = st.columns(4)
    c1.metric("CPU", f"{m['cpu']}%")
    c2.metric("RAM", f"{m['ram']}%")
    c3.metric("Disco", f"{m['disk']}%")
    c4.metric("Rete", f"{m['net_recv']:.1f} MB")

    st.divider()

    # --- 2. CONNETTIVITÀ & DATI API ---
    st.subheader("🔌 Connettività & API")
    col_api, col_mq = st.columns(2)

    with col_api:
        st.markdown("**Server API OIDC**")
        beacons_api_data, api_msg = get_api_data(cfg, sec)
        if beacons_api_data:
            st.success(f"✅ Connesso ({len(beacons_api_data)} beacon)")
            with st.expander("Visualizza Tabella Dati API"):
                # Mostriamo i dati API in una tabella senza scroll eccessivo
                df_api = pd.DataFrame(beacons_api_data)
                st.table(df_api.head(10)) 
        else:
            st.error(f"❌ Errore: {api_msg}")

    with col_mq:
        st.markdown("**Broker MQTT**")
        mq_host = cfg.get('mqtt', {}).get('host', '127.0.0.1')
        st.info(f"Host: `{mq_host}`")
        st.success("✅ Configurazione Caricata")

    st.divider()

    # --- 3. SNIFFER DATI MQTT ---
    st.subheader("🎯 Sniffer Real-Time")
    st.caption("Inserisci un MAC per intercettare il traffico live (10 secondi)")

    target_mac = st.text_input("MAC da sniffare (es. ac233fc1dd49)", "").lower().replace(":", "")

    if st.button("🚀 AVVIA CATTURA", use_container_width=True, type="primary"):
        if not target_mac:
            st.warning("Inserisci un MAC prima di iniziare.")
        else:
            captured = []
            def on_message(client, userdata, message):
                payload = message.payload.decode()
                topic = message.topic
                if target_mac in topic.lower() or target_mac in payload.lower():
                    captured.append({
                        "Ora": time.strftime("%H:%M:%S"),
                        "Topic": topic,
                        "Dati": payload[:100] + "..." # Accorciamo per la tabella
                    })

            client = mqtt.Client(client_id=f"Sniffer_{int(time.time())}")
            try:
                client.on_message = on_message
                client.connect(cfg['mqtt']['host'], cfg['mqtt']['port'], 60)
                client.subscribe("#")
                client.loop_start()

                with st.status("Cattura in corso...") as status:
                    progress = st.progress(0)
                    for i in range(100):
                        time.sleep(0.1)
                        progress.progress(i + 1)
                    client.loop_stop()
                    status.update(label="Cattura completata!", state="complete")

                if captured:
                    st.success(f"Intercettati {len(captured)} messaggi per `{target_mac}`")
                    # Usiamo st.table per evitare le slidebar (renderizza tutto il contenuto)
                    st.table(pd.DataFrame(captured))
                else:
                    st.warning("Nessun messaggio trovato. Controlla che il dispositivo sia acceso.")
            except Exception as e:
                st.error(f"Connessione fallita: {e}")
