import streamlit as st
import pandas as pd
import os
import json
import shutil
import time
import joblib
from pathlib import Path

def get_campaigns_info(directory: Path):
    """Raggruppa i file per prefisso campagna."""
    if not directory.exists(): return {}
    files = list(directory.glob("*.csv"))
    campaigns = {}
    for f in files:
        parts = f.name.split('_')
        if len(parts) >= 4:
            camp_id = parts[0]
            campaigns.setdefault(camp_id, []).append(str(f))
    return campaigns

def show_training_data_manager(cfg):
    st.subheader("🧠 Console Gestione Modelli e Rilievi")
    
    MODEL_DIR = Path("/data/model")
    JOBS_DIR = Path("/data/train/train_jobs")
    MODEL_DIR.mkdir(parents=True, exist_ok=True)
    JOBS_DIR.mkdir(parents=True, exist_ok=True)

    # --- 1. GESTIONE MODELLI E LINK SIMBOLICO ---
    st.write("### 🎯 Modelli Generati ed Attivazione")
    
    available_models = sorted(
        [m for m in MODEL_DIR.glob("model_camp_*.joblib")], 
        key=os.path.getmtime, 
        reverse=True
    )

    if available_models:
        # Visualizzazione stato attuale link simbolico
        target_path = MODEL_DIR / "model.joblib"
        if target_path.is_symlink():
            try:
                current_link = os.readlink(target_path)
                st.info(f"🔗 **Modello operativo attuale:** `{os.path.basename(current_link)}`")
            except Exception:
                st.warning("⚠️ Impossibile leggere il link simbolico.")
        
        # Tabella modelli esistenti
        m_list = []
        for m in available_models:
            m_list.append({
                "Nome Modello": m.name,
                "Data": time.strftime('%d/%m/%Y %H:%M', time.localtime(m.stat().st_mtime)),
                "Size": f"{round(m.stat().st_size / 1024, 1)} KB"
            })
        st.dataframe(pd.DataFrame(m_list), use_container_width=True, hide_index=True)

        selected_model = st.selectbox("Scegli il modello da analizzare o attivare:", [m.name for m in available_models])
        
        # --- NUOVA SEZIONE: ANALISI TECNICA ---
        with st.expander("🔍 Ispezione Metadati Modello", expanded=False):
            try:
                m_data = joblib.load(MODEL_DIR / selected_model)
                st.write(f"**Data Creazione:** {m_data.get('created_at', 'N/D')}")
                st.write(f"**Gateway allenati:** {len(m_data.get('gateways_order', []))}")
                st.code(", ".join(m_data.get('gateways_order', [])))
                
                floors = list(m_data.get('xy_by_floor', {}).keys())
                st.write(f"**Piani mappati nel regressore:** {floors}")
                
                if not floors or len(m_data.get('gateways_order', [])) == 0:
                    st.error("⚠️ Attenzione: Il modello sembra non contenere dati validi.")
            except Exception as e:
                st.error(f"Errore caricamento per analisi: {e}")

        if st.button("🔗 IMPOSTA COME OPERATIVO (Symlink)", type="primary", use_container_width=True):
            try:
                if target_path.exists() or target_path.is_symlink():
                    target_path.unlink()
                current_dir = os.getcwd()
                os.chdir(str(MODEL_DIR))
                os.symlink(selected_model, "model.joblib")
                os.chdir(current_dir)
                st.success(f"Link aggiornato con successo a {selected_model}")
                time.sleep(1)
                st.rerun()
            except Exception as e:
                st.error(f"Errore: {e}")
    else:
        st.info("Nessun modello disponibile.")

    st.divider()

    # --- 2. ISPEZIONE RILIEVI E NUOVO ADDESTRAMENTO ---
    st.write("### 🚀 Analisi Dati e Nuovo Addestramento")
    
    train_cfg = cfg.get("train", {})
    samples_dir = Path(train_cfg.get("samples_dir", "/data/train/samples"))
    campaigns_map = get_campaigns_info(samples_dir)
    
    if not campaigns_map:
        st.info("Nessun dato di rilievo trovato."); return

    camp_list = sorted(campaigns_map.keys())
    selected_camp = st.radio("Seleziona Campagna:", camp_list, horizontal=True)

    current_files = campaigns_map[selected_camp]
    files_df = pd.DataFrame([
        {"File": os.path.basename(f), "Size": f"{round(os.path.getsize(f)/1024, 1)} KB", "Path": f} 
        for f in current_files
    ]).sort_values("File")
    
    st.dataframe(files_df[["File", "Size"]], use_container_width=True, hide_index=True)

    sel_file = st.selectbox("Ispeziona contenuto file CSV:", ["-- seleziona --"] + files_df["File"].tolist())
    if sel_file != "-- seleziona --":
        f_path = files_df[files_df["File"] == sel_file]["Path"].iloc[0]
        try:
            delim = cfg.get('paths', {}).get('csv_delimiter', ';')
            st.dataframe(pd.read_csv(f_path, sep=delim), use_container_width=True)
        except Exception as e:
            st.error(f"Errore lettura: {e}")

    # Bottone di Addestramento
    pending_jobs = list(JOBS_DIR.glob("*.lock"))
    if pending_jobs:
        st.warning(f"⏳ Addestramento in corso: {pending_jobs[0].name}")
    else:
        if st.button(f"🏋️ AVVIA ADDESTRAMENTO CAMPAGNA {selected_camp}", type="primary", use_container_width=True):
            job_data = {
                "campaign": selected_camp,
                "knn": train_cfg.get("knn", {}),
                "nan_fill": train_cfg.get("nan_fill", -110),
                "gateways_csv": train_cfg.get("gateways_csv", "/data/config/gateway.csv"),
                "timestamp": time.time()
            }
            with open(JOBS_DIR / f"train_{selected_camp}.lock", "w") as f:
                json.dump(job_data, f)
            st.success("Richiesta inviata al Core.")
            time.sleep(1)
            st.rerun()
