#!/usr/bin/env python
# -*- coding: utf-8 -*-
### DESEMBARQUE TOTAL — serie de tiempo + promedio últimos N años por región (mean ± SD) POR ESPECIE

import pandas as pd
from dash import Dash, dcc, html
from dash.dependencies import Input, Output
import plotly.express as px

# ============================
# 1) Leer base y normalizar
# ============================
df = pd.read_csv("data/DES_TOTAL_2000_2024_with_comuna.csv", low_memory=False)
df.columns = df.columns.str.strip()

# --- ESPECIE ---
df["ESPECIE"] = (
    df["ESPECIE"]
    .astype(str)
    .str.upper()
    .str.strip()
)

# --- REGIÓN ---
df["REGION"] = (
    df["REGION"]
    .astype(str)
    .str.strip()
)
df["REGION"] = df["REGION"].str.replace(".0", "", regex=False)

# --- TIPO AGENTE ---
df["TIPO AGENTE"] = (
    df["TIPO AGENTE"]
    .astype(str)
    .str.upper()
    .str.strip()
)

# --- Numéricos ---
for col in ["AÑO", "MES", "TONELADAS"]:
    if col in df.columns:
        df[col] = pd.to_numeric(df[col], errors="coerce")

# ============================
# 2) Diccionario de regiones y orden geográfico
# ============================
dicc_regiones = {
    "15": "XV Arica y Parinacota",
    "1":  "I Tarapacá",
    "2":  "II Antofagasta",
    "3":  "III Atacama",
    "4":  "IV Coquimbo",
    "5":  "V Valparaíso",
    "6":  "VI Libertador General Bernardo O'Higgins",
    "7":  "VII Maule",
    "16": "XVI Ñuble",
    "8":  "VIII Biobío",
    "9":  "IX de Araucanía",
    "14": "XIV Los Ríos",
    "10": "X Los Lagos",
    "11": "XI Aysén del General Carlos Ibáñez del Campo",
    "12": "XII Magallanes y Antártica Chilena",
}

region_order_geo = [
    "15",  # XV Arica y Parinacota
    "1",   # I Tarapacá
    "2",   # II Antofagasta
    "3",   # III Atacama
    "4",   # IV Coquimbo
    "5",   # V Valparaíso
    "13",  # RM (si no existe en data, se ignora)
    "6",   # VI O'Higgins
    "7",   # VII Maule
    "16",  # XVI Ñuble
    "8",   # VIII Biobío
    "9",   # IX Araucanía
    "14",  # XIV Los Ríos
    "10",  # X Los Lagos
    "11",  # XI Aysén
    "12",  # XII Magallanes
]

regiones_presentes = sorted(df["REGION"].dropna().unique().tolist())
regiones_unicas = [r for r in region_order_geo if r in regiones_presentes]

map_region_nombre = {code: dicc_regiones.get(code, code) for code in regiones_unicas}

# ============================
# 3) Base reducida para la app
# ============================
df_base = df[["ESPECIE", "AÑO", "TONELADAS", "REGION", "TIPO AGENTE"]].dropna(
    subset=["AÑO", "TONELADAS"]
)

min_year = int(df_base["AÑO"].min())
max_year = int(df_base["AÑO"].max())

# Especies ordenadas por tonelaje total
totales_por_especie = (
    df_base.groupby("ESPECIE")["TONELADAS"]
    .sum()
    .sort_values(ascending=False)
)
especies_ordenadas = totales_por_especie.index.tolist()

# Especies por defecto
especies_default_deseadas = ["ANCHOVETA", "SARDINA COMUN"]
default_especies = [e for e in especies_default_deseadas if e in especies_ordenadas]
if not default_especies:
    default_especies = especies_ordenadas[:5] if len(especies_ordenadas) > 5 else especies_ordenadas

# Tipos de agente
tipos_agente = ["ARTESANAL", "INDUSTRIAL", "ACUICULTURA", "FABRICA"]
tipos_agente_presentes = [t for t in tipos_agente if t in df_base["TIPO AGENTE"].unique()]
default_agente = "ARTESANAL" if "ARTESANAL" in tipos_agente_presentes else "TODOS"

# ============================
# 4) Estilos
# ============================
COLORS = {
    "bg": "#f5f7fa",
    "card": "white",
    "accent": "#005f73",
    "text": "#222222",
    "muted": "#666666",
}

