"""
AR-House — Location Intelligence
=================================
Página Streamlit para análisis de ubicación con score 0-100.
"""

from __future__ import annotations

import sys
from pathlib import Path

import streamlit as st

_ROOT = Path(__file__).resolve().parent.parent
if str(_ROOT) not in sys.path:
    sys.path.insert(0, str(_ROOT))

from location_agent import run_location_agent
from location_agent.db import list_reports, get_report
from location_agent.utils.ollama_client import is_available as ollama_ok

# ── Config ────────────────────────────────────────────────────────────────────
st.set_page_config(
    page_title="AR-House · Location Intelligence",
    page_icon="🏠",
    layout="wide",
)

st.markdown("""
<style>
.score-badge {
    font-size: 3rem; font-weight: 800; text-align: center;
    padding: 0.5rem 1.5rem; border-radius: 12px;
    display: inline-block; margin: 0 auto;
}
.score-high   { background: #d4edda; color: #155724; }
.score-medium { background: #fff3cd; color: #856404; }
.score-low    { background: #f8d7da; color: #721c24; }
</style>
""", unsafe_allow_html=True)


# ── Helpers ──────────────────────────────────────────────────────────────────
def score_badge(score: int) -> str:
    cls = "score-high" if score >= 75 else ("score-medium" if score >= 50 else "score-low")
    return f'<div class="score-badge {cls}">{score}/100</div>'


def score_color(score: int) -> str:
    return "green" if score >= 75 else ("orange" if score >= 50 else "red")


def render_section_data(key: str, sec: dict) -> None:
    """Renderiza los datos clave de cada sección."""
    if key == "crime":
        st.metric("Crímenes (30 días)", sec.get("total_crimes_30d", "N/A"))
        st.metric("Crimen violento", "Sí ⚠️" if sec.get("has_violent") else "No ✅")
        types = sec.get("crime_types", {})
        if types:
            st.markdown("**Tipos de crimen:**")
            for t, n in list(types.items())[:6]:
                st.markdown(f"• {t}: {n}")

    elif key == "property":
        mlp = sec.get("median_list_price")
        ppsf = sec.get("price_per_sqft")
        dom  = sec.get("days_on_market")
        inv  = sec.get("inventory")
        if mlp:  st.metric("Precio mediano listado", f"${mlp:,}")
        if ppsf: st.metric("Precio por sqft", f"${ppsf:,}")
        if dom:  st.metric("Días en mercado (prom.)", dom)
        if inv:  st.metric("Inventario activo", inv)
        cav = sec.get("county_assessed_value")
        if cav:  st.metric("Valor tasado condado", f"${cav:,}")

    elif key == "schools":
        avg = sec.get("avg_rating")
        if avg:
            st.metric("Rating promedio", f"{avg}/10")
        for level, label in [("best_elementary", "Mejor Primaria"),
                              ("best_middle",     "Mejor Middle"),
                              ("best_high",       "Mejor High School")]:
            school = sec.get(level)
            if school:
                st.markdown(
                    f"**{label}:** {school.get('name', 'N/A')} "
                    f"({school.get('rating', '?')}/10)"
                )
        schools = sec.get("schools", [])[:6]
        if schools:
            st.table({
                "Escuela": [s.get("name", "")[:30] for s in schools],
                "Nivel":   [s.get("level", "")     for s in schools],
                "Rating":  [str(s.get("rating", "N/A")) for s in schools],
            })

    elif key == "amenities":
        ws = sec.get("walk_score")
        if ws is not None:
            st.metric("Walk Score estimado", f"{ws}/100")
        nearest = sec.get("nearest", {})
        for cat, label in [("supermarket", "🛒 Supermercado"),
                            ("hospital",    "🏥 Hospital"),
                            ("restaurant",  "🍽️ Restaurante"),
                            ("park",        "🌳 Parque")]:
            item = nearest.get(cat)
            if item:
                st.markdown(
                    f"**{label}:** {item.get('name', 'N/A')} "
                    f"— {item.get('dist_miles', '?')} mi"
                )

    elif key == "demographics":
        inc   = sec.get("median_household_income")
        age   = sec.get("median_age")
        unemp = sec.get("unemployment_rate")
        edu   = sec.get("education_bachelors_pct")
        pop   = sec.get("total_population")
        if inc:   st.metric("Ingreso mediano del hogar", f"${inc:,}/año")
        if age:   st.metric("Edad mediana", f"{age} años")
        if unemp is not None: st.metric("Tasa de desempleo", f"{unemp}%")
        if edu  is not None:  st.metric("Con título universitario", f"{edu}%")
        if pop:   st.metric("Población", f"{pop:,}")
        eth = sec.get("ethnicity", {})
        if eth:
            st.markdown("**Distribución étnica:**")
            for k, v in eth.items():
                label = k.replace("_pct", "").replace("_", " ").title()
                st.markdown(f"• {label}: {v}%")

    elif key == "maritime":
        st.metric("Astilleros",            len(sec.get("shipyards", [])))
        st.metric("Marinas",               len(sec.get("marinas_with_jobs", [])))
        st.metric("Empleadores portuarios",len(sec.get("maritime_employers", [])))
        bls = sec.get("bls_employment", {})
        if bls.get("latest_employment"):
            st.metric("Empleo marítimo estatal",
                      f"{bls['latest_employment']}K ({bls.get('year','')})")

    elif key == "lifestyle":
        nm = sec.get("nearest_marina")
        nb = sec.get("nearest_beach")
        if nm:
            st.markdown(
                f"**⛵ Marina más cercana:** {nm.get('name','N/A')} "
                f"({nm.get('dist_miles','?')} mi)"
            )
        if nb:
            st.markdown(
                f"**🏖️ Playa más cercana:** {nb.get('name','N/A')} "
                f"({nb.get('dist_miles','?')} mi)"
            )
        st.markdown(f"**🌊 Acceso oceánico:** {'Sí ✅' if sec.get('ocean_access') else 'No'}")
        st.markdown(f"**🚤 Boat ramps en 10 mi:** {len(sec.get('boat_ramps', []))}")
        for m in sec.get("marinas", [])[:5]:
            st.markdown(f"• {m.get('name','N/A')} — {m.get('dist_miles','?')} mi")


