#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
import dash
from dash import Dash,dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from scipy.stats import gaussian_kde

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

df.columns = df.columns.str.strip()

# Renombrar para trabajar más cómodo
df = df.rename(columns={
    "Año": "AÑO",
    "RegióndeOperación": "REGION_OP",
    "CaletadeDesembarque": "CALETA"
})

# Normalizar región (por si viene 10.0, etc.)
df["REGION_OP"] = df["REGION_OP"].astype(str).str.strip()
df["REGION_OP"] = df["REGION_OP"].str.replace(".0", "", regex=False)

# Año numérico
df["AÑO"] = pd.to_numeric(df["AÑO"], errors="coerce")

# Asegurar que RPAEmbarcación sea string
df["RPAEmbarcación"] = df["RPAEmbarcación"].astype(str).str.strip()

# ============================
# Diccionario de regiones
# ============================
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",
}

df["REGION_NOMBRE"] = df["REGION_OP"].map(dicc_regiones).fillna(df["REGION_OP"])

# ============================
# 2) Base reducida para la app
# ============================
df_base = df[
    [
        "AÑO",
        "REGION_OP",
        "REGION_NOMBRE",
        "CALETA",
        "RPAEmbarcación",
        "TipoEmbarcación",
        "NombreEmbarcación",
        "Eslora(m)",
        "TRG",
        "Cap.Bodega(m3)",
        "Matrícula",
    ]
].dropna(subset=["AÑO"])

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

# ----- Orden geográfico de regiones -----
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
    "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_base["REGION_OP"].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) Estilos
# ============================
COLORS = {
    "bg": "#f5f7fa",
    "card": "white",
    "accent": "#005f73",
    "muted": "#666666",
}

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

# ============================
# 4) App Layout
# ============================
app = Dash(
    __name__,
    requests_pathname_prefix="/apps/flota/",
)

app.layout = html.Div(
    style={"fontFamily": "Arial", "backgroundColor": COLORS["bg"], "minHeight": "100vh"},
    children=[
        # ----- TOP BAR -----
        html.Div(
            style={"backgroundColor": COLORS["accent"], "color": "white", "padding": "12px 25px"},
            children=[
                html.H1("Flota artesanal operativa", style={"margin": 0, "fontSize": "22px"}),
                html.Div(
                    f"Embarcaciones con actividad en el período {min_year}–{max_year}",
                    style={"fontSize": "13px"}
                ),
            ],
        ),

        # ----- CONTENIDO -----
        html.Div(
            style={"padding": "20px 25px"},
            children=[
                html.Div(
                    style={"display": "flex", "gap": "20px", "flexWrap": "wrap"},
                    children=[

                        # ----- FILTROS -------
                        html.Div(
                            style={"flex": "1 1 260px", "maxWidth": "380px"},
                            children=[
                                html.Div(
                                    style=CARD_STYLE,
                                    children=[
                                        html.H3("Filtros", style={"marginTop": 0}),

                                        html.Label("Regiones"),
                                        dcc.Dropdown(
                                            id="region-dropdown",
                                            options=(
                                                [{"label": "Nacional (todas)", "value": "NACIONAL"}] +
                                                [
                                                    {
                                                        "label": map_region_nombre.get(r, r),
                                                        "value": r,
                                                    }
                                                    for r in regiones_unicas
                                                ]
                                            ),
                                            value=["NACIONAL"],
                                            multi=True,
                                            style={"marginBottom": "12px"},
                                        ),

                                        html.Label("Tipo de embarcación"),
                                        dcc.Dropdown(
                                            id="tipoemb-dropdown",
                                            options=[
                                                {"label": t, "value": t}
                                                for t in sorted(df_base["TipoEmbarcación"].dropna().unique())
                                            ],
                                            value=sorted(df_base["TipoEmbarcación"].dropna().unique()),
                                            multi=True,
                                            style={"marginBottom": "12px"},
                                        ),
                                    ],
                                )
                            ],
                        ),

                        # ----- GRÁFICO -----
                        html.Div(
                            style={"flex": "3 1 500px"},
                            children=[
                                html.Div(
                                    style=CARD_STYLE,
                                    children=[
                                        dcc.Graph(id="grafico-flota"),

                                        html.Div(
                                            [
                                                html.Label(
                                                    "Año",
                                                    style={
                                                        "fontWeight": "bold",
                                                        "fontSize": "13px",
                                                        "marginBottom": "4px",
                                                    },
                                                ),
                                                dcc.Dropdown(
                                                    id="year-dropdown",
                                                    options=[
                                                        {"label": str(y), "value": int(y)}
                                                        for y in years_available
                                                    ],
                                                    value=int(max_year),
                                                    clearable=False,
                                                    style={"width": "200px"},
                                                ),
                                            ],
                                            style={"marginTop": "20px"},
                                        ),

                                        # Pie
                                        html.Div(
                                            [
                                                "Valores: Distribución de esloras de embarcaciones únicas (RPAEmbarcación) con actividad (desembarque). Tipo de embarcación de acuerdo del DS N°388 de junio 1995",
                                            ],
                                            style={"fontSize": "11px", "color": COLORS["muted"], "marginTop": "10px"},
                                        ),
                                        html.Div(
                                            [
                                                "Elaboración: Instituto en Socio-Ecología Costera (SECOS) – Datacenter",
                                                html.Br(),
                                                "Fuente: Sernapesca-Subpesca",
                                            ],
                                            style={"fontSize": "11px", "color": COLORS["muted"], "marginTop": "4px"},
                                        ),
                                    ],
                                )
                            ],
                        ),
                    ],
                )
            ],
        ),
    ],
)

