import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import folium
from folium.plugins import MarkerCluster
import os


from resumen import FILE_PATH  # 👈 usamos la misma ruta del archivo BD_Mazatlan.xlsm

# =======================================================================
# IDENTIDAD DE MARCA (COLORES Y TIPOGRAFÍA)
# =======================================================================
COLORS = {
    "brown":       "#8B4513",
    "gold":        "#FD6A02",
    "white":       "#FFFFFF",
    "darkslate":   "#2F4F4F",
    "beige":       "#F5F5DC",
    "black":       "#000000",
    "light_brown": "#C19A6B",
    "dark_red":    "#8B0000",
}
TITLE_FONT = "Playfair Display, serif"
BODY_FONT = "Lato, sans-serif"
ALT_FONT = "Montserrat, sans-serif"

# Paleta Picton Blue (solo charts)
PICTON_BLUE = [
    "#eff8ff", "#dff0ff", "#b8e3ff", "#78cdff", "#38b6ff",
    "#069af1", "#007ace", "#0061a7", "#02528a", "#084572", "#062b4b"
]

BUMP_COLORS = [
    "#e6194b", "#3cb44b", "#ffe119", "#4363d8",
    "#f58231", "#911eb4", "#46f0f0", "#f032e6",
    "#bcf60c", "#fabebe", "#008080", "#e6beff",
    "#9a6324", "#fffac8", "#800000", "#aaffc3",
    "#808000", "#ffd8b1", "#000075", "#808080",
]

px.defaults.template = "plotly_dark"
px.defaults.color_discrete_sequence = PICTON_BLUE

SPANISH_MONTH_ABBR = {
    1: "Ene", 2: "Feb", 3: "Mar", 4: "Abr",
    5: "May", 6: "Jun", 7: "Jul", 8: "Ago",
    9: "Sep", 10: "Oct", 11: "Nov", 12: "Dic",
}

SHEET_VERTICAL = "Vertical"
SHEET_HORIZONTAL = "Horizontal"
SHEET_LOTE = "Lote"


# =======================================================================
# Helpers para Oferta
# =======================================================================
@st.cache_data(show_spinner=False)
def load_oferta_catalogo(path: str):
    """
    Carga las hojas Vertical, Horizontal y Lote desde el archivo de BD
    y asegura que Fecha_inicio_venta sea datetime.
    """
    xls = pd.ExcelFile(path)
    vertical = pd.read_excel(xls, SHEET_VERTICAL)
    horizontal = pd.read_excel(xls, SHEET_HORIZONTAL)
    lote = pd.read_excel(xls, SHEET_LOTE)

    for df in (vertical, horizontal, lote):
        if "Fecha_inicio_venta" in df.columns:
            df["Fecha_inicio_venta"] = pd.to_datetime(
                df["Fecha_inicio_venta"], errors="coerce"
            )

    return vertical, horizontal, lote

def get_ciudad_from_file_path(path: str) -> str:
    """
    Extrae el nombre de la ciudad del archivo BD_XXXX.xlsm.
    Ejemplo: BD_Mazatlan.xlsm -> Mazatlán
    """
    base = os.path.basename(path)           # BD_Mazatlan.xlsm
    nombre = base.split(".")[0]             # BD_Mazatlan

    if "BD_" in nombre:
        nombre = nombre.split("BD_")[1]     # Mazatlan

    nombre = nombre.replace("_", " ").strip()

    # Corrección específica para Mazatlán
    if nombre.lower() == "mazatlan":
        return "Mazatlán"

    # Fallback genérico
    return nombre.title()