# ── UI principal ──────────────────────────────────────────────────────────────
st.title("🏠 Location Intelligence")
st.caption(
    "Investiga cualquier dirección en EE.UU. — "
    "score 0-100 para decisiones de inversión inmobiliaria"
)

if not ollama_ok():
    st.warning(
        "⚠️ Ollama no está activo — el análisis narrativo estará limitado. "
        "Activa Ollama para obtener síntesis completa."
    )

# ── Input + Historial ─────────────────────────────────────────────────────────
col_input, col_history = st.columns([3, 1])

with col_input:
    st.subheader("🔍 Investigar Ubicación")

    search_mode = st.radio(
        "Modo de búsqueda",
        ["🏠 Dirección exacta", "🏙️ Ciudad / Área"],
        horizontal=True,
        label_visibility="collapsed",
    )
    is_city_mode = search_mode == "🏙️ Ciudad / Área"

    if is_city_mode:
        address_input = st.text_input(
            "Ciudad o área",
            placeholder="Ej: Palm Beach, FL   |   Daytona Beach, FL   |   Key West, FL",
            help="Escribe la ciudad y el estado. El análisis usará el centro del área.",
        )
        if address_input.strip() and "," not in address_input:
            st.caption("💡 Agrega el estado para mejores resultados — ej: Miami, FL")
    else:
        address_input = st.text_input(
            "Dirección completa",
            placeholder="Ej: 1234 W 49th St, Hialeah FL 33012",
            help="Incluye ciudad, estado y ZIP para mejores resultados",
        )

    run_btn = st.button(
        "🚀 Analizar Ubicación",
        type="primary",
        disabled=not address_input.strip(),
    )

with col_history:
    st.subheader("📋 Historial")
    try:
        history = list_reports(limit=15)
        if history:
            options = {
                f"#{r['id']} — {r['address'][:32]}… ({r['score_general']}/100)": r["id"]
                for r in history
            }
            sel = st.selectbox(
                "Análisis anteriores",
                ["— Nuevo análisis —"] + list(options.keys()),
            )
            if sel != "— Nuevo análisis —" and st.button("📂 Cargar"):
                st.session_state["loaded_report"] = get_report(options[sel])
                st.session_state.pop("current_report", None)
        else:
            st.caption("Sin análisis previos")
    except Exception as e:
        st.caption(f"BD no disponible: {e}")

# ── Ejecutar agente ───────────────────────────────────────────────────────────
if run_btn and address_input.strip():
    status_box = st.empty()
    progress   = st.progress(0)
    log_lines: list[str] = []

    PROGRESS_KEYWORDS = [
        "geocodificando", "sub-agentes", "crime", "property", "schools",
        "amenities", "demographics", "maritime", "lifestyle", "score",
        "ollama", "guardado", "pdf", "completo",
    ]

    def status_cb(msg: str) -> None:
        log_lines.append(msg)
        status_box.markdown("\n".join(f"`{l}`" for l in log_lines[-8:]))
        hits = sum(
            1 for m in log_lines
            if any(k in m.lower() for k in PROGRESS_KEYWORDS)
        )
        progress.progress(min(95, hits * 7))

    with st.spinner("Analizando ubicación..."):
        try:
            result = run_location_agent(address_input.strip(), status_cb=status_cb)
            st.session_state["current_report"] = result
            st.session_state.pop("loaded_report", None)
            progress.progress(100)
            status_box.empty()
        except Exception as e:
            st.error(f"❌ Error: {e}")
            result = None