CARD_STYLE = {
    "backgroundColor": COLORS["card"],
    "borderRadius": "8px",
    "padding": "15px",
    "boxShadow": "0 2px 5px rgba(0,0,0,0.08)",
    "marginBottom": "15px",
}

# ============================
# 5) App Dash
# ============================
app = Dash(
    __name__,
    requests_pathname_prefix="/apps/puertos/",
)

app.layout = html.Div(
    style={"fontFamily": "Arial, sans-serif", "backgroundColor": COLORS["bg"], "minHeight": "100vh"},
    children=[
        # Barra superior
        html.Div(
            style={
                "backgroundColor": COLORS["accent"],
                "color": "white",
                "padding": "12px 25px",
                "display": "flex",
                "justifyContent": "space-between",
                "alignItems": "center",
            },
            children=[
                html.Div([
                    html.H1(
                        "Desembarques TOTALES (Puerto) por especie",
                        style={"margin": "0", "fontSize": "22px", "fontWeight": "bold"},
                    ),
                    html.Div(
                        "Serie de tiempo 2000–2024 · + Promedio últimos N años por región (mean ± SD) por especie",
                        style={"fontSize": "13px", "opacity": 0.9},
                    ),
                ]),
            ],
        ),

        # Contenido
        html.Div(
            style={"padding": "20px 25px"},
            children=[
                html.Div(
                    style={"display": "flex", "gap": "20px", "flexWrap": "wrap"},
                    children=[
                        # Columna izquierda: filtros
                        html.Div(
                            style={"flex": "1 1 280px", "maxWidth": "380px"},
                            children=[
                                html.Div(
                                    style=CARD_STYLE,
                                    children=[
                                        html.H3(
                                            "Filtros",
                                            style={"marginTop": 0, "fontSize": "16px", "color": COLORS["accent"]},
                                        ),

                                        html.Label("Especies", style={"fontWeight": "bold", "fontSize": "13px"}),
                                        dcc.Dropdown(
                                            id="especie-dropdown",
                                            options=[{"label": e.title(), "value": e} for e in especies_ordenadas],
                                            value=default_especies,
                                            multi=True,
                                            placeholder="Elige una o más especies...",
                                            style={"marginBottom": "12px"},
                                        ),

                                        html.Label("Regiones", style={"fontWeight": "bold", "fontSize": "13px"}),
                                        dcc.Dropdown(
                                            id="region-dropdown",
                                            options=(
                                                [{"label": "Nacional (todas las regiones)", "value": "NACIONAL"}]
                                                + [{"label": map_region_nombre.get(r, r), "value": r} for r in regiones_unicas]
                                            ),
                                            value=["NACIONAL"],
                                            multi=True,
                                            placeholder="Elige una o más regiones o deja Nacional...",
                                            style={"marginBottom": "12px"},
                                        ),

                                        html.Label("Tipo de agente", style={"fontWeight": "bold", "fontSize": "13px"}),
                                        dcc.RadioItems(
                                            id="agente-radio",
                                            options=(
                                                [{"label": "ARTESANAL", "value": "ARTESANAL"}]
                                                + ([{"label": "INDUSTRIAL", "value": "INDUSTRIAL"}] if "INDUSTRIAL" in tipos_agente_presentes else [])
                                                + ([{"label": "ACUICULTURA", "value": "ACUICULTURA"}] if "ACUICULTURA" in tipos_agente_presentes else [])
                                                + ([{"label": "FABRICA", "value": "FABRICA"}] if "FABRICA" in tipos_agente_presentes else [])
                                                + [{"label": "Todos los tipos", "value": "TODOS"}]
                                            ),
                                            value=default_agente,
                                            inline=False,
                                            style={"fontSize": "13px"},
                                        ),

                                        html.Hr(),

                                        html.Label(
                                            "Ventana para promedio regional (últimos N años)",
                                            style={"fontWeight": "bold", "fontSize": "13px"},
                                        ),
                                        dcc.Slider(
                                            id="window-years",
                                            min=3,
                                            max=10,
                                            step=1,
                                            value=5,
                                            marks={i: str(i) for i in range(3, 11)},
                                            tooltip={"placement": "bottom", "always_visible": False},
                                        ),
                                        html.Div(
                                            id="window-label",
                                            style={"fontSize": "12px", "color": COLORS["muted"], "marginTop": "8px"},
                                        ),
                                    ],
                                ),
                            ],
                        ),

                        # Columna derecha: gráficos + slider años
                        html.Div(
                            style={"flex": "3 1 500px", "minWidth": "0"},
                            children=[
                                html.Div(
                                    style={**CARD_STYLE, "height": "100%"},
                                    children=[
                                        # Serie de tiempo
                                        dcc.Graph(id="time-series-graph"),

                                        # Slider años
                                        html.Div(
                                            children=[
                                                html.Label(
                                                    "Rango de años",
                                                    style={
                                                        "fontWeight": "bold",
                                                        "fontSize": "13px",
                                                        "display": "block",
                                                        "marginBottom": "4px",
                                                    },
                                                ),
                                                dcc.RangeSlider(
                                                    id="year-range",
                                                    min=min_year,
                                                    max=max_year,
                                                    value=[min_year, max_year],
                                                    step=1,
                                                    marks={year: str(year) for year in range(min_year, max_year + 1, 5)},
                                                    allowCross=False,
                                                ),
                                            ],
                                            style={"marginTop": "15px", "padding": "5px 5px 0 5px"},
                                        ),

                                        html.Hr(style={"marginTop": "18px"}),

                                        # Barras por región (mean ± sd) por especie
                                        dcc.Graph(id="region-bar-graph"),

                                        html.Div(
                                            [
                                                html.P(
                                                    "Serie: suma anual de toneladas por especie. Barras regionales: "
                                                    "promedio de los últimos N años (según el año final del slider) con SD entre años, "
                                                    "mostrado por especie (barras agrupadas).",
                                                    style={"fontSize": "11px", "color": COLORS["muted"], "marginBottom": "6px"},
                                                ),
                                                html.Div(
                                                    [
                                                        "Elaboración: Instituto en Socio-Ecología Costera (SECOS) – Datacenter",
                                                        html.Br(),
                                                        "Fuente: Sernapesca",
                                                    ],
                                                    style={"fontSize": "11px", "color": COLORS["muted"], "marginTop": "4px"},
                                                ),
                                            ],
                                        ),
                                    ],
                                )
                            ],
                        ),
                    ],
                ),
            ],
        ),
    ],
)