def get_desarrollos_nuevos(
    periodo_sel,
    periodo_prev,
    tipo_filter,
    proyectos_seleccionados,
):
    """
    Devuelve un DataFrame con los desarrollos que ENTRAN en el periodo seleccionado,
    comparando Fecha_inicio_venta contra periodo_prev y periodo_sel.

    Regla:
    - Si hay periodo_prev: Fecha_inicio_venta en (periodo_prev, periodo_sel]
    - Si NO hay periodo_prev: Fecha_inicio_venta == periodo_sel

    Todo respeta:
    - tipo_filter (Vertical / Horizontal / Lote)
    - proyectos_seleccionados (no mostrar proyectos excluidos)
    """
    vertical, horizontal, lote = load_oferta_catalogo(FILE_PATH)

    # Agregamos columna Tipo (no viene en el Excel)
    vertical["Tipo"] = "Vertical"
    horizontal["Tipo"] = "Horizontal"
    lote["Tipo"] = "Lote"

    # Nos quedamos con las columnas relevantes (si existen)
    cols_base = ["Nombre_desarrollo", "Zona", "Fecha_inicio_venta", "Tipo"]
    vertical = vertical[[c for c in cols_base if c in vertical.columns]]
    horizontal = horizontal[[c for c in cols_base if c in horizontal.columns]]
    lote = lote[[c for c in cols_base if c in lote.columns]]

    df_all = pd.concat([vertical, horizontal, lote], ignore_index=True)

    # Filtro por rango de fechas
    if periodo_sel is None:
        return pd.DataFrame(columns=["Desarrollo", "Tipo", "Zona"])

    if periodo_prev is not None:
        # Nuevos que entran ENTRE el periodo previo y el periodo base
        mask_fecha = (
            (df_all["Fecha_inicio_venta"] > periodo_prev)
            & (df_all["Fecha_inicio_venta"] <= periodo_sel)
        )
    else:
        # Si no hay periodo previo, tomamos los que inician justo en el periodo base
        mask_fecha = df_all["Fecha_inicio_venta"] == periodo_sel

    df_all = df_all[mask_fecha]

    # Respetar filtros globales: tipo_filter y proyectos_seleccionados
    if tipo_filter:
        df_all = df_all[df_all["Tipo"].isin(tipo_filter)]

    if proyectos_seleccionados:
        df_all = df_all[df_all["Nombre_desarrollo"].isin(proyectos_seleccionados)]

    # Dejar un registro por desarrollo-tipo-zona
    df_all = (
        df_all.dropna(subset=["Nombre_desarrollo"])
        .drop_duplicates(subset=["Nombre_desarrollo", "Tipo", "Zona"])
        .copy()
    )

    # Renombrar columnas para el DataFrame final que se mostrará
    df_final = df_all.rename(
        columns={
            "Nombre_desarrollo": "Desarrollo",
            "Tipo": "Tipo",
            "Zona": "Zona",
            "Fecha_inicio_venta": "Fecha inicio venta",
        }
    )

    # Orden más bonito
    df_final = df_final[["Desarrollo", "Tipo", "Zona","Fecha inicio venta"]].sort_values(
        by=["Tipo", "Desarrollo"]
    )

    # 3. Aplicar la transformación fila por fila
    df_final["Fecha inicio venta"] = df_final["Fecha inicio venta"].apply(
        lambda x: f"{SPANISH_MONTH_ABBR[x.month]}-{x.year}"
    )
    return df_final