# ── Mostrar reporte ───────────────────────────────────────────────────────────
report = (
    st.session_state.get("current_report")
    or st.session_state.get("loaded_report")
)

if not report:
    st.info("👆 Ingresa una dirección arriba y presiona **Investigar Ubicación**")
    st.stop()

if report.get("error"):
    st.error(f"❌ {report['error']}")
    st.stop()

overall  = report.get("overall_score", 0)
sections = report.get("sections", {})
scores   = report.get("scores", {})

st.divider()

# Cabecera con score general
hdr1, hdr2, hdr3 = st.columns([2, 1, 1])
with hdr1:
    st.markdown(f"### 📍 {report.get('address','')}")
    st.caption(f"Análisis: {report.get('analysis_date','')}")
with hdr2:
    st.markdown(score_badge(overall), unsafe_allow_html=True)
    st.markdown("<p style='text-align:center'>Score General</p>", unsafe_allow_html=True)
with hdr3:
    pdf_path = report.get("pdf_path")
    if pdf_path and Path(pdf_path).exists():
        with open(pdf_path, "rb") as f:
            st.download_button(
                "📄 Descargar PDF",
                data=f.read(),
                file_name=Path(pdf_path).name,
                mime="application/pdf",
            )

st.divider()

# Gráfico de barras por dimensión
try:
    import plotly.graph_objects as go

    SCORE_LABELS = {
        "crime":        "Seguridad",
        "property":     "Inmobiliario",
        "schools":      "Escuelas",
        "amenities":    "Amenities",
        "demographics": "Demografía",
        "maritime":     "Marítimo",
        "lifestyle":    "Lifestyle",
    }
    cats = list(SCORE_LABELS.values())
    vals = [scores.get(k, 0) for k in SCORE_LABELS]

    fig = go.Figure(go.Bar(
        x=cats, y=vals,
        marker_color=[
            "#1a7a1a" if v >= 75 else ("#e6a817" if v >= 50 else "#b83232")
            for v in vals
        ],
        text=[f"{v}" for v in vals],
        textposition="outside",
    ))
    fig.update_layout(
        title="Scores por Dimensión",
        yaxis=dict(range=[0, 115], title="Score / 100"),
        height=320,
        margin=dict(t=40, b=20),
        plot_bgcolor="rgba(0,0,0,0)",
    )
    st.plotly_chart(fig, use_container_width=True)
except ImportError:
    cols = st.columns(7)
    for i, (k, lbl) in enumerate(SCORE_LABELS.items()):
        cols[i].metric(lbl, f"{scores.get(k,0)}/100")

st.divider()

# Resumen ejecutivo
exec_sec = sections.get("executive", {})
with st.expander("📋 Resumen Ejecutivo", expanded=True):
    if exec_sec.get("summary"):
        st.write(exec_sec["summary"])
    col_s, col_w = st.columns(2)
    with col_s:
        st.markdown("**✅ Fortalezas**")
        for s in exec_sec.get("strengths", []):
            st.markdown(f"• {s}")
    with col_w:
        st.markdown("**⚠️ Riesgos**")
        for w in exec_sec.get("weaknesses", []):
            st.markdown(f"• {w}")

# Secciones detalladas
SECTION_ORDER = [
    ("crime",        "🔒 Criminalidad"),
    ("property",     "🏘️ Mercado Inmobiliario"),
    ("schools",      "🎓 Escuelas"),
    ("amenities",    "🛒 Amenities y Walkability"),
    ("demographics", "👥 Demografía"),
    ("maritime",     "⚓ Mercado Laboral Marítimo"),
    ("lifestyle",    "⛵ Estilo de Vida Náutico"),
]

for key, label in SECTION_ORDER:
    sec       = sections.get(key, {})
    sec_score = sec.get("score", 0)
    clr       = score_color(sec_score)

    with st.expander(f"{label} — :{clr}[**{sec_score}/100**]"):
        col_data, col_narr = st.columns(2)

        with col_data:
            render_section_data(key, sec)
            if sec.get("errors"):
                for err in sec["errors"]:
                    st.caption(f"⚠️ {err}")
            if sec.get("sources"):
                st.caption(f"Fuentes: {', '.join(sec['sources'])}")

        with col_narr:
            if sec.get("narrative"):
                st.markdown("**Análisis:**")
                st.write(sec["narrative"])
            else:
                st.caption("Análisis narrativo no disponible (Ollama inactivo)")