# ============================
# 5) CALLBACK
# ============================
@app.callback(
    Output("grafico-flota", "figure"),
    Input("region-dropdown", "value"),
    Input("tipoemb-dropdown", "value"),
    Input("year-dropdown", "value"),
)
def actualizar_histogramas(regiones_sel, tipos_sel, year_sel):

    dff = df_base.copy()

    # -----------------------------
    # FILTROS
    # -----------------------------
    # Región
    regiones_limpias = [r for r in regiones_sel if r != "NACIONAL"]
    if regiones_limpias:
        dff = dff[dff["REGION_OP"].isin(regiones_limpias)]

    # TipoEmbarcación
    if tipos_sel:
        if isinstance(tipos_sel, str):
            tipos_sel = [tipos_sel]
        dff = dff[dff["TipoEmbarcación"].isin(tipos_sel)]

    # Año (solo uno)
    if year_sel is not None:
        dff = dff[dff["AÑO"] == year_sel]

    # Solo esloras conocidas
    dff = dff.dropna(subset=["Eslora(m)"])

    # -----------------------------
    # STRING REGIONES PARA TÍTULO
    # -----------------------------
    if not regiones_limpias:
        region_str = "a nivel nacional"
    else:
        nombres = [map_region_nombre.get(r, r) for r in regiones_limpias]
        if len(nombres) == 1:
            region_str = f"en {nombres[0]}"
        else:
            region_str = "en " + ", ".join(nombres)

    # -----------------------------
    # SEPARAR BOTES Y LANCHAS
    # -----------------------------
    botes = dff[dff["TipoEmbarcación"] == "BOTE"]
    lanchas = dff[dff["TipoEmbarcación"].isin(
        ["Lancha Menor", "Lancha Media", "Lancha Mayor"]
    )]

    # Totales (por RPA)
    total_botes = botes["RPAEmbarcación"].nunique()
    total_lanchas = lanchas["RPAEmbarcación"].nunique()

    # -----------------------------
    # CASO SIN DATOS
    # -----------------------------
    if dff.empty:
        fig = make_subplots(
            rows=1, cols=2,
            subplot_titles=("Botes", "Lanchas"),
            shared_yaxes=True
        )
        fig.update_layout(
            title=f"Flota operando el año {year_sel} {region_str} – sin datos para la selección actual",
            template="simple_white",
        )
        fig.update_xaxes(title_text="Eslora (m)", row=1, col=1)
        fig.update_xaxes(title_text="Eslora (m)", row=1, col=2)
        fig.update_yaxes(title_text="Frecuencia (nº embarcaciones)", row=1, col=1)
        return fig

    # -----------------------------
    # FIGURA Y SUBPLOTS
    # -----------------------------
    fig = make_subplots(
        rows=1,
        cols=2,
        subplot_titles=("Botes", "Lanchas"),
        shared_yaxes=True,
    )

    # =============================
    # PANEL IZQ: BOTES
    # =============================
    if not botes.empty:
        x_b = botes["Eslora(m)"].values

        fig.add_trace(
            go.Histogram(
                x=x_b,
                name="Botes",
                nbinsx=25,
                opacity=0.7,
            ),
            row=1, col=1
        )

        # KDE solo si hay > 1 dato
        if len(x_b) > 1:
            kde_b = gaussian_kde(x_b)
            xs_b = np.linspace(x_b.min(), x_b.max(), 200)
            hist_values_b, _ = np.histogram(x_b, bins=25)
            if hist_values_b.max() > 0:
                scale_b = hist_values_b.max() / kde_b(xs_b).max()
                fig.add_trace(
                    go.Scatter(
                        x=xs_b,
                        y=kde_b(xs_b) * scale_b,
                        mode="lines",
                        line=dict(color="black", width=2),
                        showlegend=False,
                    ),
                    row=1, col=1
                )

    # =============================
    # PANEL DER: LANCHAS
    # =============================
    colores_lanchas = {
        "Lancha Menor": "#4b9a6c",
        "Lancha Media": "#ff7f0e",
        "Lancha Mayor": "#d62728",
    }

    for tipo, subdf in lanchas.groupby("TipoEmbarcación"):
        if subdf.empty:
            continue

        x_l = subdf["Eslora(m)"].values
        color = colores_lanchas.get(tipo, None)

        # Histograma
        fig.add_trace(
            go.Histogram(
                x=x_l,
                name=tipo,
                nbinsx=25,
                opacity=0.6,
                marker_color=color,
            ),
            row=1, col=2
        )

        # KDE si hay suficientes datos
        if len(x_l) > 1:
            kde_l = gaussian_kde(x_l)
            xs_l = np.linspace(x_l.min(), x_l.max(), 200)
            hist_values_l, _ = np.histogram(x_l, bins=25)
            if hist_values_l.max() > 0:
                scale_l = hist_values_l.max() / kde_l(xs_l).max()
                fig.add_trace(
                    go.Scatter(
                        x=xs_l,
                        y=kde_l(xs_l) * scale_l,
                        mode="lines",
                        line=dict(color=color, width=2),
                        showlegend=False,
                    ),
                    row=1, col=2
                )

    # -----------------------------
    # TÍTULO Y LAYOUT GENERAL
    # -----------------------------
    titulo = (
        f"Flota operando el año {year_sel} {region_str}"
        f"<br><sup>Total botes: {total_botes} | Total lanchas: {total_lanchas}</sup>"
    )

    fig.update_layout(
        title=titulo,
        template="simple_white",
        bargap=0.05,
        barmode="overlay",
        margin={"l": 60, "r": 160, "t": 90, "b": 50},  # 👈 más margen derecho
        legend=dict(
            orientation="v",      # 👈 vertical
            yanchor="top",
            y=1,
            xanchor="left",
            x=1.02,              # 👈 a la derecha del panel de lanchas
            font=dict(size=10)
        ),
    )

    fig.update_xaxes(title_text="Eslora (m)", row=1, col=1)
    fig.update_xaxes(title_text="Eslora (m)", row=1, col=2)
    fig.update_yaxes(title_text="Frecuencia (nº embarcaciones)", row=1, col=1)

    return fig


# ============================
# 6) RUN
# ============================
if __name__ == "__main__":
    app.run(
        host="127.0.0.1",   # 👈 sólo interno
        port=8057,
        debug=False
    )