def get_desarrollos_vendidos(
    periodo_sel,
    periodo_prev,
    tipo_filter,
    proyectos_seleccionados,
):
    """
    Devuelve los desarrollos que SALEN en el periodo seleccionado.
    Se basa en la columna Fecha_fin_ventas en las hojas Vertical, Horizontal y Lote.

    Regla:
    - Si hay periodo_prev → Fecha_fin_ventas en (periodo_prev, periodo_sel]
    - Si NO hay periodo_prev → Fecha_fin_ventas == periodo_sel

    Respeta los filtros globales:
    - tipo_filter
    - proyectos_seleccionados
    """

    vertical, horizontal, lote = load_oferta_catalogo(FILE_PATH)

    # Asignar tipo según la hoja correspondiente
    vertical["Tipo"] = "Vertical"
    horizontal["Tipo"] = "Horizontal"
    lote["Tipo"] = "Lote"

    # Validar columnas esperadas
    cols_base = ["Nombre_desarrollo", "Zona", "Fecha_fin_ventas", "Tipo"]
    vertical = vertical[[c for c in cols_base if c in vertical.columns]]
    horizontal = horizontal[[c for c in cols_base if c in horizontal.columns]]
    lote = lote[[c for c in cols_base if c in lote.columns]]

    df_all = pd.concat([vertical, horizontal, lote], ignore_index=True)

    # Aseguramos datetime
    if "Fecha_fin_ventas" in df_all.columns:
        df_all["Fecha_fin_ventas"] = pd.to_datetime(
            df_all["Fecha_fin_ventas"], errors="coerce"
        )

    # -------------------------------
    # Filtro por rango de fechas
    # -------------------------------
    if periodo_sel is None:
        return pd.DataFrame(columns=["Desarrollo", "Tipo", "Zona"])

    if periodo_prev is not None:
        mask_fecha = (
            (df_all["Fecha_fin_ventas"] > periodo_prev) &
            (df_all["Fecha_fin_ventas"] <= periodo_sel)
        )
    else:
        mask_fecha = df_all["Fecha_fin_ventas"] == periodo_sel

    df_all = df_all[mask_fecha]

    # -------------------------------
    # Aplicar filtros globales
    # -------------------------------
    if tipo_filter:
        df_all = df_all[df_all["Tipo"].isin(tipo_filter)]

    if proyectos_seleccionados:
        df_all = df_all[df_all["Nombre_desarrollo"].isin(proyectos_seleccionados)]

    # -------------------------------
    # Limpiar y renombrar para display
    # -------------------------------
    df_all = (
        df_all.dropna(subset=["Nombre_desarrollo"])
              .drop_duplicates(subset=["Nombre_desarrollo", "Tipo", "Zona"])
              .copy()
    )

    df_final = df_all.rename(
        columns={
            "Nombre_desarrollo": "Desarrollo",
            "Tipo": "Tipo",
            "Zona": "Zona",
            "Fecha_fin_ventas": "Fecha fin ventas",
        }
    )

    df_final = df_final[["Desarrollo", "Tipo", "Zona","Fecha fin ventas"]].sort_values(
        by=["Tipo", "Desarrollo"]
    )
    # 3. Aplicar la transformación fila por fila
    df_final["Fecha fin ventas"] = df_final["Fecha fin ventas"].apply(
        lambda x: f"{SPANISH_MONTH_ABBR[x.month]}-{x.year}"
    )

    return df_final


def add_porcentaje_vendido(ventas: pd.DataFrame) -> pd.DataFrame:
    """
    Devuelve el mismo DataFrame de ventas pero con una nueva columna '% vendido',
    calculada como Ventas_acumuladas / Numero_de_viviendas_planeadas.
    """
    df = ventas.copy()

    # Aseguramos numéricos
    num = pd.to_numeric(df.get("Ventas_acumuladas", 0), errors="coerce")
    denom = pd.to_numeric(df.get("Numero_de_viviendas_planeadas", 0), errors="coerce")

    # Evitar división entre cero
    denom = denom.replace(0, np.nan)

    df["% vendido"] = np.where(
        denom.notna(),
        num / denom,
        np.nan,
    )

    return df

def get_proyectos_detenidos(
    ventas: pd.DataFrame,
    periodo_sel,
    tipo_filter,
    proyectos_seleccionados,
) -> pd.DataFrame:
    """
    Devuelve los desarrollos detenidos en el periodo seleccionado,
    usando la columna Ventas_detenidas de la hoja Ventas.

    Regla:
    - Solo se consideran las filas con Fecha == periodo_sel
    - Ventas_detenidas debe ser VERDADERO (texto) o True (booleano)
    - Respeta tipo_filter y proyectos_seleccionados
    """

    if "Ventas_detenidas" not in ventas.columns:
        return pd.DataFrame(columns=["Desarrollo", "Tipo", "Zona"])

    df = ventas.copy()

    # Filtrar por periodo base
    df = df[df["Fecha"] == periodo_sel]


    # Normalizar a valores numéricos
    df["Ventas_detenidas"] = pd.to_numeric(df["Ventas_detenidas"], errors="coerce").fillna(0)

    # Checkbox marcado = 1 → detenido
    mask_det = df["Ventas_detenidas"] == 1
    df = df[mask_det]

    # Aplicar filtros globales de tipo y proyectos
    if tipo_filter:
        df = df[df["Tipo_proyecto"].isin(tipo_filter)]

    if proyectos_seleccionados:
        df = df[df["Nombre_desarrollo"].isin(proyectos_seleccionados)]

    # Armar tabla final
    if df.empty:
        return pd.DataFrame(columns=["Desarrollo", "Tipo", "Zona"])

    df_final = (
        df[["Nombre_desarrollo", "Tipo_proyecto", "Zona"]]
        .drop_duplicates()
        .rename(
            columns={
                "Nombre_desarrollo": "Desarrollo",
                "Tipo_proyecto": "Tipo",
            }
        )
        .sort_values(["Tipo", "Desarrollo"])
    )

    return df_final


