import marimo

__generated_with = "0.15.2"
app = marimo.App(
    width="medium",
    layout_file="layouts/Graficos_plotly.grid.json",
)


@app.cell
def _():
    # Cell 1: gráfico Plotly (reactivo)
    import marimo as mo
    import pandas as pd
    import plotly.express as px
    import numpy as np


    df = pd.read_json("https://raw.githubusercontent.com/vega/vega-datasets/master/data/cars.json")

    fig = px.scatter(
        df,
        x="Horsepower",
        y="Miles_per_Gallon",
        color="Origin",
        hover_data=["Name"],
    )

    plot = mo.ui.plotly(fig)  # Solo scatter/treemap/sunburst soportan selección reactiva
    plot
    return df, mo, np, pd, plot, px


@app.cell
def _(df, plot):
    # Cell 2: dataset filtrado (reactivo e interactivo)
    # marimo vuelve a ejecutar esta celda cuando cambia la selección del gráfico
    indices = plot.indices  # lista de int con las filas seleccionadas
    selected_df = df.iloc[indices] if indices else df

    # Visor interactivo con búsqueda/ordenación/filtros integrados
    selected_df
    return


@app.cell
def _(pd):
    # Cell 2 • datos base (Vega cars)
    cars_df = pd.read_json("https://raw.githubusercontent.com/vega/vega-datasets/master/data/cars.json")
    cars_df["Year"] = pd.to_datetime(cars_df["Year"])
    cars_df["Horsepower_num"] = pd.to_numeric(cars_df["Horsepower"], errors="coerce")
    numeric_cols = ["Miles_per_Gallon","Horsepower_num","Weight_in_lbs","Acceleration","Displacement"]
    cars_df
    return cars_df, numeric_cols


@app.cell
def _(cars_df, mo, np):
    # Cell 3 • controles UI (reactivos)
    origin_dd = mo.ui.dropdown(options=["All"] + sorted(cars_df["Origin"].dropna().unique().tolist()),
                               value="All", label="Origin")
    year_min = int(cars_df["Year"].dt.year.min())
    year_max = int(cars_df["Year"].dt.year.max())
    year_rg = mo.ui.range_slider(year_min, year_max, value=(year_min, year_max), step=1, label="Year range")
    hp_min = int(np.nanmin(cars_df["Horsepower_num"]))
    hp_max = int(np.nanmax(cars_df["Horsepower_num"]))
    hp_rg = mo.ui.range_slider(hp_min, hp_max, value=(hp_min, hp_max), step=5, label="Horsepower range")
    bins_sl = mo.ui.slider(5, 60, value=20, step=1, label="Bins (hist)")
    y_metric = mo.ui.radio(options=["Miles_per_Gallon","Horsepower_num","Weight_in_lbs","Acceleration","Displacement"],
                           value="Miles_per_Gallon", label="Y metric (box)")
    mo.hstack([origin_dd, year_rg, hp_rg, bins_sl, y_metric])
    return bins_sl, hp_rg, origin_dd, y_metric, year_rg


@app.cell
def _(cars_df, hp_rg, origin_dd, year_rg):
    # Cell 4 • dataframe filtrado (base para los 5 gráficos)
    df_filtrado = cars_df.copy()
    if origin_dd.value != "All":
        df_filtrado = df_filtrado[df_filtrado["Origin"] == origin_dd.value]
    df_filtrado = df_filtrado[
        (df_filtrado["Year"].dt.year >= year_rg.value[0]) &
        (df_filtrado["Year"].dt.year <= year_rg.value[1]) &
        (df_filtrado["Horsepower_num"].between(hp_rg.value[0], hp_rg.value[1]))
    ].dropna(subset=["Miles_per_Gallon","Horsepower_num"])
    df_filtrado
    return (df_filtrado,)


@app.cell
def _(df_filtrado, mo, px):
    # Cell 5 • (1) Line chart: media de MPG por año y origen
    line_df = (df_filtrado
               .assign(YearNum=df_filtrado["Year"].dt.year)
               .groupby(["YearNum","Origin"], as_index=False)["Miles_per_Gallon"].mean())
    line_fig1 = px.line(line_df, x="YearNum", y="Miles_per_Gallon", color="Origin",
                        markers=True, title="MPG medio por año")
    line_plot1 = mo.ui.plotly(line_fig1)
    line_plot1
    return


@app.cell
def _(bins_sl, df_filtrado, mo, px):
    # Cell 6 • (2) Histogram: distribución de Horsepower (nbins reactivo)
    hist_fig1 = px.histogram(df_filtrado, x="Horsepower_num", nbins=bins_sl.value,
                             color="Origin", title="Distribución de Horsepower")
    hist_plot1 = mo.ui.plotly(hist_fig1)
    hist_plot1
    return


@app.cell
def _(df_filtrado, mo, px, y_metric):
    # Cell 7 • (3) Box plot: métrica Y por Origin (métrica reactiva)
    box_fig1 = px.box(df_filtrado, x="Origin", y=y_metric.value, points="outliers",
                      title=f"Distribución de {y_metric.value} por Origin")
    box_plot1 = mo.ui.plotly(box_fig1)
    box_plot1
    return


@app.cell
def _(df_filtrado, mo, px):
    # Cell 8 • (4) Density heatmap: Horsepower vs MPG
    heat_fig1 = px.density_heatmap(df_filtrado, x="Horsepower_num", y="Miles_per_Gallon",
                                   nbinsx=40, nbinsy=30, title="Densidad HP vs MPG")
    heat_plot1 = mo.ui.plotly(heat_fig1)
    heat_plot1
    return


@app.cell
def _(df_filtrado, mo, numeric_cols, px):
    # Cell 9 • (5) Scatter matrix: relación entre variables numéricas
    splom_fig1 = px.scatter_matrix(df_filtrado[numeric_cols], dimensions=numeric_cols,
                                   title="Scatter Matrix de variables numéricas")
    splom_plot1 = mo.ui.plotly(splom_fig1)
    splom_plot1
    return


if __name__ == "__main__":
    app.run()