# ============================
# 6) Helpers + Callbacks
# ============================
@app.callback(
    Output("window-label", "children"),
    Input("window-years", "value"),
)
def window_text(n):
    return f"Se calcula sobre los últimos {n} años (terminando en el año máximo seleccionado en el slider)."


def aplicar_filtros(especies_seleccionadas, year_range, regiones_seleccionadas, agente_sel):
    dff = df_base.copy()

    # Tipo de agente
    if agente_sel and agente_sel != "TODOS":
        dff = dff[dff["TIPO AGENTE"] == agente_sel]

    # Regiones
    regiones_limpias = []
    if regiones_seleccionadas:
        regiones_limpias = [r for r in regiones_seleccionadas if r != "NACIONAL"]

    if regiones_limpias:
        dff = dff[dff["REGION"].isin(regiones_limpias)]
        nombres = [map_region_nombre.get(r, r) for r in regiones_limpias]
        titulo_reg = "Regiones: " + ", ".join(nombres)
        region_order = regiones_limpias
    else:
        titulo_reg = "Total nacional (todas las regiones)"
        region_order = regiones_unicas

    # Especies
    if especies_seleccionadas:
        if isinstance(especies_seleccionadas, str):
            especies_seleccionadas = [especies_seleccionadas]
        dff = dff[dff["ESPECIE"].isin(especies_seleccionadas)]

    # Años
    anio_min, anio_max = year_range
    dff = dff[(dff["AÑO"] >= anio_min) & (dff["AÑO"] <= anio_max)]

    etiqueta_agente = agente_sel if agente_sel != "TODOS" else "todos los tipos"
    return dff, titulo_reg, etiqueta_agente, region_order, int(anio_min), int(anio_max)