def get_proyectos_disponibles(
    ventas: pd.DataFrame,
    precios: pd.DataFrame,
    periodo_sel,
    periodo_prev,
    tipo_filter,
    proyectos_seleccionados,
) -> pd.DataFrame:
    """
    Devuelve los proyectos DISPONIBLES o VENDIDOS en el periodo seleccionado,
    excluyendo únicamente los detenidos.

    Estatus:
    - "Vendido"      → aparece en get_desarrollos_vendidos()
    - "Disponible"   → no vendido y no detenido

    Además calcula:
    - ventas_ulti_mes = Ventas_periodo / meses_transcurridos
    - M2_promedio     = promedio de M2 de sus prototipos (en hoja Precios) en el periodo base,
                        considerando solo filas con Precio > 0.
    - % vendido       = % de ventas acumuladas sobre viviendas planeadas en el periodo base seleccionado.
    """

    # 1) Filtrar Ventas al periodo base
    df = ventas.copy()
    df = df[df["Fecha"] == periodo_sel].copy()

    # 2) Aplicar filtros globales
    if tipo_filter:
        df = df[df["Tipo_proyecto"].isin(tipo_filter)]

    if proyectos_seleccionados:
        df = df[df["Nombre_desarrollo"].isin(proyectos_seleccionados)]

    if df.empty:
        return pd.DataFrame(
            columns=[
                "Desarrollo", "Tipo", "Zona", "Estatus",
                "Ventas_acumuladas", "Ventas_periodo", "ventas_ulti_mes",
                "M2_promedio",
                "Inventario_disponible", "Numero_de_viviendas_planeadas",
            ]
        )

    # ==================================================
    # 3) Obtener vendidos y detenidos
    # ==================================================
    df_vendidos = get_desarrollos_vendidos(
        periodo_sel=periodo_sel,
        periodo_prev=periodo_prev,
        tipo_filter=tipo_filter,
        proyectos_seleccionados=proyectos_seleccionados,
    )

    df_detenidos = get_proyectos_detenidos(
        ventas=ventas,
        periodo_sel=periodo_sel,
        tipo_filter=tipo_filter,
        proyectos_seleccionados=proyectos_seleccionados,
    )

    vendidos_set = set(df_vendidos["Desarrollo"].unique()) if not df_vendidos.empty else set()
    detenidos_set = set(df_detenidos["Desarrollo"].unique()) if not df_detenidos.empty else set()

    # ==================================================
    # 4) EXCLUIR solo los detenidos
    # ==================================================
    df = df[~df["Nombre_desarrollo"].isin(detenidos_set)].copy()

    if df.empty:
        return pd.DataFrame(
            columns=[
                "Desarrollo", "Tipo", "Zona", "Estatus",
                "Ventas_acumuladas", "Ventas_periodo", "ventas_ulti_mes",
                "M2_promedio",
                "Inventario_disponible", "Numero_de_viviendas_planeadas",
            ]
        )

    # ==================================================
    # 5) Crear columna Estatus: "Vendido" o "Disponible"
    # ==================================================
    df["Estatus"] = df["Nombre_desarrollo"].apply(
        lambda x: "Vendido" if x in vendidos_set else "Disponible"
    )

    # ==================================================
    # 6) Asegurar números limpios
    # ==================================================
    for col in [
        "Ventas_acumuladas",
        "Ventas_periodo",
        "Inventario_disponible",
        "Numero_de_viviendas_planeadas",
    ]:
        if col in df.columns:
            df[col] = pd.to_numeric(df[col], errors="coerce")

    # ==================================================
    # 7) Calcular ventas_ulti_mes
    # ==================================================
    if periodo_prev is not None:
        meses_transcurridos = (periodo_sel.year - periodo_prev.year) * 12 + (
            periodo_sel.month - periodo_prev.month
        )
    else:
        meses_transcurridos = 1

    if meses_transcurridos is None or meses_transcurridos <= 0:
        meses_transcurridos = 1

    df["ventas_ulti_mes"] = df["Ventas_periodo"] / meses_transcurridos

    # ==================================================
    # 8) Calcular M2_promedio por proyecto desde hoja Precios
    # ==================================================
    # Lista de desarrollos que quedaron (ya sin detenidos)
    proyectos_validos = df["Nombre_desarrollo"].unique()

    pre = precios.copy()

    # Filtrar al periodo base
    pre = pre[pre["Fecha"] == periodo_sel].copy()

    # Solo proyectos vigentes en df
    pre = pre[pre["Nombre_desarrollo"].isin(proyectos_validos)]

    # Opcional: respeta tipo_filter si quieres ser más estricto
    if tipo_filter:
        pre = pre[pre["Tipo_proyecto"].isin(tipo_filter)]

    # Asegurar numéricos
    if "Precio" in pre.columns:
        pre["Precio"] = pd.to_numeric(pre["Precio"], errors="coerce")
    if "M2" in pre.columns:
        pre["M2"] = pd.to_numeric(pre["M2"], errors="coerce")

    # Solo prototipos con Precio > 0
    pre = pre[(pre["Precio"].notna()) & (pre["Precio"] > 0)]

    # Calcular M2 promedio por proyecto-tipo
    if not pre.empty and "M2" in pre.columns:
        df_m2 = (
            pre.groupby(["Nombre_desarrollo", "Tipo_proyecto"], as_index=False)["M2"]
            .mean()
            .rename(columns={"M2": "M2_promedio"})
        )
    else:
        df_m2 = pd.DataFrame(
            columns=["Nombre_desarrollo", "Tipo_proyecto", "M2_promedio"]
        )

    # Unir M2_promedio a df (por proyecto-tipo)
    df = df.merge(
        df_m2,
        on=["Nombre_desarrollo", "Tipo_proyecto"],
        how="left",
    )

    # ==================================================
    # 9) Armar DataFrame final
    # ==================================================
    df_final = (
        df[
            [
                "Nombre_desarrollo",
                "Tipo_proyecto",
                "Zona",
                "Estatus",
                "Ventas_acumuladas",
                "Ventas_periodo",
                "ventas_ulti_mes",
                "M2_promedio",
                "Inventario_disponible",
                "Numero_de_viviendas_planeadas",
            ]
        ]
        .drop_duplicates()
        .rename(
            columns={
                "Nombre_desarrollo": "Desarrollo",
                "Tipo_proyecto": "Tipo",
            }
        )
        .sort_values(["Tipo", "Desarrollo"])
    )
    df_final["% vendido"] = df_final["Ventas_acumuladas"] / df_final["Numero_de_viviendas_planeadas"]
    return df_final


def build_resumen_proyectos_vivienda(df_disponibles: pd.DataFrame) -> pd.DataFrame:
    """
    Construye la tabla de resumen por tipo (Vertical, Horizontal, Lote)
    a partir de df_disponibles, que ya contiene:

    - Desarrollo
    - Tipo
    - Zona
    - Estatus (Disponible / Vendido)
    - Ventas_acumuladas
    - Ventas_periodo
    - ventas_ulti_mes
    - M2_promedio
    - Inventario_disponible
    - Numero_de_viviendas_planeadas
    - % vendido
    """

    tipos = ["Vertical", "Horizontal", "Lote"]
    filas = []

    def filtro_tipo(df, tipo):
        return df[df["Tipo"] == tipo]

    for tipo in tipos:
        df_t = filtro_tipo(df_disponibles, tipo)

        df_disp = df_t[df_t["Estatus"] == "Disponible"]
        df_disp_ven = df_t[df_t["Estatus"].isin(["Disponible", "Vendido"])]

        # 1) Proyectos
        proyectos = df_disp["Desarrollo"].nunique()

        # 2) Inventario disponible
        inventario_disp = df_disp["Inventario_disponible"].sum(min_count=1)

        # 3) Absorción promedio último mes x desarrollo
        absorcion_prom_x_des = df_disp_ven["ventas_ulti_mes"].mean()

        # 4) Absorción mensual x último mes (total)
        absorcion_mensual = df_disp_ven["ventas_ulti_mes"].sum(min_count=1)

        # 5) Medida promedio (solo disponibles)
        medida_prom = df_disp["M2_promedio"].mean()

        # 6) Estimación venta oferta disponible (meses)
        if absorcion_mensual and absorcion_mensual > 0:
            meses_estim = inventario_disp / absorcion_mensual
        else:
            meses_estim = np.nan

        # 7) % vendido (solo disponibles)
        pct_vendido = df_disp["% vendido"].mean()

        filas.append(
            {
                "Tipo": tipo,
                "Proyectos:": proyectos,
                "Inventario disponible:": inventario_disp,
                "Absorción promedio último mes x desarrollo:": absorcion_prom_x_des,
                "Absorción mensual x último mes:": absorcion_mensual,
                "Medida promedio:": medida_prom,
                "Estimación de venta de oferta disponible (meses):": meses_estim,
                "% vendido": pct_vendido,
            }
        )

    # Pasar a DataFrame y pivotear al formato solicitado
    df_metricas = pd.DataFrame(filas)  # columnas: Tipo + métricas

    # Queremos filas = métricas, columnas = tipos
    df_metricas = df_metricas.set_index("Tipo").T

    # Renombrar índice a "Metricas"
    df_metricas.index.name = "Metricas"

    # Reordenar columnas explícitamente
    df_metricas = df_metricas[["Vertical", "Horizontal", "Lote"]]

    # Opcional: redondear algunos valores para que se vean mejor
    # (no tocamos "Proyectos:" que es entero)
    for metrica in df_metricas.index:
        if metrica in [
            "Inventario disponible:",
            "Absorción mensual x último mes:",
        ]:
            df_metricas.loc[metrica] = df_metricas.loc[metrica].round(1)
        elif metrica in [
            "Absorción promedio último mes x desarrollo:",
            "Medida promedio:",
            "Estimación de venta de oferta disponible (meses):",
        ]:
            df_metricas.loc[metrica] = df_metricas.loc[metrica].round(2)
        elif metrica == "% vendido":
            # Dejar como proporción o convertir a % según prefieras
            df_metricas.loc[metrica] = (df_metricas.loc[metrica] * 100).round(1)

    return df_metricas.reset_index()