@app.callback(
    Output("time-series-graph", "figure"),
    Input("especie-dropdown", "value"),
    Input("year-range", "value"),
    Input("region-dropdown", "value"),
    Input("agente-radio", "value"),
)
def actualizar_time_series(especies_seleccionadas, year_range, regiones_seleccionadas, agente_sel):
    dff, titulo_reg, etiqueta_agente, _, _, _ = aplicar_filtros(
        especies_seleccionadas, year_range, regiones_seleccionadas, agente_sel
    )

    if dff.empty:
        fig = px.line()
        fig.update_layout(
            title="No hay datos para la selección actual",
            xaxis_title="Año",
            yaxis_title="Toneladas",
            template="simple_white",
        )
        return fig

    dff_grouped = dff.groupby(["ESPECIE", "AÑO"], as_index=False)["TONELADAS"].sum()

    fig = px.line(
        dff_grouped,
        x="AÑO",
        y="TONELADAS",
        color="ESPECIE",
        markers=True,
    )

    fig.update_layout(
        title=(
            "Desembarques totales anuales por especie"
            f"<br><sup>{titulo_reg} · agente: {etiqueta_agente}</sup>"
        ),
        xaxis_title="Año",
        yaxis_title="Toneladas",
        legend_title="Especie",
        hovermode="x unified",
        template="simple_white",
        margin={"l": 60, "r": 20, "t": 70, "b": 40},
    )

    return fig


@app.callback(
    Output("region-bar-graph", "figure"),
    Input("especie-dropdown", "value"),
    Input("year-range", "value"),
    Input("region-dropdown", "value"),
    Input("agente-radio", "value"),
    Input("window-years", "value"),
)
def actualizar_barras_regiones(especies_seleccionadas, year_range, regiones_seleccionadas, agente_sel, window_years):
    dff, titulo_reg, etiqueta_agente, region_order, anio_min, anio_max = aplicar_filtros(
        especies_seleccionadas, year_range, regiones_seleccionadas, agente_sel
    )

    if dff.empty:
        fig = px.bar()
        fig.update_layout(
            title="No hay datos para la selección actual",
            xaxis_title="Región",
            yaxis_title="Promedio (ton/año)",
            template="simple_white",
        )
        return fig

    # Ventana: últimos N años terminando en el año máximo del slider
    end_year = int(anio_max)
    start_year = int(max(anio_min, end_year - (window_years - 1)))

    dff_win = dff[(dff["AÑO"] >= start_year) & (dff["AÑO"] <= end_year)]
    if dff_win.empty:
        fig = px.bar()
        fig.update_layout(
            title=f"No hay datos en la ventana {start_year}–{end_year}",
            xaxis_title="Región",
            yaxis_title="Promedio (ton/año)",
            template="simple_white",
        )
        return fig

    # 1) Total anual por región *y especie*
    annual_reg_sp = (
        dff_win.groupby(["REGION", "ESPECIE", "AÑO"], as_index=False)["TONELADAS"]
        .sum()
    )

    # 2) mean y sd entre años para cada (REGION, ESPECIE)
    summary = (
        annual_reg_sp.groupby(["REGION", "ESPECIE"])["TONELADAS"]
        .agg(mean_ton="mean", sd_ton="std", n_years="count")
        .reset_index()
    )
    summary["sd_ton"] = summary["sd_ton"].fillna(0)

    # Etiqueta de región bonita
    summary["REGION_LABEL"] = summary["REGION"].map(map_region_nombre).fillna(summary["REGION"])

    # Orden geográfico (consistente)
    ordered = [r for r in region_order if r in summary["REGION"].unique().tolist()]
    summary["REGION"] = pd.Categorical(summary["REGION"], categories=ordered, ordered=True)
    summary = summary.sort_values("REGION")

    fig = px.bar(
        summary,
        x="REGION_LABEL",
        y="mean_ton",
        color="ESPECIE",
        barmode="group",      # <-- varias columnas (recomendado para SD)
        error_y="sd_ton",
        custom_data=["REGION", "ESPECIE", "n_years", "sd_ton"],
    )

    fig.update_traces(
        hovertemplate=(
            "<b>%{x}</b><br>"
            "Especie: %{customdata[1]}<br>"
            "Promedio: %{y:,.0f} ton/año<br>"
            "SD: %{customdata[3]:,.0f}<br>"
            "Años usados: %{customdata[2]}<br>"
            "<extra></extra>"
        )
    )

    fig.update_layout(
        title=(
            f"Promedio regional últimos {window_years} años (mean ± SD) por especie"
            f"<br><sup>Ventana: {start_year}–{end_year} · {titulo_reg} · agente: {etiqueta_agente}</sup>"
        ),
        xaxis_title="Región",
        yaxis_title="Toneladas promedio por año",
        legend_title="Especie",
        template="simple_white",
        margin={"l": 60, "r": 20, "t": 80, "b": 80},
    )
    fig.update_xaxes(tickangle=35)

    return fig


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8051, debug=False)