# =======================================================================
# Página de Oferta
# =======================================================================
def oferta_page(
    ventas,
    precios,
    periodo_sel,
    periodo_prev,
    tipo_filter,
    proyectos_seleccionados,
):
    """
    Página de Oferta del dashboard REM.
    TODO lo que se muestra respeta los filtros globales que vienen de REM.py.
    """

    st.title("Oferta")

    st.caption(
        f"Periodo base: {periodo_sel.strftime('%Y-%m-%d')}"
        + (f" | Periodo anterior: {periodo_prev.strftime('%Y-%m-%d')}" if periodo_prev else "")
    )

    st.sidebar.markdown("**Contexto de esta sección**")
    st.sidebar.caption(
        "Todos los indicadores de Oferta respetan los filtros de tipo de proyecto y "
        "proyectos seleccionados en la barra lateral."
    )

    # ==============================
    # Layout principal de 5 columnas
    # ==============================
    c1, c2, c3, c4 = st.columns(4)

    # -------------------------------------------------------------------
    # C1: Desarrollos nuevos que entran
    # -------------------------------------------------------------------
    df_nuevos = get_desarrollos_nuevos(
        periodo_sel=periodo_sel,
        periodo_prev=periodo_prev,
        tipo_filter=tipo_filter,
        proyectos_seleccionados=proyectos_seleccionados,
    )

    with c1:
        st.subheader("Desarrollos nuevos que entran")

        if df_nuevos.empty:
            st.info(
                "No hay desarrollos nuevos que hayan iniciado ventas en este periodo "
                "con los filtros actuales."
            )
        else:
            st.dataframe(
                df_nuevos,
                use_container_width=True,
                hide_index=True,
            )

            # Explicación dinámica
            if periodo_prev:
                st.info(
                    f"Esta tabla muestra los desarrollos que **iniciaron ventas** entre "
                    f"**{periodo_prev.strftime('%Y-%m-%d')}** y **{periodo_sel.strftime('%Y-%m-%d')}**."
                )
            else:
                st.info(
                    f"Esta tabla muestra los desarrollos que **iniciaron ventas en el periodo** "
                    f"**{periodo_sel.strftime('%Y-%m-%d')}**."
            )


    # -------------------------------------------------------------------
    # C2: Desarrollos vendidos (que salieron)
    # -------------------------------------------------------------------
    df_vendidos = get_desarrollos_vendidos(
        periodo_sel=periodo_sel,
        periodo_prev=periodo_prev,
        tipo_filter=tipo_filter,
        proyectos_seleccionados=proyectos_seleccionados,
    )

    with c2:
        st.subheader("Desarrollos vendidos (que salieron)")

        if df_vendidos.empty:
            st.info(
                "No hay desarrollos que hayan finalizado ventas en este periodo "
                "con los filtros actuales."
            )
        else:
            st.dataframe(
                df_vendidos,
                use_container_width=True,
                hide_index=True,
            )

            # Explicación dinámica
            if periodo_prev:
                st.info(
                    f"Estos son los desarrollos que **finalizaron sus ventas** entre "
                    f"**{periodo_prev.strftime('%Y-%m-%d')}** y **{periodo_sel.strftime('%Y-%m-%d')}**."
                )
            else:
                st.info(
                    f"Estos son los desarrollos que **finalizaron sus ventas en el periodo** "
                    f"**{periodo_sel.strftime('%Y-%m-%d')}**."
                )



    # -------------------------------------------------------------------
    # C3: Desarrollos maduros: que saldrán
    # -------------------------------------------------------------------
    ventas_con_pct = add_porcentaje_vendido(ventas)

    # Filtrar al periodo base
    df_maduros = ventas_con_pct[ventas_con_pct["Fecha"] == periodo_sel].copy()

    # Aplicar filtros globales de tipo y proyectos seleccionados
    if tipo_filter:
        df_maduros = df_maduros[df_maduros["Tipo_proyecto"].isin(tipo_filter)]

    if proyectos_seleccionados:
        df_maduros = df_maduros[df_maduros["Nombre_desarrollo"].isin(proyectos_seleccionados)]

    # Filtrar los que tienen % vendido >= 95%
    df_maduros = df_maduros[(df_maduros["% vendido"] >= 0.95) & (df_maduros["% vendido"]<1.0)]
    

    with c3:
        st.subheader("Desarrollos maduros: que saldrán")

        if df_maduros.empty:
            st.info(
                "No hay desarrollos con más del 95% vendido en el periodo base "
                "con los filtros actuales."
            )
        else:
            # Armamos el dataframe final: Desarrollo, Tipo, Zona
            df_display_maduros = (
                df_maduros[["Nombre_desarrollo", "Tipo_proyecto", "Zona","% vendido"]]
                .drop_duplicates()
                .rename(
                    columns={
                        "Nombre_desarrollo": "Desarrollo",
                        "Tipo_proyecto": "Tipo",
                    }
                )
                .sort_values(["Tipo", "Desarrollo"])
            )
            # Multiplicas por 100 y le pones el símbolo %
            df_display_maduros["% vendido"] = df_display_maduros["% vendido"].apply(
                lambda x: f"{x:.1%}"
            )


            st.dataframe(
                df_display_maduros,
                use_container_width=True,
                hide_index=True,
            )
            # Explicación dinámica
            st.info(
                f"Estos son los desarrollos que tienen un **porcentaje vendido mayor al 95%** "
                f"en el periodo **{periodo_sel.strftime('%Y-%m-%d')}**. "
                "Son proyectos que están por agotar su inventario y pronto saldrán del mercado."
            )


    # -------------------------------------------------------------------
    # C4: Desarrollos detenidos
    # -------------------------------------------------------------------
    df_detenidos = get_proyectos_detenidos(
        ventas=ventas,
        periodo_sel=periodo_sel,
        tipo_filter=tipo_filter,
        proyectos_seleccionados=proyectos_seleccionados,
    )

    with c4:
        st.subheader("Desarrollos detenidos")

        if df_detenidos.empty:
            st.info(
                "No hay desarrollos marcados como detenidos en el periodo base "
                "con los filtros actuales."
            )
        else:
            st.dataframe(
                df_detenidos,
                use_container_width=True,
                hide_index=True,
            )

            st.info(
                f"Proyectos cuya comercialización está detenida "
                f"en el periodo **{periodo_sel.strftime('%Y-%m-%d')}**"
            )
    st.divider()
    st.subheader("Detalle de la oferta")
    st.caption(
        "A continuación puedes ver análisis más específicos de la oferta, "
        "complementando el resumen rápido de entradas, salidas, maduros y detenidos."
    )

    # ======================================================
    # Tabla: Proyectos disponibles en el periodo seleccionado
    # ======================================================
    df_disponibles = get_proyectos_disponibles(
        ventas=ventas,
        precios=precios,
        periodo_sel=periodo_sel,
        periodo_prev=periodo_prev,
        tipo_filter=tipo_filter,
        proyectos_seleccionados=proyectos_seleccionados,
    )

 
    
    # ===========================================
    # Tabla resumen: PROYECTOS DE VIVIENDA EN X
    # ===========================================
    if not df_disponibles.empty:
        ciudad = get_ciudad_from_file_path(FILE_PATH)
        titulo_resumen = f"PROYECTOS DE VIVIENDA EN {ciudad.upper()}"

        st.subheader(titulo_resumen)

        df_resumen = build_resumen_proyectos_vivienda(df_disponibles)

        st.dataframe(
            df_resumen,
            use_container_width=True,
            hide_index=True,
        )

        st.info(
            "Esta tabla resume, por tipo de proyecto, cuántos desarrollos hay, "
            "qué inventario está disponible, cómo ha sido la absorción reciente "
            "y cuántos meses, al ritmo actual, tomaría vender la oferta disponible."
        )





    df_disponibles["% vendido"] = df_disponibles["% vendido"].apply(
                    lambda x: f"{x:.1%}"
                )

    st.subheader("Proyectos disponibles en el periodo")

    if df_disponibles.empty:
        st.info(
            "No se encontraron proyectos disponibles en el periodo base "
            "con los filtros actuales."
        )
    else:
        st.dataframe(
            df_disponibles,
            use_container_width=True,
            hide_index=True,
        )

        st.info(
            f"Estos son los proyectos que **siguen activos y disponibles** en el periodo "
            f"**{periodo_sel.strftime('%Y-%m-%d')}**, después de excluir los que "
            "ya terminaron ventas y los que están detenidos."
        )

    # Si quieres, podemos dejar de momento esto comentado:
    # st.subheader("Vista rápida de proyectos seleccionados")
    # ventas_filtradas = ventas[
    #     (ventas["Nombre_desarrollo"].isin(proyectos_seleccionados)) &
    #     (ventas["Tipo_proyecto"].isin(tipo_filter))
    # ]
    # st.dataframe(ventas_filtradas.head(20), use_container_width=True)
